㈠ 借助Redis Bitmap实现简单的布隆过滤器
在之前的 一篇文章 中,我们已经深入理解了布隆过滤器的基本原理,并且了解到它在缓存系统中有较多的应用。Redis提供的Bitmap正好能够作为布隆过滤器所需要的位数组的基础,本文先简要介绍Bitmap,然后给出基于它的布隆过滤器实现。
Bitmap在Redis中并不是一个单独的数据类型,而是由字符串类型(Redis内部称Simple Dynamic String,SDS)之上定义的与比特相关的操作实现的,此时SDS就被当做位数组了。下面是在redis-cli中使用getbit和setbit指令的操作示例。
Redis的Bitmap是自动扩容的,亦即get/set到高位时,就会主动填充0。此外,还有bitcount指令用于计算特定字节范围内1的个数,bitop指令用来执行位运算(支持and、or、xor和not)。相应的用法可以查询Redis官方文档等。
下面我们基于Redis(Codis)实现布隆过滤器RedisBloomFilter。根据之前讲解布隆过滤器的文章,要初始化一个布隆过滤器的话,需要两个参数:预估的元素数量,以及可接受的最大误差(即假阳性率)。另外,我们也需要传入Jodis的连接池实例JedisResourcePool,以方便在Redis上操作。RedisBloomFilter类的成员和构造方法如下所示。
为了区分出布隆过滤器对应的Key,在原始Key的前面都加上"bf:"前缀。Bitmap长度bitmapLength和哈希函数个数numHashFunctions则利用Guava版实现中的方法来计算。
然后,我们需要计算一个元素被k个哈希函数散列后,对应到Bitmap的哪些比特上。这里仍然借鉴了Guava的BloomFilterStrategies实现,采用MurmurHash和双重哈希进行散列。为了应用简单,假设所有元素固定为字符串类型,不用泛型。
然后我们就可以通过Jedis的setbit()和getbit()方法来实现向布隆过滤器中插入元素与查询元素是否存在的逻辑了。一个元素会对应多个比特,为了提高效率,流水线就派上用场了。另外,setbit指令不会重置对应Key的过期时间戳。
完毕,写个简单的单元测试吧。假设现在用布隆过滤器来存储已读帖子的ID,Key中包含用户ID和时间。每天预估的每用户最大阅读量是3000篇,最大误差3%。
观察输出。
㈡ Redis 内存故障诊断及常用运维命令
你是否有过这种困扰:我的数据量非常小,但还是报OOM错误?
首先我给大家解释下,Redis的OOM分两种
简短介绍下Redis内存消耗划分情况,为下文诊断提供思路。上图可以总结Redis消耗内存分如下几块:
使用redis-benchmark持续灌入数据
制造输入缓冲区压力(防止干扰,先清空数据再压测)
压测几秒钟后,触发OOM
检查输入缓冲区内存消耗,能看到客户端输入缓冲区消耗总量为 2.4G左右,远远超过maxmemory参数设置。
可通过运行上述检查命令,定位到各客户端输入缓冲区的内存消耗(由大到小排序)。
一般如果定位到有连接异常,可以使用如下命令杀掉
为测试方便,我直接把复制积压缓冲区配置为800M。
开启redis-benchmark压测进程
检查复制积压缓冲区内存消耗,可以看到因为缓冲区设置过大,数据量才存储190多M,Redis就无法写入了。
若客户端输出缓冲区太大如何排查?一般该场景比较少见,常见于用到了redis的 monitor 命令
先开启monitor命令
上文排查过程有些Redis运维命令我认为比较实用,整理如下
脚本执行效果:
㈢ redis布隆过滤器拆分长度
布隆过滤器是一种类似set的数据结构。
Redis布隆过滤器的基本使用
在Redis中,布隆过滤器有两个基本命令,分别是:
bf.add:添加元素到布隆过滤器中,类似于集合的sadd命令,不过bf.add命令只能一次添加一个元素,如果想一次添加多个元素,可以使用bf.madd命令。
bf.exists:判断某个元素是否在过滤器中,类似于集合的sismember命令,不过bf.exists命令只能一次查询一个元素,如果想一次查询多个元素,可以使用bf.mexists命令。
布隆过滤器的高级使用
上面的例子中使用的布隆过滤器只是默认参数的布隆过滤器,它在我们第一次使用 bf.add 命令时自动创建的。Redis还提供了自定义参数的布隆过滤器,想要尽量减少布隆过滤器的误判,就要设置合理的参数。
在使用 bf.add 命令添加元素之前,使用 bf.reserve 命令创建一个自定义的布隆过滤器。bf.reserve命令有三个参数,分别是:
key:键
error_rate:期望错误率,期望错误率越低,需要的空间就越大。
capacity:初始容量,当实际元素的数量超过这个初始化容量时,误判率上升。
如果对应的key已经存在时,在执行bf.reserve命令就会报错。如果不使用bf.reserve命令创建,而是使用Redis自动创建的布隆过滤器,默认的error_rate是0.01,capacity是 100。
布隆过滤器的 error_rate 越小,需要的存储空间就越大,对于不需要过于精确的场景,error_rate设置稍大一点也可以。布隆过滤器的capacity设置的过大,会浪费存储空间,设置的过小,就会影响准确率,所以在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出设置值很多。总之,error_rate和 capacity都需要设置一个合适的数值。
㈣ redis monitor 每列什么意思
Redis MONITOR是调试命令流回来Redis服务器处理每一个指令。
它可以有助于理解数据库发生了什么事情。此命令都可以通过Redis命令行接口,并通过远程telnet登录使用。
为了发现在应用程序中错误,看到所有服务器处理请求的能力是使用的Redis作为数据库,并作为分布式缓存系统。
㈤ REDIS----配置文件----LATENCY MONITOR
Redis延迟监视子系统在运行时对不同的操作进行采样,以便收集与Redis实例的可能延迟源相关的数据;
通过延迟命令,用户可以使用此信息打印图表和获取报告;
系统只记录在等于或大于通过延迟监视器阈值配置指令指定的毫秒数的时间内执行的操作。当其值设置为零时,延迟监视器将关闭;
默认情况下,延迟监视是禁用的,因为如果没有延迟问题,则通常不需要它,而且收集数据会对性能产生影响,虽然影响很小,但可以在大负载下测量。如果需要,可以在运行时使用命令 “CONFIG SET Latency monitor threshold<millishes>” 轻松启用延迟监视;
㈥ redis monitor界面怎么看
/etc/sysctl.conf
添加
vm.overcommit_memory=1
刷新配置使之生效
sysctl vm.overcommit_memory=1
补充介绍:
**如果内存情况比较紧张的话,需要设定内核参数:echo 1 > /proc/sys/vm/overcommit_memory
内核参数说明如下:
overcommit_memory文件指定了内核针对内存分配的策略,其值可以是0、1、2。0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
**编辑redis.conf配置文件(/etc/redis.conf),按需求做出适当调整,比如:daemonize yes #转为守护进程,否则启动时会每隔5秒输出一行监控信息save 60 1000 #减小改变次数,其实这个可以根据情况进行指定maxmemory 256000000 #分配256M内存
在我们成功安装Redis后,我们直接执行redis-server即可运行Redis,此时它是按照默认配置来运行的(默认配置甚至不是后台运 行)。我们希望Redis按我们的要求运行,则我们需要修改配置文件,Redis的配置文件就是我们上面第二个cp操作的redis.conf文件,目前 它被我们拷贝到了/usr/local/redis/etc/目录下。修改它就可以配置我们的server了。如何修改?下面是redis.conf的主 要配置参数的意义:
daemonize:是否以后台daemon方式运行
pidfile:pid文件位置
port:监听的端口号
timeout:请求超时时间
loglevel:log信息级别
logfile:log文件位置
databases:开启数据库的数量
save * *:保存快照的频率,第一个*表示多长时间,第三个*表示执行多少次写操作。在一定时间内执行一定数量的写操作时,自动保存快照。可设置多个条件。
rdbcompression:是否使用压缩
dbfilename:数据快照文件名(只是文件名,不包括目录)
dir:数据快照的保存目录(这个是目录)
appendonly:是否开启appendonlylog,开启的话每次写操作会记一条log,这会提高数据抗风险能力,但影响效率。
appendfsync:appendonlylog如何同步到磁盘(三个选项,分别是每次写都强制调用fsync、每秒启用一次fsync、不调用fsync等待系统自己同步)
G
㈦ 该怎么解决 Redis 缓存穿透和缓存雪崩问题
缓存雪崩: 由于缓存层承载着大量请求,有效地 保护了存储层,但是如果缓存层由于某些原因不能提供服务,比如 Redis 节点挂掉了,热点 key 全部失效了,在这些情况下,所有的请求都会直接请求到数据库,可能会造成数据库宕机的情况。
预防和解决缓存雪崩问题,可以从以下三个方面进行着手:
1、使用 Redis 高可用架构:使用 Redis 集群来保证 Redis 服务不会挂掉
2、缓存时间不一致: 给缓存的失效时间,加上一个随机值,避免集体失效
3、限流降级策略:有一定的备案,比如个性推荐服务不可用了,换成热点数据推荐服务
缓存穿透: 缓存穿透是指查询一个根本不存在的数据,这样的数据肯定不在缓存中,这会导致请求全部落到数据库上,有可能出现数据库宕机的情况。
预防和解决缓存穿透问题,可以考虑以下两种方法:
1、缓存空对象: 将空值缓存起来,但是这样就有一个问题,大量无效的空值将占用空间,非常浪费。
2、布隆过滤器拦截: 将所有可能的查询key 先映射到布隆过滤器中,查询时先判断key是否存在布隆过滤器中,存在才继续向下执行,如果不存在,则直接返回。布隆过滤器有一定的误判,所以需要你的业务允许一定的容错性。