redis的设计与实现:
1.假如有一个用户关系模块,要实现一个共同关注功能,计算出两个用户关注了哪些相同的用户,本质上是计算两个用户关注集合的交集,如果使用关系数据库,需要
对两个数据表执行join操作,对合并的结果执行去重distinct操作,非常复杂
2.Redis直接内置了集合数据类型,支持对集合执行交集/并集/差集等集合计算操作,交集操作可以直接用于共同关注功能,使用之后速度更快代码量更少,可读性大大提高
3.越来越多的疑问:五种数据类型是由什么数据结构实现的?字符串数据类型既可以存储字符串,又可以存储整数浮点数,二进制位,在内部是怎么存储这些值的?
有些命令只能对特定数据类型执行,是如何进行类型检查的?怎样存储各种不同类型的键值对?过期键是怎样实现自动删除的?发布与订阅/脚本/事务等特性是如何实现的?使用什么模型处理客户端的命令请求?一条命令从发送到返回需要经历的步骤?
4.第一版发布的时候还不是很完善,作者一边注释源码一边写,只介绍了内部机制和单机特性,新版添加了关于二进制位操作/排序/复制/Sentinel和集群等主题的新章节
5.数据结构与对象,单机数据库的实现,多机数据库的实现,独立功能的实现
6.数据库里面的每个键值对都是由对象组成的:数据库键总是字符串对象;键的值可以是字符串对象/列表对象(list object)/哈希对象(hash object)/集合对象(set object)/有序集合对象(sorted set object),这五种中的其中一种
7.第一部分和第二部分单机功能比较重要:第一部分,简单动态字符串,链表,字典,跳跃表,整数集合,压缩列表,对象
8.Redis自己构建了一个SDS的类型用来保存所有的字符串对象,包括键值对的键,值中存储字符串对象的底层也是SDS

redis的设计与实现-链表
1.链表提供了高效的节点重排能力,顺序性的节点访问方式,通过增删节点调整链表的长度,C语言不内置,Redis构建了自己的链表实现
2.列表键的底层实现之一就是链表,当元素比较多,元素都是比较长的字符串,就会使用链表作为底层实现
3.发布与订阅,慢查询,监视器等功能也用到了链表,redis本身使用链表保存多个客户端的状态信息
4.每个链表节点使用adlist.h/listNode结构表示,通过prev和next指针组成双端链表;使用adlist.h/list结构操作更方便,提供了表头指针head,表尾指针tail,长度计数len,特定类型的函数等
5.链表表头前置和表尾后置都是指向null,所以是无环链表,设置不同类型特定函数,可以用于保存不同类型的值
字典
1.字典,又称为符号表/关联数组/映射,保存键值对的抽象数据结构;一个键和一个值进行关联,或者叫键映射为值
2.redis的数据库就是使用字典作为底层,对数据库的增删查改操作也是构建在对字典的操作之上;字典还是哈希键的底层实现
3.redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,每个哈希表节点保存了字典中的一个键值对
4.redis字典所使用的哈希表由dict.h/dictht结构,table属性是一个数组,每个元素都是指向dict.h/dictEntry结构的指针.每个dictEntry结构保存一个键值对
5.哈希表节点使用dictEntry结构表示,key属性保存着键值对中的键,v属性保存着键值对中的值,键值对的值可以是指针或整数,next属性是指向另一个哈希表节点的指针,以此解决键冲突,通过next指针将两个索引值相同的键k1和k0连接在一起
6.Redis字典由dict.h/dict结构表示,type属性和privdata属性是针对不同类型的键值对,为创建多态字典设置;ht属性是一个包含两个项的数组,每一项都是dictht哈希表,一般只使用ht[0],ht[1]只会在哈希表进行rehash的时候使用,rehashidx记录rehash的进度
7.哈希算法-将一个新的键值对添加到字典里面时,先根据键计算出哈希值和索引值,根据索引值将一个新键值对的哈希表节点放到哈希表数组的指定索引上
hash=dict->type->hashFunction(key);index=hash&dict->ht[x].sizemask
Redis使用了MurmurHash2算法来计算键的哈希值
8.解决键冲突,使用了链地址法,被分配到同一个索引的多个节点可以用单向链表连接起来
9.哈希表保存的键值对逐渐增多或者减少,为了让哈希表的负载因子维持在一个合理的范围内,程序对大小进行扩展或者收缩

redis的设计与实现-跳跃表
1.跳跃表(skiplist)是一种有序数据结构,通过在每个节点中维持多个指向其他节点的指针,达到快速访问其他节点的目的,跳跃表支持平均O(logN),最坏O(N)复杂度的节点查找,还可以通过顺序性操作批量处理节点

1.跳跃表(skiplist)大部分情况下效率可以和平衡树媲美,并且比平衡树要简单
2.Redis使用跳跃表作为有序集合键的底层实现之一,在内部的集群节点中也有使用
3.比如zrange fruit 0 2 withscores 水果名是成员,水果价钱是分数值,每个水果存储在跳跃表节点中,价钱由低到高排序
4.redis跳跃表由redis.h/zskiplist和redis.h/zskiplistNode两个结构定义,zskiplist包含,header指向表头节点,tail指向表尾节点,length跳跃表的长度,level节点中最高层数
zskiplistNode结构包含,level表示层每层都有前进指针和跨度指向下一个节点,backward表示后退指针,score表示分值,obj表示成员对象;遍历时这些前进指针和后退指针就能启动快速访问的目的
5.迭代程序遍历跳跃表的时候只与前进指针有关,每个层的跨度与节点在跳跃表中的排位有关,每个节点的层高在1-32之间的随机数

[Redis]Redis的设计与实现-链表/字典/跳跃表的更多相关文章

  1. redis底层数据结构--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表

    1.动态字符串 redis中使用c语言的字符床存储字面量,默认字符串存储采用自己构建的简单动态字符串SDS(symple dynamic string) redis包含字符串的键值对都是用SDS实现的 ...

  2. 【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等

    redis有五种数据类型string.list.hash.set.zset(字符串.哈希.列表.集合.有序集合)并且自实现了简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等数据结构.red ...

  3. Redis底层探秘(二):链表和跳跃表

    链表简介 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地跳转链表的长度. 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用C语言并没有内 ...

  4. Redis实现之字典跳跃表

    跳跃表 跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.跳跃表支持平均O(logN).最坏O(N)的时间复杂度查找,还可以通过顺序性操作来批量处理节 ...

  5. 小白也能看懂的Redis教学基础篇——朋友面试被Skiplist跳跃表拦住了

    各位看官大大们,双节快乐 !!! 这是本系列博客的第二篇,主要讲的是Redis基础数据结构中ZSet(有序集合)底层实现之一的Skiplist跳跃表. 不知道那些是Redis基础数据结构的看官们,可以 ...

  6. [REDIS 读书笔记]第一部分 数据结构与对象 跳跃表

    下面是跳跃表的基本原理,REDIS的实现大致相同 跳跃表的一个特点是,插入NODE是通过随机的方式来决定level的,比较奇特 下面是skipList的一个介绍,转载来的,源地址:http://ken ...

  7. redis跳跃表

    最近在阅读redis设计与实现,关于redis数据结构zset的一种底层实现跳跃表一直没有太理解,所以在搜了一下资料,终于搞懂了它的设计思路,记录一下. 参考链接:https://mp.weixin. ...

  8. Redis 的底层数据结构(跳跃表)

    字典相对于数组,链表来说,是一种较高层次的数据结构,像我们的汉语字典一样,可以通过拼音或偏旁唯一确定一个汉字,在程序里我们管每一个映射关系叫做一个键值对,很多个键值对放在一起就构成了我们的字典结构. ...

  9. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

随机推荐

  1. pycharm 中 django 导入静态文件不提示补全

    File—>setting----->Languages & Frameworks ------> Python Template  Languages ------> ...

  2. Excel大批量数据导出

    package com.tebon.ams.util; import lombok.extern.slf4j.Slf4j;import org.apache.poi.openxml4j.excepti ...

  3. OpenCV读写摄像头并写入视频

    #include <opencv2/opencv.hpp>using namespace cv;#include <iostream>using namespace std; ...

  4. Hadoop源码分析(1):HDFS读写过程解析

    一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public F ...

  5. [Swift]LeetCode10. 正则表达式匹配 | Regular Expression Matching

    Given an input string (s) and a pattern (p), implement regular expression matching with support for  ...

  6. [Swift]LeetCode886. 可能的二分法 | Possible Bipartition

    Given a set of N people (numbered 1, 2, ..., N), we would like to split everyone into two groups of  ...

  7. Android device debug (adb) by Charge Only mode

    Android device debug by Charge Only mode Method 1 Connect devices to computer and execute lsusb Find ...

  8. win10安装ubuntu16.04及后续配置

    原文地址:https://www.jianshu.com/p/842e36a8255c UEFI 模式下win10安装ubuntu16.04双系统教程 - baobei0112的专栏 - CSDN博客 ...

  9. eclipse项目有红叉的解决办法

    eclipse项目上有红叉,说明这个项目存在一些的问题,对于这种情况需要具体来看. 1 新导入项目的红叉 如果是新导入的项目,一般红叉就只在项目名称上面有红叉,项目下的分项上面没有,这一般是由于当初项 ...

  10. HashMap? ConcurrentHashMap? 相信看完这篇没人能难住你!

    前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...