redis 怎么读 怎么写 存储的时候为什么会不同各种数据类型 读取数据怎么存 怎么读写
set 分布式锁 时间怎么确定
redis 大家都来争夺锁 给谁
--《redis设计与实现》
redis 动态字符串 SDS
用的不是C的字符串,而是自己重新构建了一个
set msg 'hello world'时,键值对的键是一个字符串对象,对象的底层实现是保存着“msg”的SDS,值也是保存着“hello world”的SDS。链表中的字符串,也都是由SDS实现的。
SDS与C的字符串比有以下优点:
常数复杂度获取字符串长度。
杜绝缓冲区溢出。
减少修改字符串长度时,所需的内存重分配次数。
二进制安全。
兼容部分C字符串函数。
链表
提供了高效的节点重排能力,以及顺序性的节点访问方式。并且可以通过增删节点,来灵活地调整链表的长度。
redis因为C没有链表这种数据结构,所以自己构建的。
列表键的底层实现之一就是链表。还有发布与订阅、慢查询、监控器也用到了链表。
链表组成:
ListNode :前置节点、后置节点、节点的值。listnode通过prev、next组成双端链表。
特点:双端、无环(头尾都指向null)、有表头表尾指针、有链表长度计数器、多态。
字典
是用于保存键值对(key-value pair)的抽象数据结构。
字典应用的相当广泛,redis的数据库底层就是字典,增删改查也是构建在对字典的操作之上。
set msg 'hello world' 就是保存在字典里。
除了用于表示数据库,字典还是哈希键的底层实现之一。当键值对较多或者都是元素较长的键值对时,redis就会使用字典作为哈希键的底层实现。
哈希表使用链地址法解决哈希冲突,被分配到同一索引上的多个键值对会连接成也给单向链表。
扩展或者收缩时,要先把所有键值对rehash到一个新哈希表里。这个不是一次性完成的。
跳跃表
有序数据结构,通过在每个节点中维持多个指向其他节点的指针,达到快速访问节点的目的。还可以通过顺序性操作来批量处理节点。
redis使用跳跃表作为有序集合键的底层实现之一。
redis只在两个地方用到了跳跃表,一个是实现有序集合键,另一个是在集群节点中用作内部数据结构。
redis的跳跃表实现由zskiplist和zskiplistNode来组成,zskiplist用于保存跳跃表信息,zskiplistNode则用于表示跳跃表节点。
跳跃表节点的层高是1至32之间的随机数。
在同一个跳跃表中,多个几点可以包含相同的分之,但每个几点的成员对象必须是唯一的。
整数集合
整数集合是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,redis就会使用整数集合作为集合键的底层实现。
SADD numbers 1 3 5 7 9 -----set
整数集合的底层实现为数组,这个数组以有序、不重复的方式保存集合元素,在有需要时,会根据新添加的元素类型,改变这个数组的类型。
整数集合只能升级不能降级。