用外链技术做视频网站,ps网站主页按钮怎么做,wordpress企业版主体,好听的域名取名Redis中的BigKey 文章目录 Redis中的BigKey什么是BigKey#xff1f;BigKey的危害找到Bigkey删除BigKey优化BigKeyBigKey对持久化的影响对AOF日志的影响对AOF重写和RDB的影响 什么是BigKey#xff1f;
大 key 并不是指 key 的值很大#xff0c;而是 key 对应的 value 很大。…Redis中的BigKey 文章目录 Redis中的BigKey什么是BigKeyBigKey的危害找到Bigkey删除BigKey优化BigKeyBigKey对持久化的影响对AOF日志的影响对AOF重写和RDB的影响 什么是BigKey
大 key 并不是指 key 的值很大而是 key 对应的 value 很大。
一般而言下面这两种情况被称为大 key
String 类型的值大于 10 KBHash、List、Set、ZSet 类型的元素的个数超过 5000个
BigKey的危害
网络阻塞 对BigKey执行读请求时少量的QPS就可能导致带宽使用率被占满导致Redis实例乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例无法使数据分片的内存资源达到均衡 Redis阻塞 对元素较多的hash、list、zset等做运算会耗时较旧使主线程被阻塞 CPU压力 对BigKey的数据序列化和反序列化会导致CPU的使用率飙升影响Redis实例和本机其它应用
找到Bigkey
1、redis-cli --bigkeys 查找大key
可以通过 redis-cli --bigkeys 命令查找大 key
redis-cli -h 127.0.0.1 -p6379 -a password -- bigkeys使用的时候注意事项
最好选择在从节点上执行该命令。因为主节点上执行时会阻塞主节点如果没有从节点那么可以选择在 Redis 实例业务压力的低峰阶段进行扫描查询以免影响到实例的正常运行或者可以使用 -i 参数控制扫描间隔避免长时间扫描降低 Redis 实例的性能。
该方式的不足之处
这个方法只能返回每种类型中最大的那个 bigkey无法得到大小排在前 N 位的 bigkey对于集合类型来说这个方法只统计集合元素个数的多少而不是实际占用的内存量。但是一个集合中的元素个数多并不一定占用的内存就多。因为有可能每个元素占用的内存很小这样的话即使元素个数有很多总内存开销也不大
2、使用 SCAN 命令查找大 key
使用 SCAN 命令对数据库扫描然后用 TYPE 命令获取返回的每一个 key 的类型。
对于 String 类型可以直接使用 STRLEN 命令获取字符串的长度也就是占用的内存空间字节数。
对于集合类型来说有两种方法可以获得它占用的内存大小
如果能够预先从业务层知道集合元素的平均大小那么可以使用下面的命令获取集合元素的个数然后乘以集合元素的平均大小这样就能获得集合占用的内存大小了。List 类型LLEN 命令Hash 类型HLEN 命令Set 类型SCARD 命令Sorted Set 类型ZCARD 命令如果不能提前知道写入集合的元素大小可以使用 MEMORY USAGE 命令需要 Redis 4.0 及以上版本查询一个键值对占用的内存空间。
3、使用 RdbTools 工具查找大 key
使用 RdbTools 第三方开源工具可以用来解析 Redis 快照RDB文件找到其中的大 key。
比如下面这条命令将大于 10 kb 的 key 输出到一个表格文件。
rdb dump.rdb -c memory --bytes 10240 -f redis.csv删除BigKey
1、分批次删除
如果是集合类型则遍历BigKey的元素先逐个删除子元素最后删除BigKey
2、异步删除
从 Redis 4.0 版本开始可以采用异步删除法用 unlink 命令代替 del 来删除。
这样 Redis 会将这个 key 放入到一个异步线程中进行删除这样不会阻塞主线程。
优化BigKey
假如有hash类型的key其中有100万对field和valuefield是自增id这个key存在什么问题如何优化
keyfieldvaluesomeKeyid:0value0..........id:999999value999999
存在的问题
hash的entry数量超过500时会使用哈希表而不是ZipList内存占用较多 可以通过hash-max-ziplist-entries配置entry上限。但是如果entry过多就会导致BigKey问题
拆分为小的hash将 id / 100 作为key 将id % 100 作为field这样每100个元素为一个Hash BigKey对持久化的影响
对AOF日志的影响
Redis 提供了 3 种 AOF 日志写回硬盘的策略分别是
Always这个单词的意思是「总是」所以它的意思是每次写操作命令执行完后同步将 AOF 日志数据写回硬盘Everysec这个单词的意思是「每秒」所以它的意思是每次写操作命令执行完后先将命令写入到 AOF 文件的内核缓冲区然后每隔一秒将缓冲区里的内容写回到硬盘No意味着不由 Redis 控制写回硬盘的时机转交给操作系统控制写回的时机也就是每次写操作命令执行完后先将命令写入到 AOF 文件的内核缓冲区再由操作系统决定何时将缓冲区内容写回硬盘。
总结一下
Always 策略就是每次写入 AOF 文件数据后就执行 fsync() 函数Everysec 策略就会创建一个异步任务来执行 fsync() 函数No 策略就是永不执行 fsync() 函数;
当 AOF 写回策略配置了 Always 策略如果写入是一个大 Key主线程在执行 fsync() 函数的时候阻塞的时间会比较久因为当写入的数据量很大的时候数据同步到硬盘这个过程是很耗时的。
当使用 Everysec 策略的时候由于是异步执行 fsync() 函数所以大 Key 持久化的过程数据同步磁盘不会影响主线程。
当使用 No 策略的时候由于永不执行 fsync() 函数所以大 Key 持久化的过程不会影响主线程。
对AOF重写和RDB的影响
AOF 重写机制和 RDB 快照bgsave 命令的过程都会分别通过 fork() 函数创建一个子进程来处理任务。会有两个阶段会导致阻塞父进程主线程
创建子进程的途中由于要复制父进程的页表等数据结构阻塞的时间跟页表的大小有关页表越大阻塞的时间也越长创建完子进程后如果父进程修改了共享数据中的大 Key就会发生写时复制这期间会拷贝物理内存由于大 Key 占用的物理内存会很大那么在复制物理内存这一过程就会比较耗时所以有可能会阻塞父进程。