Redis 跳表(skiplist)知识点详解

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis框架从入门到学精(全)Python操作Redis从入门到精通附代码(全)Redis的常见面试题(全)一文读懂基于Redis的Amazon MemoryDB数据库科普下Redis数据类型中底层的数据结构(常考点)数据类型可以存储的值操作应用场景string字符串、整数或者浮点对整个字符串或者字符串的其中一部分执行操作,对整数和浮点数执行自增或者自减操作做简单的键值对缓存,计数器,共享session以及限速list列表。

@TOC

前言

关于Redis的相关知识点可看我之前的文章:

  1. Redis框架从入门到学精(全)
  2. Python操作Redis从入门到精通附代码(全)
  3. Redis的常见面试题(全)
  4. 一文读懂基于Redis的Amazon MemoryDB数据库

科普下Redis数据类型中底层的数据结构(常考点)

数据类型 可以存储的值 操作 应用场景
string 字符串、整数或者浮点 对整个字符串或者字符串的其中一部分执行操作,对整数和浮点数执行自增或者自减操作 做简单的键值对缓存,计数器,共享session以及限速
list 列表 从两端压入或者弹出元素,对单个或者多个元素进行修剪,只保留一个范围内的元素 存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的
set 无序集合 添加、获取、移除单个元素,检查一个元素是否存在于集合中。计算交集、并集、差集。从集合里面随机获取元素 交集、并集、差集的操作,比如交集,可以把两个人的粉丝列表整一,或者是用户的喜好标签等
hash 包含键值对的无序散列 添加、获取、移除单个键值对。获取所有键值对。检查某个键是否存在 结构化的数据,比如一个对象
zset 有序集合 添加、获取、删除元素。根据分值范围或者成员来获取元素。计算一个键的排名。 去重但可以排序,如获取排名前几名的用户,排行榜等

1. zset底层结构

zset主要是有序集合

底层结构有压缩列表和跳表两种结构

数据结构 描述 优点 缺点 应用场景
压缩列表 在列表的前面加入了列表长度、尾部偏移量、列表元素个数,在列表的后面加入了列表结束标识 有利于快速的找到首尾节点 不利于找其他的元素,只能一个个遍历 1.有序集合保存的元素数量小于128个
2.有序集合保存的所有元素长度小于64字节
跳表 在链表的基础上增加了多级索引,通过多级索引位置的转跳,实现快速查找元素 可快速查找对应元素,用空间换实践,实践复杂度笑了 元素数量比较多 或者 元素比较长的字符串

2. 跳表结构

之所以有跳表这个结构是为了解决平衡二叉树复杂问题

hash可快速定位,但是不是有序
若用二叉查找树,有序的话会退化为链表
链表加平衡因子,变成平衡二叉树(可分为b树、b+树、红黑树等)

跳表和平衡二叉树的区别如下:

共同点 差异
查找、插入、删除的时间复杂度都是o(logn) 跳表 查找区间元素比较快,但是 平衡二叉树 查找区间元素 一开始需要定位左端点,之后查找后续节点比较费时

最后选用了跳表,是因为跳表实现起来容易,所以用它来实现有序集合

基本的性质:

  1. 主要是单链表 + 索引的方式实现,以空间换时间的形式,提高查找速度
  2. 底层主要由两个结构组成

在这里插入图片描述

  • zskiplist:保存跳表信息(头尾节点、跳表层数最大的层数、长度)
  • zkiplistnode:保存跳表节点信息(比如level层:每层都有两个属性,指针和跨度,跨度大距离远)

类似如下结构,原本是1到6的链表结构,专门找5这个数字的话,需要遍历5个节点
如果每隔一个数字建立一个索引,具体如下:
在这里插入图片描述

通过一级索引来减少遍历节点的次数
如果觉得一级索引比较慢,可以在一级索引的基础上在建立索引

当数据量比较大的时候,跳表查询、插入、删除的复杂度均为为 O(logn),本身的主要思想是二分法

3. 拓展思考

为什么zset使用跳表而不用红黑树或者二叉树?

Redis直接操作内存而不是磁盘,所以不需读取IO,速度比较快

  • 跳表不是很占用内存(基本取决于节点数据),本身节点的数据参数会让内存密集度小于B+树
  • 跳表本身实现方式比其他结构都要简单(将相同级别的节点存储在同一个文件或者映射中,有利于解决缓存局部性问题)

而MYSQL使用B+树是为了减少IO以及支持范围查询

关于这个问题的讲解,结合MYSQL的底层结构讲解比较清晰。
(对应的数据库最终使用了b+树,可看我这篇文章的推理:Mysql底层原理详细剖析+常见面试题(全)

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
NoSQL 算法 分布式数据库
【Redis】求求你,别再问跳表了
【Redis】求求你,别再问跳表了
|
3月前
|
NoSQL 算法 Redis
redis7.0源码阅读(五):跳表(skiplist)
redis7.0源码阅读(五):跳表(skiplist)
59 1
|
3月前
|
存储 NoSQL Redis
Redis数据结构之——跳表skiplist
Redis数据结构之——跳表skiplist
|
5月前
|
存储 NoSQL Redis
Redis 跳表skiplist
Redis 跳表skiplist
|
5月前
|
存储 NoSQL 测试技术
关于redis涉及的知识点,C语言如何操作redis
关于redis涉及的知识点,C语言如何操作redis
|
5月前
|
存储 NoSQL 算法
redis6.0源码分析:跳表skiplist
redis6.0源码分析:跳表skiplist
31 0
|
7月前
|
存储 NoSQL 算法
Redis中ZSet的底层数据结构跳跃表skiplist,你真的了解吗?
Redis中ZSet的底层数据结构跳跃表skiplist,你真的了解吗?
|
8月前
|
存储 缓存 NoSQL
redis知识点
redis 知识点
59 0
|
8月前
|
缓存 监控 NoSQL
【Redis】Redis知识点阶段性总结 2
【Redis】Redis知识点阶段性总结
42 0
|
8月前
|
NoSQL Linux Redis
【Redis】Redis知识点阶段性总结 1
【Redis】Redis知识点阶段性总结
65 0