定时自动删除redis key
Posted wzy0623
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定时自动删除redis key相关的知识,希望对你有一定的参考价值。
目录
1. 背景描述
使用redis存储群发消息。当初匆忙上线,设计上有两个主要问题:一是在每个userid的key中存储消息体,从数据库的角度看,存在大量的数据冗余,占用大量存储空间。二是不设置key的过期时间,使得redis像貔貅一样只进不出,不断膨胀。
由于对用户的群发消息量很大,使得redis几天就内存报警。开始时使用单实例redis,遇到报警就增加maxmemory配置。后来将单实例进行拆分,按照userid取模4,拆分成4个redis实例。但结果是治标不治本,依旧撑不了几天,架不住一个劲地狂发消息啊。不得已只能采用定期删除未读消息的方案来弥补设计缺陷。
2. 实现脚本
delmsg.sh内容如下:
#!/bin/bash
cd ~/delmsg/
# 已处理的最大logid,首次为0
max_logid=`cat max_logid.txt`
# 从mysql导出三天前的数据,这部分可以删除。mod4列用来标识userid的模数。
mysql -u user1 -p123456 -h 10.10.10.1 -P3306 -D db1 -N -e "
select @dt:=current_date;
select logid, userid, msgorder,
case when mod(userid,4)=0 then 'mod4_0'
when mod(userid,4)=1 then 'mod4_1'
when mod(userid,4)=2 then 'mod4_2'
else 'mod4_3'
end mod4
from batch_system_msg_user_msgorder_log
where yearMonth=year(@dt)* 100 + month(@dt)
and createTime < date_sub(@dt, interval 3 day)
and logid > $max_logid order by logid" > yushu.txt
######## 处理mod4_0(20007端口的redis实例)########
# 生成mod4_0的redis命令文件,每个文件不超过50000行,避免报redis每秒命令数超限警告
grep mod4_0 yushu.txt | awk '{print "zremrangebyscore UnReadMessageEx_"$2 " " $3 " " $3}' | split -l 50000 -d -a 5 - yushu0_
# 由于可能发生自动主从redis切换,需要从哨兵获取当前20007端口的master ip
master=`/home/redis/redis-5.0.3/src/redis-cli -p 30001 info | grep 20007 | awk -F, {'print $3'} | awk -F= {'print $2'} | awk -F: {'print $1'}`
# 删除消息。使用--pipe方式逐个处理split生成的命令文件,每个文件处理后sleep 1秒用于缓解负载。
ls -l yushu0_* | awk {'print "cat " $9 " | /home/redis/redis-5.0.3/src/redis-cli -h '$master' -p 20007 -a 123456 -n 1 --pipe; sleep 1;"'} > yushu0.sh
chmod 755 yushu0.sh
./yushu0.sh
######## 处理mod4_1(20006端口的redis实例)########
grep mod4_1 yushu.txt | awk '{print "zremrangebyscore UnReadMessageEx_"$2 " " $3 " " $3}' | split -l 50000 -d -a 5 - yushu1_
master=`/home/redis/redis-5.0.3/src/redis-cli -p 30001 info | grep 20006 | awk -F, {'print $3'} | awk -F= {'print $2'} | awk -F: {'print $1'}`
ls -l yushu1_* | awk {'print "cat " $9 " | /home/redis/redis-5.0.3/src/redis-cli -h '$master' -p 20006 -a 123456 -n 1 --pipe; sleep 1;"'} > yushu1.sh
chmod 755 yushu1.sh
./yushu1.sh
######## 处理mod4_2(20015端口的redis实例) ########
grep mod4_2 yushu.txt | awk '{print "zremrangebyscore UnReadMessageEx_"$2 " " $3 " " $3}' | split -l 50000 -d -a 5 - yushu2_
master=`/home/redis/redis-5.0.3/src/redis-cli -p 30001 info | grep 20015 | awk -F, {'print $3'} | awk -F= {'print $2'} | awk -F: {'print $1'}`
ls -l yushu2_* | awk {'print "cat " $9 " | /home/redis/redis-5.0.3/src/redis-cli -h '$master' -p 20015 -a 123456 -n 1 --pipe; sleep 1;"'} > yushu2.sh
chmod 755 yushu2.sh
./yushu2.sh
######## 处理mod4_3(20014端口的redis实例) ########
grep mod4_3 yushu.txt | awk '{print "zremrangebyscore UnReadMessageEx_"$2 " " $3 " " $3}' | split -l 50000 -d -a 5 - yushu3_
master=`/home/redis/redis-5.0.3/src/redis-cli -p 30001 info | grep 20014 | awk -F, {'print $3'} | awk -F= {'print $2'} | awk -F: {'print $1'}`
ls -l yushu3_* | awk {'print "cat " $9 " | /home/redis/redis-5.0.3/src/redis-cli -h '$master' -p 20014 -a 123456 -n 1 --pipe; sleep 1;"'} > yushu3.sh
chmod 755 yushu3.sh
./yushu3.sh
# 更新已处理的最大logid
tail -1 yushu.txt | awk '{print $1}' > max_logid.txt
# 清理文件
rm -f yushu0_* yushu1_* yushu2_* yushu3_*
3. 自动执行
在crontab中增加项:
0 4 * * * /home/redis/delmsg/delmsg.sh > /home/redis/delmsg/delmsg.log 2>&1
以上是关于定时自动删除redis key的主要内容,如果未能解决你的问题,请参考以下文章