Redis 数据类型String,List,Set,ZSet,Hash详解

大家好 我是积极向上的湘锅锅

Redis 数据结构SDS,Intset,Dict,Ziplist,Quicklist详解

1. String

  • 其中最基本的编码方式是RAW编码,基于动态字符串(SDS)实现,存储上线为512mb
    每一个String实则就是一个RedisObject,只不过在RedisObject的ptr指针指向的SDS的地址
typedef struct redisObject 
{ 
	unsigned type:4; 
	unsigned encoding:4; 
	unsigned lru:REDIS_LRU_BITS;  
	/* lru time (relative to server.lruclock) */  
	int refcount; 
	void *ptr;
} robj;

如图

Redis 数据类型String,List,Set,ZSet,Hash详解_第1张图片

  • 第二种编码方式是EMBSTR编码,需要SDS长度小于44字节,那RedisObject与SDS就是一段连续的内存空间,只需要申请一次内存即可,大大提高效率

如图
在这里插入图片描述

  • 第三章编码方式是INT编码,需要存储的字符串为整数值,并且大小在LONG_MAX范围内,那就可以直接把数据保存在ptr(整数不会超过8字节)指针,就不再需要SDS了

如图

Redis 数据类型String,List,Set,ZSet,Hash详解_第2张图片
总结:
可以看到Redis在string类型所做的优化已经十分完善,根据数据类型,数据大小采用不同的编码方式,以此来节省空间,提高效率


2. List

Redis的List类型可以从首,尾操作列表中的元素
在3.2版本之前,Redis的List采用ZipList和LinkedList来实现
在3.2版本之后,Redis的List底层是统一采用QuickList来实现

一个完整的list如下:
Redis 数据类型String,List,Set,ZSet,Hash详解_第3张图片


3. Set

Set是Redis中的集合,不一定确保元素有序,可以满足元素唯一,查询效率要求极高

  • 为了保证查询效率,Set采用HT(Dict),其中key来存储元素,value统一为null

Redis 数据类型String,List,Set,ZSet,Hash详解_第4张图片

  • 当存储的所有数据都是整数,并且元素数量不超过set-max-intset-entries时,会采用Intset编码,用以节省内存(因为Intset是一段连续的内存)

Redis 数据类型String,List,Set,ZSet,Hash详解_第5张图片


4. ZSet

Redis中的ZSet满足键值存储,键唯一,可排序
所以ZSet采用俩种编码结构

  • SkipList :可以排序
  • HT:键值存储

整个zset结构如下,没有什么是加一层解决不了的

Redis 数据类型String,List,Set,ZSet,Hash详解_第6张图片

整个ZSet就显得比较庞大,也比较容易看出来是非常消耗内存的

Redis 数据类型String,List,Set,ZSet,Hash详解_第7张图片
Redis也做了相应的优化

当元素不多的时候,用HT和SkipList那就很浪费内存那有没有不浪费内存的编码结构有的,那就是ZipList

但是需要满足俩个条件

  • 元素数量小于zset_max_ziplist_entries,默认值128
  • 每个元素都小于zset_max_ziplist_value,默认值64

问题来了,ZipList也可以满足ZSet的特性?

这就不得不感叹大佬的设计思想

  1. 没有键值对
    解决:因为是连续内存,可以将score和ele紧挨在一起,ele在前,score在后,可以看成一个整体,虽然遍历的时候需要遍历一遍ZipList,查询性能不高,但是在数据量小的情况下是影响不大的(牺牲性能,节省内存)
  2. 不可排序
    解决:score越小越接近队首,score越大越接近队尾,按照score升序排列

Redis 数据类型String,List,Set,ZSet,Hash详解_第8张图片


5. Hash

其实Hash跟Zset只有一点区别,就是是否是排序,那就直接去掉SkipList
那整个编码就是HT+ZipList

  • 数据量小的时候,采用的是ZipList

Redis 数据类型String,List,Set,ZSet,Hash详解_第9张图片

  • 数据量大的时候,采用的是HT
    ZipList的元素超过了zset_max_ziplist_entries,默认512
    ZipList的元素超过了zset_max_ziplist_value,默认64字节

你可能感兴趣的:(redis,redis,哈希算法,java)