redis 数据删除策略和逐出算法的问题小结

2020-06-12 15:00:04王旭

内存压力很大,出现长期占用内存的数据。

总结

用存储空间换取处理器性能

定期删除

周期性轮询redis库中时效性数据,采用随机抽取的策略,利用过期数据占比的方式删除频度。

优点

CPU性能占用设置有峰值,检测频度可自定义设置

内存压力不是很大,长期占用内存的冷数据会被持续清理

缺点

需要周期性抽查存储空间

定期删除详解

redis的定期删除是通过定时任务实现的,也就是定时任务会循环调用serverCron方法。然后定时检查过期数据的方法是databasesCron。定期删除的一大特点就是考虑了定时删除过期数据会占用cpu时间,所以每次执行databasesCron的时候会限制cpu的占用不超过25%。真正执行删除的是 activeExpireCycle方法。

时间事件

对于持续运行的服务器来说, 服务器需要定期对自身的资源和状态进行必要的检查和整理, 从而让服务器维持在一个健康稳定的状态, 这类操作被统称为常规操作(cron job)

在 Redis 中, 常规操作由 redis.c/serverCron() 实现, 它主要执行以下操作

1 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等。

2 清理数据库中的过期键值对。

3 对不合理的数据库进行大小调整。

4 关闭和清理连接失效的客户端。

5 尝试进行 AOF 或 RDB 持久化操作。

6 如果服务器是主节点的话,对附属节点进行定期同步。

7 如果处于集群模式的话,对集群进行定期同步和连接测试。

因为 serverCron() 需要在 Redis 服务器运行期间一直定期运行, 所以它是一个循环时间事件: serverCron() 会一直定期执行,直到服务器关闭为止。

在 Redis 2.6 版本中, 程序规定 serverCron() 每秒运行 10 次, 平均每 100 毫秒运行一次。 从 Redis 2.8 开始, 用户可以通过修改 hz选项来调整 serverCron() 的每秒执行次数, 具体信息请参考 redis.conf 文件中关于 hz 选项的说明

查看hz

way1 : config get hz # "hz" "10"
way2 : info server # server.hz 10

serverCron()

serverCron()会定期的执行,在serverCron()执行中会调用databasesCron() 方法(serverCron()还做了其他很多事情,但是现在不讨论,只谈删除策略)

int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
 // 略去多无关代码

 /* We need to do a few operations on clients asynchronously. */
 // 检查客户端,关闭超时客户端,并释放客户端多余的缓冲区
 clientsCron();

 /* Handle background operations on Redis databases. */
 // 对数据库执行各种操作
 databasesCron(); /* !我们关注的方法! */