加入收藏 | 设为首页 | 会员中心 | 我要投稿 网站开发网_安阳站长网 (https://www.0518zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

Redis为何这么快——数据存储角度

发布时间:2018-11-12 14:15:10 所属栏目:站长百科 来源:JAVA高级程序员
导读:副标题#e# 【新产品上线啦】51CTO播客,随时随地,碎片化学习 本文内容思维导图如下: 一、简介和应用 Redis是一个由ANSI C语言编写,性能优秀、支持网络、可持久化的K-K内存数据库,并提供多种语言的API。它常用的类型主要是 String、List、Hash、Set、ZSe

当一个列表键只包含少量列表项,且是小整数值或长度比较短的字符串时,那么redis就使用ziplist(压缩列表)来做列表键的底层实现。

Redis为何这么快——数据存储角度

ziplist是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块(而不是像双端链表一样每个节点是指针)组成的顺序型数据结构;具体结构相对比较复杂,有兴趣读者可以看 Redis 哈希结构内存模型剖析。在新版本中list链表使用 quicklist 代替了 ziplist和 linkedlist:

Redis为何这么快——数据存储角度

quickList 是 zipList 和 linkedList 的混合体。它将 linkedList 按段切分,每一段使用 zipList 来紧凑存储,多个 zipList 之间使用双向指针串接起来。因为链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 (64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。

Redis为何这么快——数据存储角度

quicklist 默认的压缩深度是 0,也就是不压缩。为了支持快速的 push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。为了进一步节约空间,Redis 还会对 ziplist 进行压缩存储,使用 LZF 算法压缩。

五、Hash

Hash对象的底层实现可以是ziplist(压缩列表)或者hashtable(字典或者也叫哈希表)。

Redis为何这么快——数据存储角度

Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。

hashtable哈希表可以实现O(1)复杂度的读写操作,因此效率很高。源码如下:

  1. typedef struct dict {  
  2.  // 类型特定函数  
  3.  dictType *type;  
  4.  // 私有数据  
  5.  void *privdata;  
  6.  // 哈希表  
  7.  dictht ht[2];  
  8.  // rehash 索引  
  9.  // 当 rehash 不在进行时,值为 -1  
  10.  int rehashidx; /* rehashing not in progress if rehashidx == -1 */  
  11.  // 目前正在运行的安全迭代器的数量  
  12.  int iterators; /* number of iterators currently running */  
  13.  } dict;  
  14.  typedef struct dictht {  
  15.  // 哈希表数组  
  16.  dictEntry **table;  
  17.  // 哈希表大小  
  18.  unsigned long size;  
  19.  // 哈希表大小掩码,用于计算索引值  
  20.  // 总是等于 size - 1  
  21.  unsigned long sizemask;  
  22.  // 该哈希表已有节点的数量  
  23.  unsigned long used;  
  24. } dictht;  
  25. typedef struct dictEntry {  
  26.  void *key;  
  27.  union {void *val;uint64_t u64;int64_t s64;} v;  
  28.  // 指向下个哈希表节点,形成链表  
  29.  struct dictEntry *next;  
  30.  } dictEntry;  
  31.  typedef struct dictType {  
  32.  // 计算哈希值的函数  
  33.  unsigned int (*hashFunction)(const void *key);  
  34.  // 复制键的函数  
  35.  void *(*keyDup)(void *privdata, const void *key);  
  36.  // 复制值的函数  
  37.  void *(*valDup)(void *privdata, const void *obj);  
  38.  // 对比键的函数  
  39.  int (*keyCompare)(void *privdata, const void *key1, const void *key2);  
  40.  // 销毁键的函数  
  41.  void (*keyDestructor)(void *privdata, void *key);  
  42.  // 销毁值的函数  
  43.  void (*valDestructor)(void *privdata, void *obj);  
  44. } dictType; 

上面源码可以简化成如下结构:

Redis为何这么快——数据存储角度

(编辑:网站开发网_安阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!