前言

一、简单动态字符串

1.字符串长度处理

字符串在 C 语言中的存储方式,想要获取 字符串的长度,需要从头开始遍历,直到遇到 ‘\0’ 为止
redis中用一个 len 字段记录当前字符串的长度。想要获取长度只需要获取 len 字段即可。你看,差距不言自明。前者遍历的时间复杂度为 O(n),Redis 中 O(1) 就能拿到,速度明显提升。
如图所示

2.内存重新分配

空间预分配
对 SDS 修改及空间扩充时,除了分配所必须的空间外,还会额外分配未使用的空间。
具体分配规则是这样的:SDS 修改后,len 长度小于 1M,那么将会额外分配与 len 相同长度的未使用空间。如果修改后长度大于 1M,那么将分配1M的使用空间。

惰性空间释放
当然,有空间分配对应的就有空间释放。
SDS 缩短时,并不会回收多余的内存空间,而是使用 free 字段将多出来的空间记录下来。如果后续有变更操作,直接使用 free 中记录的空间,减少了内存的分配。

3.二进制安全

你已经知道了 Redis 可以存储各种数据类型,那么二进制数据肯定也不例外。但二进制数据并不是规则的字符串格式,可能会包含一些特殊的字符,比如 ‘\0’ 等。C 中字符串遇到 ‘\0’ 会结束,那 ‘\0’ 之后的数据就读取不上了。但在 SDS 中,是根据 len 长度来判断字符串结束的。这样,二进制安全的问题就解决了。

二、双端链表

列表 List 更多是被当作队列或栈来使用的。队列和栈的特性一个先进先出,一个先进后出。双端链表很好的支持了这些特性。

1.前后节点

链表里每个节点都带有两个指针,prev 指向前节点,next 指向后节点。这样在时间复杂度为 O(1) 内就能获取到前后节点。

2.头尾节点

头节点里有 head 和 tail 两个参数,分别指向头节点和尾节点。这样的设计能够对双端节点的处理时间复杂度降至 O(1) ,对于队列和栈来说再适合不过。同时链表迭代时从两端都可以进行。

3.链表长度

头节点里同时还有一个参数 len,和上边提到的 SDS 里类似,这里是用来记录链表长度的。因此获取链表长度时不用再遍历整个链表,直接拿到 len 值就可以了,这个时间复杂度是 O(1)。这些特性都降低了 List 使用时的时间开销。

三、压缩列表

双端链表我们已经熟悉了。不知道你有没有注意到一个问题:如果在一个链表节点中存储一个小数据,比如一个字节。那么对应的就要保存头节点,前后指针等额外的数据。这样就浪费了空间,同时由于反复申请与释放也容易导致内存碎片化。这样内存的使用效率就太低了。于是引入了压缩列表。

压缩列表是经过特殊编码,专门为了提升内存使用效率设计的。所有的操作都是通过指针与解码出来的偏移量进行的。并且压缩列表的内存是连续分配的,遍历的速度很快。

四、字典

Redis 作为 K-V 型数据库,所有的键值都是用字典来存储的。
日常学习中使用的字典你应该不会陌生,想查找某个词通过某个字就可以直接定位到,速度非常快。这里所说的字典原理上是一样的,通过某个 key 可以直接获取到对应的value。
字典又称为哈希表,这点没什么可说的。哈希表的特性大家都很清楚,能够在 O(1) 时间复杂度内取出和插入关联的值。
redis中的字典使用哈希表做底层实现,每个字典带有两个哈希表,一个平时使用,一个rehash时使用。
哈希表利用链地址法解决冲突,被分配到同一个索引上的多个键值对会连接成一个单向链表。
哈希表进行扩展和收缩的时候,程序将哈希表所有键值对rehash到新的哈希表里面,并且这个rehash过程并不是一次性完成的,而是渐进式完成的。

五、跳跃表

作为 Redis 中特有的数据结构-跳跃表,其在链表的基础上增加了多级索引来提升查找效率。每一层都有一条有序的链表,最底层的链表包含了所有的元素。这样跳跃表就可以支持在 O(logN) 的时间复杂度里查找到对应的节点。最坏才是o(n)。
具体就是:


注意事项
(1)每个跳跃表的层高是1到32之间的随机数。
(2)同一个跳跃表中,多个节点可以含有相同的分值,但是节点的成员对象必须是唯一的。
(3)跳跃表的节点按照分值大小排序完成的,如果分值大小相同,按照成员对象大小排序。

Redis高效的数据结构及特殊性相关推荐

  1. Redis中五大数据结构的底层实现

    来自:DBAplus社群 作者介绍 田兆壮,新炬网络开发工程师.具备扎实的Java.Scala开发经验,熟练使用Python和Shell等脚本语言:具备前后端开发能力,熟练使用关系型数据库和非关系型数 ...

  2. Redis专题-底层数据结构与使用场景

    Redis介绍 Redis是一种基于键值对的NoSQL数据库,是一个基于内存中的数据结构存储系统,可以用作数据库.缓存和消息中间件.它支持以string(字符串),hash(哈希),list(列表), ...

  3. Redis高效性探索--线程IO模型,通信协议

    Redis线程IO模型 Redis是单线程,这个毋庸置疑 Redis单线程能做到这么高的效率?不用怀疑,还有很多其他的服务都是单线程但是也有超高的效率,比如Node.js,Nginx也是单线程. Re ...

  4. redis源码分析 ppt_【Redis】redis各类型数据结构和底层实现源码分析

    一.简介和应用 Redis是一个由ANSI C语言编写,性能优秀.支持网络.可持久化的K-K内存数据库,并提供多种语言的API.它常用的类型主要是 String.List.Hash.Set.ZSet ...

  5. redis:redis的底层数据结构

    高效的数据结构 redis中的数据结构有2种意思: (redis本质上是一个hashmap) redis键值对中的值的数据类型,也就是数据的保存形式,常用的有5种:String(字符串).List(列 ...

  6. java必学之Redis中的数据结构

    目录 一.String不在适用Redis底层数据结构 1.String类型的内存消耗问题 2:String类型怎么保存数据 2.1RedisObject结构体: 2.2int.embstr和raw这三 ...

  7. redis创建像mysql表结构_如何给redis添加新数据结构

    前言 作为一款缓存型nosql数据库,redis在诞生之初就以高性能.丰富的数据结构等特性获得业界的青睐.redis默认提供了五种数据类型的支持:string.list.set.zset.hash.针 ...

  8. Redis 之(二) Redis的基本数据结构以及一些常用的操作

    本篇内容是Redis最简单最容易掌握的知识,如果你已经熟知了,就可以选择跳过啦! 要体验Redis,那么首先你得安装Redis,这边的话我就只讲一下Windows环境下的安装与操作: Window 下 ...

  9. Android开发中高效的数据结构用SparseArray代替HashMap

    Android开发中高效的数据结构用SparseArray代替HashMap 转载于:https://www.cnblogs.com/zhujiabin/p/5775435.html

最新文章

  1. 2019秦皇岛ccpc A题:Angle Beats[计算几何:统计符合直角三角形的个数]+[向量hash+3hash]
  2. 拿到input输入的时间_【Keras 笔记】Input/Dense层的数学本质
  3. java合集框架第一天
  4. One-Error多标签分类_深度学习:如何在多标签分类问题中考虑标签间的相关性?
  5. mysql 取模分区_MySQL分区
  6. android 获取全局context,说说 Android 中如何在全局获取 Context
  7. 三句话捋清楚java垃圾收集器
  8. java操作properties文件简单学习
  9. python正则表达式思考_Python正则表达式由浅入深(一)
  10. 需求规格说明书5.0版本
  11. 中间人攻击的实践与原理(ARP毒化、DNS欺骗)
  12. Java 基础入门训练
  13. 申论高分作者心得分享——站在政府的角度写申论
  14. winHex数据恢复(第一篇)
  15. 【转载】参数返回值及NRV优化
  16. 钉钉考勤报表--工时统计小程序
  17. 判断浏览器必须是IE10以上,低于IE10做出提示
  18. 文件操作fwrite写txt文件乱码怎么办,我这里有方法解决
  19. sql server无法用sql server身份验证
  20. 天道酬勤~我如此惬意

热门文章

  1. 离群点、异常点检测及Python实现(正态分布3∂,Z-score 异常值检测,基于MAD的Z-score 异常值检测,杠杆值点、DFFITS值、SR学生化残差、cook距离和covratio值)
  2. class 'memcache' not found php,PHP Fatal error: Class 'Memcache' not found in
  3. js 取得数组下标_剖析JS和Redis的数据结构设计:数组
  4. 无法删除所有指定的值_SQL-插入、更新、删除、创建
  5. Linux下更新libnss3的代码,yum安装firefox错误libnssutil3.s
  6. 微服务 数据库耦合_mysql – 与其他服务共享的微服务数据库
  7. 利用计算机语言进行并行性描述,有没有一种语言可以利用大规模并行计算机?...
  8. c语言程序与设计第三版-苏小红--第一轮学习笔记、难点整理
  9. 161011、oracle批量插入数据
  10. sql server实用工具sql prompt的安装与注册