zoukankan      html  css  js  c++  java
  • redis笔记

    1.Zset

    redis的中的Zset底层是一个跳表,Skip list是一个“概率型”的数据结构,可以在很多应用场景中替代平衡树。Skip list算法与平衡树相比,有相似的渐进期望时间边界,但是它更简单,更快,使用更少的空间。

    Skip list是一个分层结构多级链表,最下层是原始的链表,每个层级都是下一个层级的“高速跑道”。
    假设:zset中存X个节点
    跳表的高度: h = logX;
    跳表的每一层中放着数据索引:
    第一级索引个数为:X/2;
    第二级索引个数为:X/4;
    ···
    第h级索引个数为:X/2^h;
    某个i层的元素,出现在i+1层的概率p是固定的,例如常取p=1/2或p=1/4;
    平均来讲,每个元素出现在1/(1-p)个链表中;
    最高的元素,例如head通常采用Int.MIN_VALUE作为的最小值,会出现在每一层链表中;
    跳表特性
    查询 和 增加 删除的算法难度都是logN。其实是二分法的一种实现。跳表在插入和删除的时候,要注意。
      插入时:跳表通过“随机函数”来维护前面的“高效性”,具体的操作是:往跳表中插入数据a时,通过随机函数生成一个随机数h,a插入单链表的同时,在第1级到第h级中也同时插入索引a。随机函数不是乱选的,要能保证索引的大小及跳表的平衡性,防止它退化成单链表的窘境。跳表的实现有点复杂,所以在此不再赘述。
      删除时:删除时,不仅仅要删除单链表,而且还要删除索引。
     

    2.Pipeline(管道)

      Redis 的 pipeline(管道)功能在命令行中没有,但 redis 是支持 pipeline 的,而且在各个语言版的 client 中都有相应的实现。 由于网络开销延迟,就算 redis server 端有很强的处理能力,也会由于收到的 client 消息少,而造成吞吐量小。当 client 使用 pipelining 发送命令时,redis server 必须将部分请求放到队列中(使用内存),执行完毕后一次性发送结果;如果发送的命令很多的话,建议对返回的结果加标签,当然这也会增加使用的内存;

      Pipeline 在某些场景下非常有用,比如有多个 command 需要被“及时的”提交,而且他们对相应结果没有互相依赖,对结果响应也无需立即获得,那么 pipeline 就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是 TCP 连接中减少了“交互往返”的时间。

      不过在编码时请注意,pipeline 期间将“独占”链接,此期间将不能进行非“管道”类型的其他操作,直到 pipeline 关闭;如果你的 pipeline 的指令集很庞大,为了不干扰链接中的其他操作,你可以为 pipeline 操作新建 Client 链接,让 pipeline 和其他正常操作分离在2个 client 中。不过 pipeline 事实上所能容忍的操作个数,和 socket-output 缓冲区大小/返回结果的数据尺寸都有很大的关系;同时也意味着每个 redis-server 同时所能支撑的 pipeline 链接的个数,也是有限的,这将受限于 server 的物理内存或网络接口的缓冲能力。
      其实作用不大,像这种提交可以转换成使用lua来写。

    3.redis 过期策略及内存淘汰机制

    redis过期策略分为:主动删除(也可以说:定时删除)惰性删除

      主动删除也是定时删除,既然是定时,说明redis会定时定期去删除。redis默认是每100s就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。

      惰性删除:既然是惰性肯定懒惰,redis会在每次获取这个key的时候,判断这个key是否过期,将key删除,返回null。
     
    从上面看:redis过期策略是 主动删除(也可以说:定时删除)+ 惰性删除。而不是单一的某一种,那么问题来了:
      假设默认100s内,有大量需要淘汰的key,而且还有大量的数据需要进来,内存不够了,这个时候怎么办?
    那就是:内存淘汰机制。

     redis 内存淘汰机制有以下几个:

    • noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了。
    allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
    • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。
    • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)。
    • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
    • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。

    产考链接:

    https://www.jianshu.com/p/60d2561b821c

    https://blog.csdn.net/u011489043/article/details/78769428

  • 相关阅读:
    强引用、软引用、弱引用、幻象引用有什么区别?
    vue基础指令学习
    如何设计一个自动化测试框架
    测试工程师需要了解的shell变量知识
    记一次kubernetes集群异常: kubelet连接apiserver超时
    golang http/transport 代码分析
    logging in kubernetes
    tune kubernetes eviction parameter
    kubernetes continually evict pod when node's inode exhausted
    Compile git version inside go binary
  • 原文地址:https://www.cnblogs.com/Zero-Jo/p/12960292.html
Copyright © 2011-2022 走看看