redisbigkey(redisbigkeys内容详解)
本篇文章给大家谈谈redisbigkey,以及redisbigkeys内容详解对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
redis布隆过滤器属于bigkey
redis布隆过滤器属于bigkey。根据枝缺查询公开信息显示,redis是单线程纤山运行的,一次猛竖辩操作的value会对整个redis的响应时间造成负面影响。出现这种情况下需要对bigkey进行拆分。
[img]浅析Redis的BigKey(阿里巴巴技术协会ATA同步发送)
在完成事件接入的需求时,我们需要记录上一个批次拉取的事件,并与当前拉取到的事件做出比对,从而进行差分。我们目前的做法是使用redis来进行缓存:将上一个批次拉取到的事件缓存到一个list中。但是当事件数量过多时,value的大小会超过1M的限制,直接抛出异常。这其实是Tair出于性能的考虑而做出的限制,本文将谈谈我个人对于bigKey的理解。
顾名思义,bigKey指一个key对应的value占据的内存空间相对比较大,bigKey通常会有两种表现形式:
bigKey一旦产生,将会槐拆坦对tair的性能以及稳定性造成较大的影响,下面我将详细介绍一下bigKey的危害。
bigKey给tair带来的危害是多方面的,性能下降只是其中的御锋一方面,极端情况下,bigKey甚至会导致缓存服务崩溃。下面我将从几个角度进行分析。
我们可以看到:
另外,在Redis执行异步重写操作时(bgrewriteaof),主线程会fork出一个子进程来执行重写命令,这个子进程会与主线程共享内存。当主线程收到了新增或者修改一个key的命令,主线程会申请一块额外的内存空间来保存数据。但如果这个key是一个bigKey时,主线程会去申请一块更大空间,同样会阻塞主线程(与JVM分配内存一样,涉及锁和同步)。如果申请不到足够的空间,会导致Swap甚至会有OOM的风险,这同样会降低Redis的性能和稳定性。
Tair中一个key最大为1M,我们就以1M举例,当访问这个key的QPS为1000时,每秒将会有1GB左右的流量,对于带宽来说将是一个较大压力。如果这个bigKey是一个热点key时,后果将不堪设想。
如果主从同步的 client-output-buffer-limit 设置过小,并且 master 存在大量bigKey(数据量很大),主从全量同步时可能会导致 buffer 溢出,溢出后主从全量同步就会失败。如果主从集群配置了哨兵,那么哨兵会让 slave 继续向 master 发起全量同步请求,然后 buffer 又溢出同步失败,如此反复,会形成复制风暴,这会浪费 master 大量的 CPU、内存、带宽资源,也会让 master 产生阻塞的风险。 另外,当我们使用Redis Cluster时,由于Redis Cluster采用了同步迁移的方式,bigKey同样会阻塞主线程。这里提一下Codis,Codis在迁移bigKey时,使用了异步迁移 + 指令拆分的方式,对于bigKey (集合类型) 中每个元素,用一条指令进行迁移,而不是把整个 bigKey 进行序列化后再整铅桐体传输。这种化整为零的方式,就避免了 bigKey 迁移时,因为要序列化大量数据而阻塞的问题。
当我们写入或者读取大量bigKey的时候,很有可能导致输入/输出缓冲区溢出。如果客户端占用的内存总量超过了服务器设置的maxmemory时(默认4GB),将会直接触发服务器的内存淘汰策略,如果有数据被淘汰,再要获取这些数据就需要到后端回源,间接降低了缓存系统的性能。同时,淘汰的如果是bigKey也同样会阻塞主线程。另外,在极端情况下,多个客户端占用了过多的内存将导致OOM,进而使得整个redis进程崩溃。
使用切片集群的时候,我们通常会将不同的key存放在不同的实例上,如果存在bigKey的话,会导致相应实例的数据量增大,内存压力也相应增大。
常用的做法是通过./redis-cli --bigkeys命令对整个redis中的键值对进行统计,输出每种数据类型中最大的 bigkey 的信息。一般会配合-i参数一起使用,控制扫描间隔,避免长时间扫描降低 Redis 实例的性能。另外该命令不要在业务高峰期使用。
或者我们可以通过debug object key 命令去查看serializedlength属性,serializedlength表示key对应的value序列化后的字节数,通过观察serializedlength的大小可以辅助排查bigKey。使用scan + debug object key命令,我们可以计算其中每个key的serializedlength,进而发现其中的bigKey,并做好相应的监控和处理。不过对于集合类型的bigKey,debug object key 命令的执行效率不高,存在阻塞redis的风险。
另外,在读取bigKey的时候,我们尽量不要一次性将全部数据读取出来,而是采用分批的方式进行读取:利用scan命令进行渐进式遍历,将大量数据分批多次读取出来,减小redis的压力,避免阻塞的风险。
同样的,在删除bigKey的时候我们也可以使用scan命令来进行批量删除。如果你是用的redis是4.0之后的版本,则可以利用unlink命令配合lazy free配置(需要手动开启)来进行异步删除,避免主线程阻塞。
redis架构模式(6)数据倾斜
数据倾斜通常分为两种情况,一是各实例上面的数据不均匀,个别实例数据量特别多;
二是某个实例上的热点数据多,导致的访问量倾斜。发生了数据倾斜,那么保存了大量
数据或者是保存了热点数据的实例的处理压力就会增大,速度变慢,甚至还可能会引起
这个实例的内存资源耗尽导致宕机风险。
如果某个实例上保存了bigkey,会导致这个实例的数据量及相应的内存资源消耗增加,
bigkey的操作容易导致主线程IO的阻塞,bigkey最好能够从业务层面避免掉,正轿如果是
集合类型的bigkey,建议拆分成多个集合多实例保存,再根据业务逻辑做相应的映射。
solt分配不均,就根据具体的使用的中间件查看slot分布情况进而做具体slot迁移
hashtag指的是对key的部分用{}圈起来,例如dramaId:episode:1232变成
dramaId:episode:{1232},在计算 key 的 CRC16 值时,只对HashTag花括号中的
key内容进行计算,这有什么用处呢?就是key不一样但是hashtag内容一样的key
会被分配到同一个slot,它主要是用在 Redis Cluster 和 Codis中,支持事务操作
和范围查询。因为 Redis Cluster 和 Codis 本身并不支持跨实例的事务操作和
范围查询,当业务应用有这些需求时,就只能先把这些数据读取到业务层进行事务
处理,或者是逐个查询每个实例,得到范围查询的结果,所以我们可以使用 Hash Tag
把要执行事务操作或是范围查询的数据映射到同一个实例上,这样就能很轻松实现
事务或范围查询,潜在的风险就是会导致大量的数据被分配到同一实例,导致数据
倾斜和集群负载不均衡,所以迅亮在hashtag和业务上的事务范围查询,得我们自己做
取舍,建议还是避免hashtag
在某个实例上的商品或者某些影视剧集突然火了,那么就导致这个实例的访问量突增,
好在热点数据通常只是读,所以我们可以采用热点数据多副本的方式应对,我们把热点
数据复制多份,然后把key加个前缀,使其分布在不同的slot,查询的时候做好相应逻举昌肆辑,
那么即可把热点数据的压力分摊到多实例上
Redis删除big key的方法
这里注意:
1)以迹凳迹上的操作可以使用pipeline加速。
2)redis 4.0已粗皮经支持key的异步删除,可姿并以使用。
参考资料:
关于redisbigkey和redisbigkeys内容详解的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。