redis中的大key和unlink操作
1、什么是 bigkey
Key 本身的数据量过大:一个 String 类型的 Key,它的值为 5 MB。
Key 中的成员数过多:一个 ZSET 类型的 Key,它的成员数量为 10,000 个。
Key 中成员的数据量过大:一个 Hash 类型的 Key,它的成员数量虽然只有 1,000 个但这些成员的 Value(值)总大小为 100 MB。
2、bigkey 的影响
集群架构下,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡
如果 bigkey 一直在增长,会导致 Redis 内存 OOM,影响读写性能
因为 Redis 是单线程的,对 bigkey 的增删改操作,会导致超时,甚至阻塞服务
对大 Key 执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换
3、如何避免 bigkey
如果是 hash 的话,通过一定规则拆分到不同 hash 中,特别是在集群中很有效果
堆积大量过期数据会造成大 Key 的产生,例如在 HASH 数据类型中以增量的形式不断写入大量数据而忽略了数据的时效性。可以通过定时任务的方式对失效数据进行清理。
对大 Key 进行直接删除
4、如何查看 bigkey
可以通过 Redis 客户端命令查看:
redis-cli --bigkeys
Scanning the entire keyspace to find biggest keys as well as
average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
per 100 SCAN commands (not usually needed).
[00.00%] Biggest string found so far '"frontLastPullSysMsgId:1257:964350"' with 5 bytes
[00.00%] Biggest string found so far '"exam_data:1233:913172:39017:140692"' with 8885 bytes
[00.01%] Biggest string found so far '"exam_data:319:877777:14274:126728"' with 14875 bytes
[00.03%] Biggest list found so far '"live_merge:154_159588"' with 9 items
[00.06%] Biggest string found so far '"exam_data:319:1101505:52328:151653"' with 19125 bytes
[00.07%] Biggest hash found so far '"timer_ids:company_id:1134:sys_id:5"' with 11 fields
[00.17%] Biggest string found so far '"exam_data:908:644980:22627:146279"' with 31320 bytes
[00.30%] Biggest hash found so far '"timer_ids:company_id:927:sys_id:5"' with 130 fields
[00.73%] Biggest hash found so far '"timer_ids:company_id:264:sys_id:2"' with 551 fields
[01.19%] Biggest string found so far '"exam_data:973:693508:33936:128891"' with 40643 bytes
[03.09%] Biggest hash found so far '"timer_ids:company_id:1183:sys_id:5"' with 625 fields
[03.29%] Biggest hash found so far '"timer_ids:company_id:1183:sys_id:2"' with 1410 fields
[06.39%] Biggest string found so far '"exam_data:301:104065:51535:165675"' with 127069 bytes
[06.75%] Biggest hash found so far '"websocket_duration"' with 1560568 fields
[37.36%] Biggest string found so far '"exam_data:301:104065:51536:165675"' with 128746 bytes
[81.08%] Sampled 1000000 keys so far
-------- summary -------
Sampled 1233274 keys in the keyspace!
Total key length in bytes is 48419022 (avg len 39.26)
Biggest list found '"live_merge:154_159588"' has 9 items
Biggest hash found '"websocket_duration"' has 1560568 fields
Biggest string found '"exam_data:301:104065:51536:165675"' has 128746 bytes
14 lists with 47 items (00.00% of keys, avg size 3.36)
2736 hashs with 1726892 fields (00.22% of keys, avg size 631.17)
1230524 strings with 1649082886 bytes (99.78% of keys, avg size 1340.15)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
优点:方便、快速、安全
缺点:分析结果不可定制化,准确性与时效性差
可以使用 redis-rdb-tools 或者 xueqiu/rdr,有对应的图形界面看着也很清晰
优点:支持定制化分析,对线上服务无影响
缺点:时效性差,RDB 文件较大时耗时较长
5、如何删除 bigkey
Redis 4.0 及之后版本:您可以通过 UNLINK 命令安全地删除大 Key 甚至特大 Key,该命令能够以非阻塞的方式,逐步地清理传入的 Key。
Redis 4.0 之前的版本:建议先通过 SCAN 命令读取部分数据,然后进行删除,避免一次性删除大量 key 导致 Redis 阻塞。
清理 HASH 数据时,建议通过 HSCAN 命令配合 HDEL 命令对失效数据进行清理,避免清理大量数据造成 Redis 阻塞。
6、UNLINK
Redis 4.0 开始引入了 UNLINK 命令,他和 del 的作用是一样的。但是区别就在于 del 是单线程的,如果删除的是 bigkey 的话,会导致整个服务都被占用。
UNLINK 其实就是把 del 的操作分到了 2 个线程里面:
在主线程中,从整个键空间中删除键
在另一个线程回收内存
虽然分在了 2 个线程里,但是操作也是安全的,并不会带来我删着删着又被读到了的并发问题。因为它(在主线程中)从键空间中删除了对象,因此任何 Redis 命令都无法访问它。
如果你有很大的值,速度会显着提高——UNLINK 是一个 O(1) 操作(每个键;在主线程中),而不管键中保存的值的大小。使用 DEL 删除一个大值可能需要几百毫秒或更长时间,而 UNLINK 将在不到一毫秒的时间内完成(包括网络往返)。
但是并不是说 del 无用武之地了,当需要实时响应的时候最好还是 del,因为毕竟 UNLINK 是一个异步操作。
标签:far,Redis,so,Key,Biggest,found,unlink,delete From: https://www.cnblogs.com/DCFV/p/18345940