Redis对象--ZSET类型

57 阅读2分钟

ZSET类型

说明:ZSET是带分数的有序集合

ZSET的常见操作

  • 写操作:

    • ZADD KEY SCORE1 MEMBER1[SCORE2 MEMEBER2.....]
    • ZREM KEY MEMBER1 [MEBER2 MEMBER2.....]
  • 读操作:

    • ZCARD KEY 【返回有序集合数量】
    • ZCOUNT KEY MIN MAX 【计算SCORE在MIN-MAX之间的集合】
    • ZSCORE KEY MEMBER1【返回MEMBER1的分数】
    • ZRANK KEY MEMBER1 【返回MEMEBER1的SCORE排名】
    • ZRANGE/ZRERANGE KEY START STOP [WITHSCORES]【返回指定的有序集合,可选带分数,和list的lrange用法类似】【ZRANGE从小到大 ZRERANGE从大到小】

ZSET的编码方式

  • 当元素个数不超过128个,小于64B时用ZIPLIST KEY和SCORE两个连在一起的ENTRY-DATA/LISTPACK
  • 当元素超过128时,用SIPLIST+HASHTABLE(字典)

SKIPLIST

跳表:多层链表,最底层链表步长为1,依次往上二级索引步长为2,三级索引步长为3,每层按照SCORE升序来排列,所以从最上层开始找,因为从小到大排列,所以如果目标比当前节点小,就继续在这一层查找,如果目标比当前节点大,就进入下一层,因为每个节点都由指向下一层的指针,所以下一层不用从头开始查找。

REDIS中SKIPLIST单个节点的level

REDIS用概率均衡策略,每个节点是否增加一层的概率是25%,REDIS5中是64层,REDIS7中是32层,调表的时间复杂度是O(LOG2N)

SKIPLIST时间复杂度

插入不会影响层高,层高在创建就确定了,查找节点总数时间是O(1),查找某个值的分数时间是O(LOG2N)

HASHTABLE(字典)下查总数时间复杂度

O(1)

HASHTABLE结构

和Java中的一样,数组+链表,通过HASH值和数组长度得到数组下标

HASHTABLE扩容和缩容

  • 负载因子=节点数量/数组长度,当负载因子<0.1就缩容

  • 负载因子>5强制扩容,负载因子>=1时看是否在执行BGSAVE和BGREWRITEAOF

  • HASHTABLE执行rehash期间,会新分配1号表,每次执行增删改查,就会将当前指针元素复制到1号表,直到全部复制结束,1号表变成0号表,0变成1,大小是2的幂次

  • 缩容和扩容机制一样,不过大小是按使用节点的最近2的幂次来决定的,比如used=6 那就是8,最小是4