Redis CAP理论、数据类型、详细讲解
一、知识点
1、CAP理论
C:Consistency(强一致性)
A:Availability(可用性)
P:Partition tolerance(分区容错性)
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。
Redis(CP单线程)zookeeper CP
2、redis数据类型
都⽤过哪些数据类型?分别介绍下使⽤场景?
2.1、Spring:字符串
内部数据结构
在Redis内部,String类型通过int、SDS(simple dynamic string 简单动态字符串)作为结构存储,int用来存放整型数据,sds存放字节/字符串和浮点型数据。在C的标准字符串结构下进行了封装,用来提升基本操作的性能,同时也充分利用已有的C的标准库,简化实现逻辑。我们可以在redis的源码中【sds.h】中看到sds的结构如下;
typedef char *sds;
redis3.2分支引入了五种sdshdr类型,目的是为了满足不同长度字符串可以使用不同大小的Header,从而节省内存,每次在创建一个sds时根据sds的实际长度判断应该选择什么类型的sdshdr,不同类型的sdshdr 占用的内存空间不同。这样细分一下可以省去很多不必要的内存开销,下面是3.2的sdshdr定义
Len:已使用长度
Alloc:总长度
Flags:1字节标识当前类型
Buf[]:柔性数据,存放数据
len和alloc的类型不同(uint8、uint16、uint32、uint64)
如果是type5并且是空字符串,强制转化为type8,避免后期扩容引响性能。
SDS扩容:
1、获取当前可用空间长度avail,若大于等于新增长度addlen则无需扩容,直接返回
2、若avail小于addlen,len+addlen<1M,则按新长度的2倍扩容
3、若avail小于addlen,len+addlen>1M,则按新长度+1M
redis五种数据结构4、根据新长度选择sds类型,如果sds类型和原类型相同,则通过realloc扩大柔性数组
5、如果sds类型和原类型不相同,则malloc重新申请内存,并把原buf内容移动到新位置
6、对新串的属性进行赋值后返回
2.2、Hash:哈希结构(map)
数据结构
map提供两种结构来存储,一种是hashtable、另一种是ziplist,数据量小的时候用ziplist. 在redis中,哈希表分为三层,源码地址【dict.h】,分别是
dictEntry相当于JAVA中的NODE、dictht->数组、dict->hashMap
2.3、list:链表
内部数据结构
redis3.2之前,List 类型的value 对象内部以linkedlist(双向链表)或者ziplist 来实现, 当list 的元素个数和单个元素的长度比较小的时候,Redis 会采用ziplist (压缩列表)来实现来减少内存占用。否则就会采用linkedlist 结构。
这两种存储方式都有优缺点,双向链表在链表两端进行push 和pop 操作,在插入节点上复杂度比较低,
但是内存开销比较大;ziplist存储在一段连续的内存上,所以存储效率很高,但是插入和删除都需要频繁申请和释放内存;
redis3.2之后,采用的一种叫quicklist的数据结构来存储list,列表的底层都由quicklist实现。
quicklist仍然是一个双向链表,只是列表的每个节点都是一个ziplist,其实就是linkedlist和ziplist的结合,quicklist中每个节点ziplist都能够存储多个数据元素,在源码中的文件为【quicklist.c】,在源码第一行中有解释为:A doubly linked list of ziplists意思为一个由ziplist组成的双向链表;
quickList的数据存储由quicklist和quicklistNode构成。
压缩列表的设计思想
1、Redis为了节约内存而创造的存储结构。
2、连续的内存,元素与元素之间没有空隙。
3、encoding既存类别也存长度。
4、并不存储前后节点的指针,通过长度来计算出前后节点的位置。
5、zlentry的解码存储。
Redis采用的压缩算法是LZF,这是一种无损压缩算法进一步的节省空间
2.4、Set:集合
内部数据结构
Set在的底层数据结构以intset或者hashtable来存储。当set中只包含整数型的元素时,采用intset来存储,否则,采用hashtable存储,但是对于set来说,该hashtable的value值用于为NULL。通过key来存储元素
整数集合(intset)是一个有序的、存储整型数据的结构。
Set类型存储元素为64位有符号整数且存储个数小于512(配置)个时使用该结构存储。
encoding的编码类型:
length:元素个数
element[] 柔性数组根据encoding来决定几个字节来存一个元素
2.5、Sorted Set:有序集合
内部数据结构
zset类型的数据结构就比较复杂一点,内部是以ziplist或者skiplist+hashtable来实现,这里面最核心的一个结构就是skiplist,也就是跳跃表
Redis中的跳跃表实现:zskiplistNode
跳跃表节点管理:zskiplist
zskiplistNode *header *tail:头节点和尾节点
length:跳跃表长度(不包括头节点)
level:跳跃表高度
跳跃表的优势
既有链表快速插入的优势,又有数组快速定位的优势,对于有序链表查询优化,相比与平衡树(AVL、RBT)来说,更容易实现,从内存占用上来说,skiplist比平衡树更灵活一些(每节点平均1.33个指针)
2.6、(流)Stream(redis 5之后出现的)
紧凑列表listpack和基数树RaxTree

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。