Redis Module
Redis module 是Redis 4.0 以后支持的新的特性,这里很多国外牛逼的大学和机构提供了很多牛逼的Module 只要编译引入到Redis 中就能轻松的实现我们某些需求的功能。在Redis 官方Module 中有一些我们常见的一些模块,我们在这里就做一个简单的使用。
个人推荐可以尝试的
- neural-redis 主要是神经网络的机器学,集成到redis 可以做一些机器训练感兴趣的可以尝试
- RedisSearch 主要支持一些富文本的的搜索
- RedisBloom 支持分布式环境下的Bloom 过滤器
布隆过滤器
比如我们存放某些数据的id属性,id属性通过K个Hash 函数,计算到bit(位数组)上面,把它们变成1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。这个一般可以使用在新闻推荐和缓存穿透的处理上面,效果很好。
优点和缺点
优点
空间效率和查询时间都远远超过一般的算法,布隆过滤器存储空间和插入 / 查询时间都是常数O(k)。 另外, 散列函数相互之间没有关系,方便由硬件并行实现。 布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。
缺点
- 为什么效率会那么高,是因为布隆过滤器牺牲了准备性和删除操作,布隆过滤器存在一定的误判概率。 比如我们查询某个key ,通过K个hash 函数对应的位数组上面映射的都是1 ,但其实我们的数据存储并没有这个数据,所以存在一定误判。如果我们用来做一个ip 黑名单的添加,可能就会存在一定的误判率。
- 删除问题,我们如果把数组某个位置设置为 1 或者是 0 ,那么识别会影响其它数据的判断,
实现
而对于我们java 实现的bloom过滤器可以通过谷歌提供的guava ,但是我们现在的系统大部分都是分布式系统,那么这种方式就不太合适,我们可能会想把数据存放到一个分布式环境下的内存中,自然就会想到redis ,那么redis的那帮大神们自然肯定也会想到,所以就有很多开源组织和个人研发了基于redis 的布隆过滤器。 那么首先介绍使用Redis Module 集成进RedisBloom。
- 下载官方的git 仓库文件 github.com/RedisBloom/…
- 比如在Linux 服务器上面可以直接通过git 拉取源码 git github.com/RedisBloom/…
- 进入下载好的目录 执行make 命令进行编译成so 库
- 接下来就很简单了,直接在redis.conf 配置文件里面,然后重启服务器
loadmodule /opt/redis/redis-cluster/redisbloom.so - 重启服务,进入 client 查看集成进来的module
那么对与官网提供的其它模块的集成模式基本和RedisBloom一样,有兴趣的可以去尝试下,这样面试的时候可以提一下自己研究过这块,相信面试官会喜欢这样的面试人员。
那么如果用java 调用RedisBloom 先给大家看一下官网的实现方式。
// 核心还是通过jedis客户端的方式,这种方式还是笔者看它源码改写后的,官方提供的不支持redis 密码验证
pom 文件
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.redislabs</groupId>
<artifactId>jrebloom</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<repositories>
<repository>
<id>snapshots-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
代码实现
public class RedisBloom {
public static void main(String[] args) {
JedisPoolConfig conf = new JedisPoolConfig();
conf.setMaxTotal(100);
conf.setTestOnBorrow(false);
conf.setTestOnReturn(false);
conf.setTestOnCreate(false);
conf.setTestWhileIdle(false);
conf.setMinEvictableIdleTimeMillis(60000L);
conf.setTimeBetweenEvictionRunsMillis(30000L);
conf.setNumTestsPerEvictionRun(-1);
conf.setFairness(true);
JedisPool jedisPool = new JedisPool(conf,"192.168.13.131",6379,30000,"123456");
Client client = new Client(jedisPool);
boolean exists = client.exists("newFilter", "foo55");
System.out.println(exists);
client.add("newFilter","123");
client.add("newFilter","456");
client.add("newFilter","789");
client.close();
}
}
上面的这种实现方式比较复杂,下面给大家介绍一款redis 比较牛皮的客户端工具,可能大家听说过 Redission 框架,可能大家了解的是它实现分布式锁忒简单,这个框架提供了很多强大的功能, 比如分布式锁、令牌桶限流、分布式布隆过滤器,那么我们就来爽一波
<!-- 引入redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.5</version>
</dependency>
编写 ReissonConfig
/**
* @Description
* @Author gavin
* @Since 1.0
* @Date 2019/10/27
*/
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.13.132:6379")
return Redisson.create(config);
}
}
// 分布式信号实现秒杀库存 利用ab 测试工具可以测试
@GetMapping("/kill2")
public void kill2(){
RSemaphore semaphore = redissonClient.getSemaphore("number");
// 默认抢到会减少一个
boolean tryAcquire = semaphore.tryAcquire();
if(tryAcquire){
Integer number = redisUtil.get("number", Integer.class);
if(number > 0){
System.out.println("当前库存还剩:"+number+" 用户抢购成功");
}
}
}
// 分布式环境下布隆过滤器的实现,非常的简单
@Test
public void testBloomFilter() {
RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter("newFilter2");
// 初始化布隆过滤器,预计统计元素数量为55000000,期望误差率为0.03
bloomFilter.tryInit(55000000L, 0.03);
bloomFilter.add("lisi");
bloomFilter.add("wangwu");
boolean foo = bloomFilter.contains("lisi343");
System.out.println(foo);
}
// 限流
public void testRateLimiter() {
RRateLimiter rateLimiter = redissonClient.getRateLimiter("myRateLimiter");
// 初始化
// 最大流速 = 每1秒钟产生10个令牌
boolean trySetRate = rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);
if(rateLimiter.tryAcquire()){
System.out.println("我获取到了信息哈");
}else{
System.out.println("对不起你被限流了哈");
}
}
欧克欧克😀 大概这里都介绍完毕了,如果大家想研究更多Redisson 的强大功能,这里给一个传送地址 github.com/redisson/re… 绝壁不会让你失望