1、Rax是Redis内部比较特殊的一种数据结构,它是有序字典树,按照key进行排序,支持快速定位、插入、删除操作。它与zset排序不同,zset是按照score排序,而Rax是按照key进行排序。
- 集中数据结构的特点如下图所示
- 咱们可以将英语字典开成一棵radix tree,key是每个单词,value是对应的解释;也可以应用到时间序列,key为时间窜,value为发生在具体时间的事件,时间窜就是按照年月日时分秒纳秒微妙进行排列
- Rax被用在Redis 的Stream结构里,用于存储消息列表,Stream里面消息ID的前缀是时间窜加序号,我们可以根据时间窜定位到具体的消息,然后继续遍历指定消息之后的所有的消息
- Rax被用在Redis Cluster中用于记录槽位和key的对应关系,对应关系的变量名叫slots_to_keys,这个raxNode的key是由槽位编号hashslot和key组合而成。由于rax的key是按照key前缀顺序挂接的,所有相同的hashslot的对象key将被挂到同一个raxNode下面,这样我们就能遍历某个槽下面的所有对象key
2、结构
1)raxNode结构体
struct raxNode { int<1> isKey; // 是否有 key,没有 key 的是根节点 int<1> isNull; // 是否有对应的 value,无意义的中间节点 int<1> isCompressed; // 是否压缩存储,这个压缩的概念比较特别 int<29> size; // 子节点的数量或者是压缩字符串的长度 (isCompressed) byte[] data; // 路由键、子节点指针、value 都在这里 } |
解释:rax是一颗特殊的radix tree,它还不是标准的radix tree。若一个中间节点存在多个字节点,那么路由键就是一个字符,若只有一个字节点,那么路由键就是一个字符串
2)压缩结构字节点如果只有一个,那就是压缩结构,data字段如下伪代码
struct data { optional struct { // 取决于 header 的 size 字段是否为零 byte[] childKey; // 路由键 raxNode* childNode; // 子节点指针 } child; optional string value; // 取决于 header 的 isNull 字段 } |
解释:如果是叶节点,child字段就不存在。如果是无意义的中间节点(isNull),那么value字段不存在
3)非压缩节点
如果字节点有多个,那就不是压缩结构,存在多个路由键,一个键就是一个字符
struct data { byte[] childKeys; // 路由键字符列表 raxNode*[] childNodes; // 多个子节点指针 optional string value; // 取决于 header 的 isNull 字段 } |