Redis

Redis架构

Redis命令

数据结构和对象

  • 动态字符串

    • 常数复杂度获取字符串长度
    • 杜绝缓冲区溢出
    • 减少修改字符串时带来的内存重新分配次数
    • 兼容部分C字符串函数
  • 链表

  • hash

    rehash是渐进式的

  • 跳跃表

    每个跳跃表节点的层高都是1至32之间的随机数;在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的;跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序

  • 整数集合

    每当我们要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级,然后才能将新元素添加到整数集合。不支持降级

    升级整数集合

    • 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间
    • 将底层数组现有的所有元素都转换成新元素相同的类型,维持底层数组的有序性质不变
    • 将新元素添加到底层数组
  • 压缩列表

    entry的组成:

    • previous_entry_length
    • encoding:记录当前节点的数据类型及长度
    • content: 实际数据body

    连锁更新问题

    压缩列表是一种为解决内存而开发的顺序型数据结构

  • 对象

    redis对象实现了基于引用技术的内存回收机制;实现了基于引用技术的对象共享机制

    为了确保只有指定类型的键可以执行某种特定操作,在执行一个类型特定的命令之前,会先检查输入键的类型和对应命令

    • 字符串对象

      mbstr 编码是专门用于保存短字符串的一种优化编码方式, 这种编码和 raw 编码一样, 都使用 redisObject 结构和 sdshdr 结构来表示字符串对象, 但 raw 编码会调用两次内存分配函数来分别创建 redisObject 结构和 sdshdr 结构, 而 embstr 编码则通过调用一次内存分配函数来分配一块连续的空间, 空间中依次包含 redisObject 和 sdshdr 两个结构

    • 列表对象

    • 哈希对象

    • 集合对象

    • 有序集合对象

      有序集合同时使用跳跃表和字典来实现。(范围查找和等值查找)

    • redis对象淘汰: https://zhuanlan.zhihu.com/p/105587132

  • quicklist实现: https://juejin.cn/post/6844904023418486791

  • redis数据结构: https://i6448038.github.io/2019/12/01/redis-data-struct/

事件循环

Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:

文件事件: Redis服务器通过套接字和客户端进行连接,而文件事件就是服务器对套接字操作的抽象

时间事件: 一些操作需要在给定时间点执行

redis服务器将所有时间事件都放在一个无序链表中,每当有时间事件执行器运行时,它遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器。(正常情况下只有serverCron一个时间事件,benchmark也只是两个时间事件)

事件调度规则:

  • 最早时间事件
  • 文件事件循环,逼近时间事件when
  • 事件处理有需要时主动让出执行权。例如写入字节数超过了一个预设值命令回复器会主动break,将余下的数据留到下次再写

Redis高可用

Redis应用

未分类

  • Redis生产架构选型解决方案: https://mp.weixin.qq.com/s/aKmagp5dyFOKgEjcZ_iwaw

  • redis为何那么快: https://mp.weixin.qq.com/s/ZcHLSDVxdG6qXxLl5-p8qQ

  • redis优化

    • 缩短键值对的存储长度;
      • 内容越大需要的持久化时间就越长,需要挂起的时间就越长
      • 内容越大在网络传输的内容越多,需要的时间就越多
      • 内容越大占用的内存阅读,就会更频繁地触发内存淘汰机制
    • 使用 lazy free(延迟删除)特性;
    • 设置键值的过期时间;
    • 禁用长耗时的查询命令;
    • 使用slowlog优化耗时命令;
    • 使用pipeline批量操作数据;
    • 避免大量数据同时失效;
    • 客户端使用数据计算操作;
    • 限制redis内存大小;
    • 使用物理机而非虚拟机安装redis服务;
    • 选择更好的数据持久化策略;
    • 禁用THP特性;
    • 使用分布式架构来增加读写速度