diff --git a/notes/Redis.md b/notes/Redis.md index 84396d00..c26eaa72 100644 --- a/notes/Redis.md +++ b/notes/Redis.md @@ -9,6 +9,7 @@ * [HASH](#hash) * [ZSET](#zset) * [三、数据结构](#三数据结构) + * [对象编码](#对象编码) * [字典](#字典) * [跳跃表](#跳跃表) * [四、使用场景](#四使用场景) @@ -39,6 +40,7 @@ * [主从链](#主从链) * [十二、Sentinel](#十二sentinel) * [十三、分片](#十三分片) + * [Redis Cluster](#redis-cluster) * [十四、一个简单的论坛系统分析](#十四一个简单的论坛系统分析) * [文章信息](#文章信息) * [点赞功能](#点赞功能) @@ -209,6 +211,20 @@ OK ## 三、数据结构 +### 对象编码 + +同一种数据类型会根据元素的数量和大小选择不同的底层结构,称为编码,可以用 OBJECT ENCODING 查看。元素少时使用 listpack,它把所有元素连续地存放在一块内存中,节省内存,查找时虽然要逐个比较,但元素很少时并不慢;元素增多后转换为查找更快的结构。以下是在 Redis 7.4 上用默认配置验证的结果: + +| 类型 | 元素少时 | 超过阈值后 | 阈值 | +| --- | --- | --- | --- | +| STRING | int(整数)、embstr | raw | 44 字节 | +| LIST | listpack | quicklist(多个 listpack 组成的链表) | 单个 listpack 超过 8 KB | +| HASH | listpack | hashtable | 512 个字段,或者有值超过 64 字节 | +| SET | intset(全是整数)、listpack | hashtable | 整数 512 个,其它 128 个 | +| ZSET | listpack | skiplist(跳跃表 + 字典) | 128 个成员,或者有成员超过 64 字节 | + +例如一个 HASH 有 512 个字段时编码为 listpack,再写入一个字段就变为 hashtable。ZSET 转换后同时使用跳跃表和字典:字典按成员查分数,跳跃表按分数排序和范围查询。 + ### 字典 dictht 是一个散列表结构,使用拉链法解决哈希冲突。 @@ -570,6 +586,24 @@ Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入 - 代理分片:将客户端请求发送到代理上,由代理转发请求到正确的节点上。 - 服务器分片:Redis Cluster,使用 CRC16(key) % 16384 计算键所属的哈希槽,再把 16384 个哈希槽分配给各个节点。 +### Redis Cluster + +Redis 有三种常见的部署方式,解决的问题不同: + +- 主从复制:从服务器复制主服务器的数据,分担读请求,主服务器宕机后需要手动切换; +- Sentinel:在主从复制的基础上自动监控和故障转移,但仍然只有一个主服务器负责写入,数据量受单机内存限制; +- Redis Cluster:把数据分散到多个主节点上,每个主节点有自己的从节点,同时解决容量和高可用的问题。 + +Redis Cluster 把键空间分为 16384 个哈希槽,每个主节点负责一部分槽。下面是在本机创建的 3 主 3 从的集群: + +