Redis 能存多少个 Key
数据结构
Redis 的键值对存在哪里? 哈希表
dictEntry 存储的是实际键值对,定义如下
1 |
|
dictht是哈希表,它的定义如下
1 |
|
Redis 的 kv 里面不是直接存字符串 key 是 sds,value 是 redisObject
冲突处理
因为每个数组下标对应一个链表,如果一个新的 key 算出的数组下标已经包含了其他的 dictEntry,只需要把新的 key 对应的 dictEntry 挂在链表的第一个位置即可(因为是新插入的,可能马上会用到)
扩缩容
单纯依赖链表做冲突处理,链表会越来越长,读写效率差,所以需要对哈希表扩容
对于 Redis 来说,一个哈希结构内置了两个哈希表,一个用于使用,另一个平时闲置,待时机成熟,扩容一倍,将数据迁移到另一个哈希表中
1 |
|
其中 rehashidx 表示当前 dict 是否正在做 rehash,如果为 -1 表示没有 rehash,当 used > 2^n 时候,需要扩容(rehashidx 表示ht[0] 在 rehash 的时候所在的索引值)
为了保证 Redis 单线程的高效性,整个 rehash 是渐进式的,全部迁移完成之后 rehashidx 置为 -1 对于key的路由来说,它依然先从dict[0]去找,如果找到了,就顺便把它迁移到dict[1]。如果没找到就要从dict[1]去找
能存多少 key?
先说结论:最好千万级别
size 定义了数组的长度,由于它是 unsigned long
(4 个字节)所以理论上可以存 2 ^ 32 个元素
官方回答说最好放 2.5 亿个键值对
原因:
- rehash 问题,导致内存异常增长,由于要为
ht[1]
分配空间,大小取决于ht[0]
当前包含的数量 - 死键问题,Redis 将所有键值对保存在 dict 中,还有一个
dict *expires
用来保存过期键,如果键值数量过多,并设置了过期时间,会导致内存占用
1 |
|
- Redis有最大内存淘汰机制(maxmemory-policy),如果键值个数过多,那么可能逐出的就会更多,也就意味段时间内有大量的删除操作,甚至会造成Redis段时间不可用
Redis 能存多少个 Key
http://showyoubug.cn/2024/09/07/Redis 能存多少个 Key/