Redis bigkeys操作 附:自己的代码

什么是 bigkey

在Redis中,一个字符串最大512MB,一个二级数据结构(例如hash、list、set、zset)可以存储大约40亿个(2^32-1)个元素,但实际上中如果下面两种情况,我就会认为它是bigkey。

字符串类型:它的big体现在单个value值很大,一般认为超过10KB就是bigkey。

非字符串类型:哈希、列表、集合、有序集合,它们的big体现在元素个数太多。

危害

1.内存空间不均匀

这样会不利于集群对内存的统一管理,存在丢失数据的隐患。

2.超时阻塞

由于Redis单线程的特性,操作bigkey的通常比较耗时,也就意味着阻塞Redis可能性越大,这样会造成客户端阻塞或者引起故障切换,它们通常出现在慢查询中。

3.网络拥塞

bigkey也就意味着每次获取要产生的网络流量较大,假设一个bigkey为1MB,客户端每秒访问量为1000,那么每秒产生1000MB的流量,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直是灭顶之灾,而且一般服务器会采用单机多实例的方式来部署,也就是说一个bigkey可能会对其他实例造成影响,其后果不堪设想。

4.过期删除

有个bigkey,它安分守己(只执行简单的命令,例如hget、lpop、zscore等),但它设置了过期时间,当它过期后,会被删除,如果没有使用Redis 4.0的过期异步删除(lazyfree-lazy-expire yes),就会存在阻塞Redis的可能性,而且这个过期删除不会从主节点的慢查询发现(因为这个删除不是客户端产生的,是内部循环事件,可以从latency命令中获取或者从slave节点慢查询发现)。

5.迁移困难

当需要对bigkey进行迁移(例如Redis cluster的迁移slot),实际上是通过migrate命令来完成的,migrate实际上是通过dump + restore + del三个命令组合成原子命令完成,如果是bigkey,可能会使迁移失败,而且较慢的migrate会阻塞Redis。

怎么产生的

一般来说,bigkey的产生都是由于程序设计不当,或者对于数据规模预料不清楚造成的,来看几个:

(1) 社交类:粉丝列表,如果某些明星或者大v不精心设计下,必是bigkey。

(2) 统计类:例如按天存储某项功能或者网站的用户集合,除非没几个人用,否则必是bigkey。

(3) 缓存类:将数据从数据库load出来序列化放到Redis里,这个方式非常常用,但有两个地方需要注意:

第一,是不是有必要把所有字段都缓存

第二,有没有相关关联的数据

建议

string 控制在 10kb 以内,hash、list、set、zset元素个数不要超过5000。反之,则称之为「bigkey」。

如何发现呢

既然知道有这些危害了,那该怎么避免呢?

可以使用 redis-cli 原生命令   redis-cli --bigkeys

这个命令是使用「scan」进行取样处理的,所有并不用太担心会阻塞 redis。统计完的结果如下

[01.35%] Biggest string found so far 'AAA:SHOPPING:FlightInfoCacheService:getFlightScheduleInfoMap:CTU PEK 2022 07 09' with 3535 bytes
[02.22%] Biggest string found so far 'AAA:ORDER:JOURNEY_INFO:88342190' with 9226 bytes
[08.10%] Biggest string found so far 'AAA:BAGGAGE:CONGIG:G5:V' with 28249 bytes
[26.00%] Biggest string found so far 'AAA:FS:QUERY:PKX:SZX:20220710' with 35530 bytes
[29.30%] Biggest hash   found so far 'AAA:FRM:SZX:HAK' with 173 fields
[30.39%] Biggest hash   found so far 'AAA:FRM:CGO:HAK' with 195 fields
[40.85%] Biggest string found so far 'AAA:FS:QUERY:CAN:CKG:20220711' with 47711 bytes
[51.40%] Biggest hash   found so far 'AAA:FRM:LGA:CMH' with 233 fields
[61.67%] Biggest string found so far 'AAA:ORDER:JOURNEY_INFO:90388812' with 184500 bytes
[63.14%] Biggest hash   found so far 'AAA:FRM:CJU:GMP' with 318 fields

        从这个结果可以得出,它会统计出每一种数据结构 top 1 的「bigkey」。同时,也可以增加一个 --i 阈值,让它定时执行一次统计。例如下面的命令,表示100毫秒执行一次

redis-cli -h $REDIS_IP -p $REDIS_PORT -n 0  --i 0.1 --bigkeys

附:自己写的简易代码 可以批处理操作

#!/bin/bash
# Filename   : redis BIGKEYS key 
# Version    : 1.0


#auth  liudh
 

WORK_HOME=./

cd ${WORK_HOME}

echo "">redis_bigkeys_list
date=`date`
function commit_bigkeys()
{
    redis-cli -h $REDIS_IP -p $REDIS_PORT -n 0 --bigkeys >> redis_bigkeys_list
}

while read REDIS_IP  REDIS_PORT
do
    if [ -n ${REDIS_IP} ]; then
        REDIS_IP=${REDIS_IP}
        REDIS_PORT=${REDIS_PORT}
        echo " ${date} ${REDIS_IP}: ${REDIS_PORT} analysis bigkeys begin " >>redis_bigkeys_list
        commit_bigkeys
        sleep 1
        echo " ${date} ${REDIS_IP}: ${REDIS_PORT} analysis bigkeys over " >>redis_bigkeys_list
        echo ""
    fi
done < redis_bigkeys_ip_port.txt

echo "analysis over , please see list!"

 redis_bigkeys_ip_port.txt
 
 192.168.1.1 6379
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值