Redis相关文章
zset | socreset
Redis中的Set结构与Java中的HashSet如出一辙,可一看做一个value为null的HashTable,本质上也是通过Hash表实现去重。
ZSet或者叫SocreSet,是基于set数据结构基础之上增加score属性并按score排序的数据结构。因为可排序且元素不重复的特性通常用作排行榜等功能。
本质上是依赖两个核心数据结构,ziplist压缩链表与skiplist跳跃链表实现。
ziplist
- ziplist本质上是字节数组,每个元素可以是一个字节数组或一个整数。占用一块完整的内存,空间连续,避免内存碎片,节省内存
- 对值存储采用变长形式,根据大小调整存储字节大小
- 基础结构:
- zlbytes:记录整个ziplist的大小。
- zltail:ziplist开始指针与最后一个entry之间的偏移量,通过该偏移量可以获得最后一个entry。
- zllen:entry数量。
- entry:存储具体数据的节点。
- prelen:上一个entry的大小。
- encoding:记录content的类型以及长度。
- content:一个整形或者字节数组。
- zlend:ziplist结尾标识。
- 总结
- 本质为占用一段完整内存字节数组,空间连续避免内存碎片
- 每个节点通过保存特殊节点位置实现双向链表特性
- 新增元素可能会引起连锁更新(类似数组,引发后续下标变动)
skiplist
- 本质上由Node节点构造成的多层链表结构,每层都是有序链表,最底层包含所有元素,上下层元素比例约为1:2
- 通过空间换时间的思想,在原有的有序链表中增加多级索引,每个元素包含多指针,指针个数通过"丢硬币"的方式实现基本满足二分概率1/2,每丢一次指针个数+1,指向下一层的元素,直到扔到反面为止
- 新增删除操作需要把后面的节点都更新一遍
- redis为什么使用跳表而不是用红黑树
- 内存占用更少,自定义参数化决定使用多少内存
- 查询性能至少不比红黑树差
- 简单更容易实现和维护
总结
- 基于ziplist或skiplist
- 符合以下条件使用ziplist
- 服务器属性server.zset_max_ziplist_entries 的值大于 0
- 元素的member长度(成员长度)小于服务器属性server.zset_max_ziplist_value的值(默认64)
- 不符合使用skiplist