使用shell脚本优雅删除redis的大key
本文关于大键(key)的描述参考博客:https://www.geek-share.com/detail/2724939666.html
理解大key
理解redis中的大key,可从两方面的来理解:1、时间复杂度,2、空间复杂度。前者主要表示Redis键的占用内存大小;后者表示Redis集合数据类型(set/hash/list/sorted set)键,所含有的元素个数。内存空间复杂性处理耗时都非常小,测试 del 200MB String键耗时约1毫秒,而删除一个含有1kw个字段的Hash键,却会阻塞Redis进程数十秒。
直接删除大Key的风险
DEL命令在删除单个集合类型的Key时,命令的时间复杂度是O(M),其中M是集合类型Key包含的元素个数。
DEL key
Time complexity: O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).
redis是单线程处理的,单个耗时过大命令,会导致阻塞其它命令,容易引起应用程序雪崩或redis集群发生故障切换。所以避免在生产环境中使用耗时过大的命令。
scan命令
关于scan的理解请看:https://blog.csdn.net/still_fantasy/article/details/80963550
为避免删除大key带来的阻塞风险,在下面的脚本例子中会先使用sscan命令遍历set集合中一定数量成员,再使用del命令将这些成员数删除。从而达到将删除一个大key化整为零,分为一小步一小步删除,从而达到避免redis服务器长时间阻塞的目的。
shell脚本
以集合set为例子:
[code]function delSet() { key=$3 rs=`redis-cli -p $1 -a $2 exists $key` scannum=100 #echo $rs if [ `echo $rs | awk -v tem="0" '{print($1>tem)? "1":"0"}'` -eq "0" ] ; then echo "redis doesn't exist the key $key" else cursor="1" members=`redis-cli -p $1 -a $2 sscan $key 0 count $scannum` while [ `echo $cursor | awk -v tem="0" '{print($1>tem)? "1":"0"}'` -eq "1" ] ; do OLD_IFS="$IFS" IFS=" " array=($members) IFS="$OLD_IFS" count=1 delkeys="" for var in ${array[@]} do if [ $count -eq 1 ] ; then cursor=$var count=$((count+1)) else #rs=`redis-cli -p $1 -a $2 SREM $key $var` #echo "del:$var" delkeys=$delkeys$var" " fi done rs=`redis-cli -p $1 -a $2 SREM $key $delkeys` if [ `echo $cursor | awk -v tem="0" '{print($1>tem)? "1":"0"}'` -eq "1" ];then members=`redis-cli -p $1 -a $2 sscan $key $cursor count $scannum` fi done fi } key="setkey" echo "start remove the key $key" delSet $1 $2 $key rs=`redis-cli -p $1 -a $2 del $key` echo "remove the key $key successfully"
阅读更多
- 删除redis集群上的key的shell脚本
- shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作
- 利用shell脚本监控redis的使用内存
- 通过shell脚本删除代码里面定义但未使用的变量
- redis中跑lua脚本删除指定key
- 使用shell脚本删除系统用户
- 使用RMAN和控制文件备份删除归档日志的SHELL脚本--RED HAT 5 LINUX 64
- shell脚本中使用tr命令实现对字符串删除、替换和赋值
- Linux监控系统磁盘使用比例,当使用率达到指定比例,删除指定目录下的所有文件的shell脚本
- shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作
- 使用shell 脚本递归删除项目中的所有源文件的行注释
- linux下使用shell编写的删除历史文件的脚本 find | xargs tar 有文件个数限制哦
- shell脚本使用cat和EOF组合添加和删除文件内容
- shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作
- shell脚本操作mysql数据库,使用mysql的-e参数可以执行各种sql的(创建,删除,增,删,改、查)等各种操作
- 书写优雅的shell脚本(四) - kill命令的合理使用
- 用户管理(二):使用shell脚本批量删除除root用户以外的其它用户
- 使用Linux管道批量删除Redis的key
- redis中跑lua脚本删除指定key
- 书写优雅的shell脚本(四) - kill命令的合理使用