redis----zset
By skyshappiness Posted 2022-11-22 13:09:58 In

一、reset实现


     知识点:当score相同时,按照 value 的字典序排序



    1)ziplist

         健值对数量小于128个,并且每一个元素长度小于64位

         

    2)skiplist

         源码数据结构的定义:


         #define ZSKIPLIST_MAXLEVEL 32 

         #define ZSKIPLIST_P 0.25 

         typedef struct zskiplistNode

             robj *obj;   //节点数据

             double score;  //score对应的分数

             struct zskiplistNode *backward;  //后退指针

             struct zskiplistLevel

                struct zskiplistNode *forward;  //前向指针

                unsigned int span;  //表示当前指针跨越了多少个节点,用于计算排名

             }  level[]; 

         } zskiplistNode; 


         typedef struct zskiplist

             struct zskiplistNode *header, *tail;  //头指针、尾指针

             unsigned long length;   //链表的长度

             int level;  //skiplist总层数

        } zskiplist;


         


二、使用场景:

     1)延迟队列:

          将 score 设置为到期时间,然后通过额外的进程,去获取到期的 score 进行分布式的消费;常见的用法:超时订单的取消

          此处需要考虑的问题是:redis无ack机制,因此需要考虑消费失败的情况需要怎么去处理


     2)排行榜

           战力排行榜:

           zadd power_ranking  20 name1 30 name2 ......

           zadd power_ranking  40 name1 //更新战力

           zincrby power_ranking  -10 name1 //name1战力减少 10 

           zrange power_ranking 0 2 withscores //获取排名列表

          

     3)滑动窗口限流

          将用户ID作为key,时间戳作为 score 和 member; 然后通过 zcount key score_start score_end 获取数量;判断是否可以继续即可:

          伪代码:

          client_id := xxxxx;

          now_time_stamp := int(time.Now().Unix())

         request_time := redis.zcount(client_id, now_time_stamp - 1000, now_time_stamp)

        if  request_time > max_request_count {

             return "max_request"

        }

        redis.Zadd(client_id, now_time_stamp, now_time_stamp)

        

  参考地址:

      1、redis跳表扫盲:https://juejin.cn/post/6844904164120608781#comment

      2、底层结构之zset:http://t.zoukankan.com/reecelin-p-13368374.html







友情链接
联系方式
  • 邮箱 / E-mail:121388038@qq.com