Loading... # redis管道、事务、布隆过滤器 ## 管道 当要执行多个redis命令时,我们可以顺序的执行这几个命令,也可以通过pipeline(管道),一次性将命令发送给redis,节省通信成本。 ### 原理 redis-client与redis-server之间的通信交互无非就是socket通信,只要能建立socket连接,就可以发送命令并且接收返回数据,因此,我们可以直接通过nc命令,与端口建立socket连接。 ``` nc localhost 6379 # 开启与6379端口的socket通信,然后就可以给redis发送命令 ``` echo -e 命令可以识别\n换行符, ``` echo -e "set k2 99\nincr k2\n get k2" | nc localhost 6379 ``` 该语句执行三个命令 ``` set k2 99 incr k2 get k2 ``` ## 事务 MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。 1. MULTI MULTI命令会开启一个事务,之后的命令会被单独放入一个队列中,并不会执行,只有调用EXEC命令时,才会执行所有队列中的 任务。如果有两个客户端同时访问,并开启事务,由于redis是单线程,也就是说所有redis命令都是顺序执行的,因此,谁先 调用EXEC就先执行谁的命令,如果client1的队列中要get k1,而client2队列中的命令时del k1,但是先执行了client2的 EXEC,client1执行EXEC之后得到的结果就是nil,因为k1已经被client2删除了。 2. DISCARD 当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中退出。 3. WATCH WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。如果client1执行WATCH命令监控了一个key,并开启 MULTI事务,然后get key,client2这时候将key的value修改了,这时client1调用了EXEC命令,因为WATCH检测到key被修 改,因此会返回nil。与MULTI的区别是,只要WATCH检测到被修改,那么队列中的命令会全部放弃执行。 ## 布隆过滤器 ![01.png][1] ### 作用 减少缓存穿透,当数据库中没有该数据记录时,缓存中肯定不会有,我们要达到的效果是,当缓存中没有,但是数据库中有,那么就去数据库中查,当缓存中没有,数据库中也没有时,就不应该查数据库,而是直接返回错误信息。当数据量很大的时候,缓存穿透问题会极大增加数据库的查询压力,然而,我们将所有数据库中有的数据都存进缓存也不现实,毕竟内存有限,所以,需要用到过滤器。 ### 原理 从数据库中取出所有存在的数据,然后通过调用N次映射函数(hash算法),得到N个数值,然后将这几个数值所对应的bitmap位设置为1。当客户端调用查询时,将查询的关键词同样经过这几个映射函数,然后去与bitmap中对应的二进制位对比,只要有一个为0,就说明该关键词对应的数据在数据库中不存在,因为存在hash碰撞问题,不能保证每一个位都不为1,也可能每一个位都恰巧是1,但是数据库中不存在。因此,布隆过滤器不能保证100%过滤,理论上可以保证,每位都是1,但数据库中不存在的可能性小于1%,当出现这种情况时,我们需要调用set命令,将这个key写入缓存中value为error,避免下次查询时仍然查询数据库。 ### 实现方案 过滤器根据我们的业务或者性能,在架构层面也可以有不同的实现方式。 ![02.png][2] - 客户端的service自己实现布隆算法(第三方库),自己承载bitmap。 - 客户端的service自己实现布隆算法(第三方库),然后用redis的bitmap。 - 使用redis的布隆module以及bitmap。 ### redis集成布隆过滤器 访问redis.io然后点击Modules,进入Modules页面,找到RedisBloom,点击 ![03.png][3] 进入布隆过滤器的github,下载布隆过滤器,并解压缩。进入解压之后的文件夹,运行 ``` make ``` 然后会生成一个redisbloom.so文件,将改文件拷贝到redis目录下。 ``` cp redisbloom.so /opt/redis5 ``` 然后启动redis时加上该module ``` redis-server --loadmodule /opt/redis5/redisbloom.so ``` 调用客户端连接 ``` redis-cli ``` 之后就可以调用 ``` BF.ADD key value BF.EXISTS key CF.ADD # 布谷鸟过滤器 ``` 等命令了。 [1]: https://www.princelei.club/usr/uploads/2019/11/1781726831.png [2]: https://www.princelei.club/usr/uploads/2019/11/2741355526.png [3]: https://www.princelei.club/usr/uploads/2019/11/1612575735.png Last modification:June 11th, 2020 at 06:13 pm © 允许规范转载