Redis的渐进式hash和缓存时间戳深入学习
前言
关于redis,可由应用维度、系统维度来进行了解。
如下所示:
redis在缓存应用发挥着重要作用,不知道你有没思考过Redis为什么这么快?
1、纯内存访问
为什么内存访问比磁盘访问更快,可参考:
操作系统的内核态和用户态场景-CSDN博客https://blog.csdn.net/weixin_50055999/article/details/148189950?spm=1011.2415.3001.5331
2、单线程避免上下文切换
关于I/O多路复用,可参考:关于多线程的Redis模型_redis线程模型-CSDN博客https://blog.csdn.net/weixin_50055999/article/details/147977886?spm=1011.2415.3001.5331
3、渐进式ReHash、缓存时间戳
1、渐进式ReHash
1.1、全局哈希表
为了实现快速根据键访问到值,Redis使用了一个全局哈希表来存储所有的键值对。
一个哈希表其实就是一个数组,数组的每个元素称为一个哈希桶。
如下图所示:
1.2、核心流程
1、扩、缩容触发条件:
- 扩容:当哈希表的负载因子(键数量/桶数量)超过阈值(默认 1.0,且无后台保存任务;或 5.0,若有后台保存任务)时触发。
- 缩容:当负载因子过低(如低于 0.1)时触发,以节省内存。
如下图所示:
2、核心机制:
Redis 维护两个哈希表:ht[0](旧表)和 ht[1](新表)。
1、当触发 ReHash 时,Redis 创建一个更大的(或更小的)新哈希表 ht[1],并将数据从 ht[0] 逐步迁移到 ht[1]。
2、迁移过程通过 渐进式操作 分摊到每次读写操作中,而不是一次性完成。
3、Redis 使用一个 rehashidx 指针记录当前迁移的桶(bucket)位置,逐步将 ht[0] 的桶迁移到 ht[1]。
4、迁移期间,Redis 会同时查询 ht[0] 和 ht[1],确保数据访问无中断。
5、迁移完成后,ht[1] 成为新的主哈希表,ht[0] 被清空并释放。
1.3、示例场景
假设 Redis 存储了一个包含 100 万键的哈希表:
1、一次性 ReHash:
需要一次性将 100 万键重新计算哈希并迁移,可能导致数百毫秒甚至秒级的阻塞。
2、渐进式 ReHash:
每次操作迁移 1-10 个键,100 万键分摊到多次操作中,可能只需几秒到几十秒完成,单次操作延迟仅增加微秒级。
1.4、注意事项
1、ReHash 性能影响:
虽然渐进式 ReHash 极大降低了阻塞风险,但在极端高并发场景下,频繁触发 ReHash 可能仍会带来轻微性能波动。
2、监控 ReHash:
通过 INFO MEMORY 命令查看 rehashidx 值,判断是否正在进行 ReHash(非 -1 表示进行中)。
3、优化策略:
合理设置初始哈希表大小或负载因子阈值(通过 hash-max-ziplist-entries 或 activerehashing 配置),减少不必要的 ReHash。
2、缓存时间戳
2.1、使用原因
redis 为什么要缓存系统时间戳?
平时使用系统时间戳时,都是直接调用系统函数(涉及到用户态和内核态线程的上下文切换) 直接获取时间戳。redis 不是这样的。因为 每一次获取系统时间戳都 一次系统调用。相对耗时。作为 高性能的 redis是承受不起的。
redis采用定时任务来获取系统时间 每毫秒更新一次,需要获取时间戳直接从缓存中拿。
2.2、Redis缓存过期机制
1、惰性删除:
惰性删除是指 Redis 只有在访问一个键(比如 GET、SET 等操作)时,才会检查该键是否已过期。如果键已过期,Redis 会立即删除该键,并返回空(对客户端来说就像键不存在)
优点:
节省 CPU 资源,只有在必要时才执行删除操作。
适合访问频率较高的场景,过期键能被及时清理。
缺点:
如果某些键长期不被访问,过期键可能占用内存,直到被定期删除或其他机制清理。
2、定期删除:
Redis 会定期(后台)扫描数据库中的键,随机抽样检查部分键的过期状态,并删除已过期的键。
优点:
能清理不常访问的过期键,防止内存浪费。
扫描是分批进行的,不会一次性占用过多 CPU。
缺点:
随机抽样可能漏掉一些过期键,导致内存清理不彻底。
高负载下,定期删除可能不够及时。
扩展点
redis 6.0 之前为什么一直不使用多线程?
- 在使用redis 过程中 cpu 一直不是瓶颈。受制于 内存 和 网络
- 提高Redis, Pipeline(命令批量处理) 每秒 100万请求
- 单线程内部维护简便 高效
参考文章:
1、redis高阶2 高性能-CSDN博客https://blog.csdn.net/nicepainkiller/article/details/147308857?ops_request_misc=&request_id=&biz_id=102&utm_term=Redis%E7%9A%84%E6%B8%90%E8%BF%9B%E5%BC%8Fhash%E5%92%8C%E7%BC%93%E5%AD%98%E6%97%B6%E9%97%B4%E6%88%B3&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-147308857.142^v102^pc_search_result_base1&spm=1018.2226.3001.4187