redis内部存储结构

一.redis基础

--安装步骤省略...

--连接远程命令:

redis ./redis-cli -h 192.168.100.109  -p  6379

--启动命令:

redis-server /path/redis.conf(设置daemonize yes可以以守护进程的方式启动)

 --停止redis:

优雅停止:redis-cli SHUTDOWN

当redis收到SHUTDOWN命令后,会先断开所有客户端连接,然后根据配置执行持久化,最终完成退出.

强行停止:kill -9 ...

会造成未持久化的数据丢失.

二.内部存储结构:

1. string:

  它能存储任何形式的字符串,包括二进制数据。你可以用它存储用户的邮箱、json化的对象甚至是图片。一个字符类型键允许存储的最大容量是512M。

  String类型通过 int、SDS(simple dynamic string)作为结构存储,int用来存放整型数据,sds存放字节/字符串和浮点型数据。

  redis3.2分支引入了五种sdshdr类型,每次在创建一个sds时根据sds的实际长度判断应该选择什么类型的sdshdr,不同类型的sdshdr占用的内存空间不同。

redis内部存储结构

len;//表示当前sds的长度(单位是字节);

alloc; //表示已为sds分配的内存大小(单位是字节);

flags; //用一个字节表示当前sdshdr的类型;

buf[];//sds实际存放的位置

2. list:

  列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段,内部使用双向链表实现。

redis内部存储结构

  redis3.2之前,List类型的value对象内部以linkedlist或者ziplist来实现, 当list的元素个数和单个元素的长度比较小的时候,Redis会采用ziplist(压缩列表)来实现来减少内存占用。否则就会采用linkedlist(双向链表)结构。

  redis3.2之后,列表的底层都由一种叫quicklist的数据结构来存储list。双向链表在链表两端进行push和pop操作,在插入节点上复杂度比较低,但是内存开销比较大;ziplist存储在一段连续的内存上,所以存储效率很高,但是插入和删除都需要频繁申请和释放内存;quicklist仍然是一个双向链表,只是列表的每个节点都是一个ziplist,其实就是linkedlist和ziplist的结合,quicklist中每个节点ziplist都能够存储多个数据元素。

 redis内部存储结构

3. hash类型:

map提供两种结构来存储,一种是hashtable、另一种是前面讲的ziplist,数据量小的时候用ziplist. 在redis中,哈希表分为三层,分别是:

--dictEntry:

  管理一个key-value,同时保留同一个桶中相邻元素的指针,用来维护哈希桶的内部链。

redis内部存储结构

--dictht:

  实现一个hash表会使用一个buckets存放dictEntry的地址,一般情况下通过hash(key)%len得到的值就是buckets的索引,这个值决定了我们要将此dictEntry节点放入buckets的哪个索引里,这个buckets实际上就是我们说的hash表。dict.h的dictht结构中table存放的就是buckets的地址。

redis内部存储结构

--dict:

  dictht实际上就是hash表的核心,但是只有一个dictht还不够,比如rehash、遍历hash等操作,所以redis定义了一个叫dict的结构以支持字典的各种操作,当dictht需要扩容/缩容时,用来管理dictht的迁移。

 

redis内部存储结构

   我们要将一个数据存储到hash表中,那么会先通过murmur计算key对应的hashcode,然后根据hashcode取模得到bucket的位置,再插入到链表中。

redis内部存储结构

4. set集合类型:

  集合类型中,每个元素都是不同的,也就是不能有重复数据,同时集合类型中的数据是无序的。一个集合类型键可以存储至多 2^32-1 个 。集合类型和列表类型的最大的区别是有序性和唯一性。集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在。由于集合类型在redis内部是使用的值为空的散列表(hash table),所以这些操作的时间复杂度都是O(1).

  Set在的底层数据结构以intset或者hashtable来存储。当set中只包含整数型的元素时,采用intset来存储,否则,采用hashtable存储,但是对于set来说,该hashtable的value值用于为NULL,通过key来存储元素。

 

 redis内部存储结构

5. 有序集合:

  在集合类型的基础上,有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元素都是不同的,但是他们的分数却可以相同。

 

 redis内部存储结构

  zset类型的数据结构就比较复杂一点,内部是以ziplist或者skiplist+hashtable来实现,这里面最核心的一个结构就是skiplist,也就是跳跃表。

 redis内部存储结构