前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >定时自动删除redis key

定时自动删除redis key

作者头像
用户1148526
发布2021-12-07 12:43:22
2.1K0
发布2021-12-07 12:43:22
举报
文章被收录于专栏:Hadoop数据仓库Hadoop数据仓库

目录

1. 背景描述

2. 实现脚本

3. 自动执行

1. 背景描述

使用redis存储群发消息。当初匆忙上线,设计上有两个主要问题:一是在每个userid的key中存储消息体,从数据库的角度看,存在大量的数据冗余,占用大量存储空间。二是不设置key的过期时间,使得redis像貔貅一样只进不出,不断膨胀。

由于对用户的群发消息量很大,使得redis几天就内存报警。开始时使用单实例redis,遇到报警就增加maxmemory配置。后来将单实例进行拆分,按照userid取模4,拆分成4个redis实例。但结果是治标不治本,依旧撑不了几天,架不住一个劲地狂发消息啊。不得已只能采用定期删除未读消息的方案来弥补设计缺陷。

2. 实现脚本

delmsg.sh内容如下:

代码语言:javascript
复制
#!/bin/bash

cd ~/delmsg/

# 已处理的最大logid,首次为0
max_logid=`cat max_logid.txt`

# 从mysql导出三天前的数据,这部分可以删除。mod4列用来标识userid的模数。
d=`date +'%Y-%m-%d'`
mysql -u user1 -p123456 -h 10.10.10.1 -P3306 -D db1 -N -e "
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('$d')* 100 + month('$d')
   and createTime < date_sub('$d', interval 3 day)
   and logid > $max_logid order by logid" > yushu.txt

# 如果导出文件为空则退出脚本
if [[ ! -s yushu.txt ]] 
then
  exit 1
fi

######## 处理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中增加项:

代码语言:javascript
复制
0 4 * * * /home/redis/delmsg/delmsg.sh > /home/redis/delmsg/delmsg.log 2>&1
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-05-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景描述
  • 2. 实现脚本
  • 3. 自动执行
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档