You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$ 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 'key-419' with 3 bytes
[05.14%] Biggest list found so far 'mylist' with 100004 items
[35.77%] Biggest string found so far 'counter:__rand_int__' with 6 bytes
[73.91%] Biggest hash found so far 'myobject' with 3 fields
-------- summary -------
Sampled 506 keys in the keyspace!
Total key length in bytes is 3452 (avg len 6.82)
Biggest string found 'counter:__rand_int__' has 6 bytes
Biggest list found 'mylist' has 100004 items
Biggest hash found 'myobject' has 3 fields
504 strings with 1403 bytes (99.60% of keys, avg size 2.78)
1 lists with 100004 items (00.20% of keys, avg size 100004.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
1 hashs with 3 fields (00.20% of keys, avg size 3.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
内存不均
导致集群内不同节点内存分布不均,间接导致访问请求倾斜,同时不利于集群统一管理,存在丢失数据的隐患。
超时阻塞
由于 Redis 单线程模型,在操作 bigkey 的时候很容易出现阻塞甚至导致 Sentinel 主从切换。 常见的操作包括
SMEMBERS
、HGETALL
、DEL
或自动过期 bigKey,一般都会出现在 Redis 慢查询日志中。网络流量拥塞
如果 bigkey 正好又是 hot key,则容易产生流量拥塞问题,比如 bigkey 为 1MB,每秒访问几千次, 对于普通千兆网卡(最大 128MB/s)服务器来说是灭顶之灾,即便对于万兆网卡服务器来说也是很大压力。
而且一般服务器都会采用单机多 Redis 实例的方式部署,也就是说某个 Redis 实例上的 bigkey 可能会对其他 Redis 实例造成巨大影响。
如何发现 Bigkey
方案 1:redis-cli --bigkeys
使用官方的 redis-cli --bigkeys 时,它会对 Redis 中的 key 进行
SCAN
采样,寻找较大的 keys,不用担心会阻塞 Redis。执行的结果可以用于分析 Redis 的内存的使用用状态和各种类型 key 的平均大小。
方案 2:redis-rdb-tools 工具
redis-rdb-tools 是用 Python 写的用来分析 Redis 的 rdb 快照文件用的工具, 它可以把 rdb 快照文件生成 CSV 或 JSON 文件,也可以导入到 MySQL 生成报表来分析。
可以通过 Python 的 pip 来安装:
pip install rdbtools
。使用方法:
对 slave 进行
得到 rdb 文件
生成内存快照
在生成的 CSV 文件中以下几列:
database
key 在 Redis 的 dbtype
key 类型key
key 值size_in_bytes
key 的内存大小encoding
value 的存储编码形式num_elements
key 中的 value 的个数len_largest_element
key 中的 value 的长度将 CSV 文件导入到 MySQL 进行分析 在 MySQL 中新建表,然后导入 CSV 数据。
查询内存占用最高的 3 个 key
查询元素最多的 3 个 key
方案对比
如何删除 bigkey
如果直接
DEL
bigkey 操作可能会引发 Redis 阻塞甚至是发生 Sentinel 主从切换,那么如果清理这些 bigkey 呢?答案是 SCAN 命令组 ,从 Redis 2.8 版本开始支持
SCAN
命令, 可以指定 count,来分多批枚举 bigkey,然后实现渐进式删除 bigkey。Redis 4.0 新增 UNLINK 命令 ,是
DEL
命令的异步版本, 它将删除键的操作放在后台线程执行,从而尽可能地避免服务器阻塞。此外,Redis 4.0 中的FLUSHDB
和FLUSHALL
新增ASYNC
选项, 带有这个选项的操作也将在后台线程进行。删除 big string
删除
string
类型的 bigkey,不会造成 Redis 阻塞,可以直接用DEL
。删除 big hash key
使用
HSCAN
命令,每次获取 500 个元素,再用HDEL
命令结合pipeline
批量删除。参考 Python 代码实现:
删除 big set key
使用
SSCAN
命令,每次获取 500 个元素,再用SREM
命令结合pipeline
批量删除。删除 big list key
使用
LTRIM
命令,每次删除 100 个元素。删除 big sortedset key
使用
ZREMRANGEBYRANK
命令,每次删除 Top 100 个元素。如何避免 bigkey
主要是对 bigkey 进行拆分,拆成多个 key,然后用
MGET
取回来,再在业务层做合并。扩展资料
The text was updated successfully, but these errors were encountered: