Redis学习笔记之底层数据结构

1.简单动态字符串(simple dynamic string, SDS)

  定义:

  struct sdshdr {

         int len;//记录buf中使用的字节数量

         int free;//记录buf中未使用的字节数量

         char buf[];//字节数组,用于保存字符串

         //buf字节数组以’\0’结束,但是’\0’不计算在len之中,对于用户来说是透明的

  }

  SDS与C中的字符串相比,优势在于:

   O(1)时间复杂度获取字符串长度;杜绝缓冲区溢出(每次修改buf时会检查空间是否充足);提高修改字符串的效率(空间预分配和惰性释放空间,客观的说会浪费一定的空间,空间换时间);二进制安全(支持字符串中有空字符串);

2.链表和链表节点

  定义:双向链表的节点

  typedef struct listNode {

           struct listNode *prev;//前置节点

           struct listNode *next;//后置节点

           void *value;//节点的值

  } listNode;

  用如下结构来管理链表:

  typedef struct list {

           listNode *head;//链表头

           listNode *tail;//链表尾

           unsigned long len;//链表节点数

           void *(*dup) (void *ptr);//节点值复制函数

           void (*free) (void *ptr);//节点值释放函数

           int (*match) (void *ptr, void *key);//节点值对比函数

  } list;

  优点:很多值或者节点都存储起来了,访问节点长度、尾节点等时间复杂度降低,多态(value的类型是void*)

3.字典——哈希键的底层实现之一

  哈希表结构:

  typedef struct dictht {

           dictEntry **table;//哈希表数组

           unsigned long size;//哈希表大小

           unsigned long sizemask;//哈希表大小掩码

           unsigned long used;//哈希表已有节点数量

  } dictht;

  哈希表节点结构:

  type struct dictEntry {

           void *key;//

           union {//

                  void *val;

                  unit64_tu64;

                  int64_ts64;

           } v;

           struct dictEntry *next;//指向下个哈希表节点,形成链表

  } dictEntry;

  字典结构:

  typedef struct dict {

                dictType *type;//字典类型,为创建多态字典

                void *privdata;//保存需要传给类型特性函数的参数

                dictht ht[2];//字典只使用ht[0],rehash时才使用ht[1]

                int rehashidx;//记录了rehash的进度,默认是-1

  } dict;

  Redis的哈希表使用链地址法,rehash时将ht[0]上的值rehash到ht[1]上(涉及ht[1]的空间分配大小问题),然后把ht[1]作为ht[0],把ht[1]设置为空白哈希表

  渐进式rehash:在每一次增删改操作的时候,将ht[0]上对应的键值对写到ht[1]上,在某个时间点时,ht[0]上的值全部写到ht[1]上

4.跳跃表

  实现:主要由两个结构组成,zskiplist用于保存跳跃表信息,zskiplistNode用于表示跳跃表节点;每一个zskiplistNode有若干(1~32随机)层(每一层都有前进指针和跨度),还有后退指针、分值、成员对象obj;成员对象唯一,分值可相同;节点按照分值的大小进行排序,分值相同时按照成员对象的大小排序。

  用处:有序集合、集群节点中用作内部数据结构

5.整数集合

  定义:

  typedef struct intset {

                uint32_t encoding;

                uint32_t length;

                int8_t contents[];

  } intset;

  重点:整数集合升级,contents中保存的数据可能是16位、32位、64位的,会根据存入数据的位数对集合进行升级;不支持降级

  用处:集合元素全是整数的情况

6.压缩列表——列表键和哈希键的底层实现之一

  结构:zlbytes zltail zllen entry1 entry2…entryN zlend

  zlbytes:uint32_t,记录整个压缩列表的字节数

  zltail:uint32_t,记录压缩列表尾节点距离列表首地址有多少个字节

  zllen:uint16_t,记录压缩列表包含的节点数量

  entryN:压缩列表包含的节点

       previous_entry_length   前一节点的大小

          encoding   记录了节点content所保存的数据的类型和值

        content   节点的值

  zlend:uint8_t,特殊值0XFF,用于标记压缩列表的末端

  连锁更新:节点中previous_entry_length的长度是根据值的大小确定的,所以当更新前一节点的长度时,这个值所占的字节数可能会引起改变,因此需要更新更新节点的后续节点。如果更新节点的后续节点全部都需要更新,那么效率会很低,但是需要全部节点更新的概率极低,因此不需要考虑对效率的影响。

时间: 2024-10-07 03:21:35

Redis学习笔记之底层数据结构的相关文章

Redis学习笔记

Redis学习笔记:Redis是什么?redis是开源BSD许可高级的key-vlue存储系统可以用来存储字符串哈希结构链表.结构.集合,因此常用来提供数据结构服务. redis和memcache相比的独特之处:1.redis可以用来做存储,而memcache是用来做缓存 这个特点主要因为其有"持久化"的功能.2.存储的数据有"结构",对于memcache来说,存储的数据只有1种类型"字符串"而 redis则可以存储字符串.链表.哈希机构.集合.

Redis学习笔记~目录

redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hashs(哈希类型).这些数据类型都 支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排 序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更

[redis读书笔记] 第一部分 数据结构与对象 对象以及总结

- 从前面redis的基本数据结构来看,可以看出,redis都是在基本结构(string)的基础上,封装了一层统计的结构(SDS),这样让对基本结构的访问能够更快更准确,提高可控制度. - redis的键值对中,键必然是用字符串对象实现的,所以我们一般说的列表键,指的是字符串键+列表值. - 但是redis并没用这些数据结构直接实现redis的键值数据库,而是基于这些数据结构有一个对象系统,这个系统包括:字符串对象,列表对象,哈希对象,集合对象和有序集合对象,每一种对象都可能用到一到多种基本的数

(转)redis 学习笔记(1)-编译、启动、停止

redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先到这里下载Stable稳定版,目前最新版本是2.8.17 1.2 上传到linux,然后运行以下命令解压 tar xzf redis-2.8.17.tar.gz 1.3 编译 cd redis-2.8.17make 注:make命令需要linux上安装gcc,若机器上未安装gcc,redhat环境下,如

Redis学习笔记4-Redis配置具体解释

在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redis学习笔记中Redis的依照方式依照后,Redis的配置文件是/etc/redis/6379.conf.以下是Redis2.8.9的配置文件各项的中文解释. #daemonize no 默认情况下, redis 不是在后台运行的.假设须要在后台运行,把该项的值更改为 yes daemonize ye

Redis学习笔记7--Redis管道(pipeline)

redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client.基本的通信过程如下: Client: INCR X Server: 1 Client: INCR X Server: 2 Client: INCR X Server: 3 Client: INCR X Server: 4

Lua学习笔记(八):数据结构

table是Lua中唯一的数据结构,其他语言所提供的数据结构,如:arrays.records.lists.queues.sets等,Lua都是通过table来实现,并且在Lua中table很好的实现了这些数据结构. 1.数组 在Lua中通过整数下标访问table中元素,既是数组,并且数组大小不固定,可动态增长.通常我们初始化数组时,就间接地定义了数组的大小,例如: 1 a = {} -- new array 2 for i=1, 1000 do 3 a[i] = 0 4 end 5 6 --数

Redis学习笔记(简单了解与运行)

Redis学习笔记(简单了解与运行) 开源的非关系型数据库 是REmote Dictionary Server(远程字典服务器)的缩写,以字典结构存储数据 允许其他应用通过TCP协议读写字典中的内容. Redis支持存储的键值数据类型 字符串类型 散列类型 列表类型 集合类型 有序集合类型 Redis的特性 通过一个列子看出Mysql和Redis的存储区别 例如: (存储一篇文章,文章包括:标题(title),正文(content),阅读量(views),标签(tags)) 需求: 把数据存储在

Redis学习笔记4-Redis配置详解

原文:  http://blog.csdn.net/mashangyou/article/details/24555191 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redis学习笔记中Redis的按照方式按照后,Redis的配置文件是/etc/redis/6379.conf.下面是Redis2.8.9的配置文件各项的中文解释. 1 #daemon