Redis数据类型——list

简介

  • 数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
  • 需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
  • list类型:保存多个数据,底层使用双向链表存储结构实现
    在这里插入图片描述

数据结构

压缩列表

先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表
在这里插入图片描述

struct ziplist<T> {     
	int32 zlbytes; // 整个压缩列表占用字节数     
	int32 zltail_offset; // 最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点     
	int16 zllength; // 元素个数     
	T[] entries; // 元素内容列表,挨个挨个紧凑存储     
	int8 zlend; // 标志压缩列表的结束,值恒为 0xFF 
} 
struct entry {     
	int<var> prevlen; // 前一个 entry 的字节长度     
	int<var> encoding; // 元素类型编码,ziplist 通过这个字段来决定后面的 content 内容的形式     
	optional byte[] content; // 元素内容 
}

因为 ziplist 都是紧凑存储,没有冗余空间 (对比一下 Redis 的字符串结构)。意味着插入一个新的元素就需要调用 realloc 扩展内存。取决于内存分配器算法和当前的 ziplist 内存大小,realloc 可能会重新分配新的内存空间,并将之前的内容一次性拷贝到新的地址,也可能在原有的地址上进行扩展,这时就不需要进行旧内容的内存拷贝。 如果 ziplist 占据内存太大,重新分配内存和拷贝内存就会有很大的消耗。所以 ziplist 不适合存储大型字符串,存储的元素也不宜过多。

快速列表

当数据量比较多的时候才会改成 quicklist。Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
在这里插入图片描述

struct ziplist_compressed {     
	int32 size;    
	byte[] compressed_data; 
 } 
struct quicklistNode {     
	quicklistNode* prev;     
	quicklistNode* next;     
	ziplist* zl; // 指向压缩列表     
	int32 size; // ziplist 的字节总数     
	int16 count; // ziplist 中的元素数量     
	int2 encoding; // 存储形式 2bit,原生字节数组还是 LZF 压缩存储     
	... 
}
struct quicklist {     
	quicklistNode* head;     
	quicklistNode* tail;     
	long count; // 元素总数     
	int nodes; // ziplist 节点的个数     
	int compressDepth; // LZF 算法压缩深度     
	... 
} 
 

quicklist 内部默认单个 ziplist 长度为 8k 字节,超出了这个字节数,就会新起一个 ziplist。ziplist 的长度由配置参数 list-max-ziplist-size 决定。
为了进一步节约空间,Redis 还会对 ziplist 进行压缩存储,使用 LZF 算法压缩,可以选择压缩深度。
在这里插入图片描述
quicklist 默认的压缩深度是 0,也就是不压缩。压缩的实际深度由配置参数 listcompress-depth 决定。为了支持快速的 push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。如果深度为 2,就表示 quicklist 的首尾第一个 ziplist 以及首尾第二
个 ziplist 都不压缩。

常用命令

从左添加:lpush key value [value1] 
从右添加:rpush key value [value1] 
获取下标从start到stop的value:lrange key start stop
获取指定下标位置的值:lindex key index
list的长度:llen key
从左边获取并移除数据:lpop key
从右边获取并移除数据:rpop key
规定时间内获取并移除数据:blpop key1 [key2] timeout 
规定时间内获取并移除数据:brpop key1 [key2] timeout 
移除count个值为value的数据:lrem key count value

注意事项

  • list中保存的数据都是string类型的,数据总容量是有限的,最多2^32 - 1 个元素 (4294967295)
  • list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
  • 获取全部数据操作结束索引设置为-1,即:lrange list 0 -1
  • list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载

使用场景

  • 新浪微博中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面
  • 新闻、资讯类网站将最新的新闻或资讯按照发生的时间顺序展示
  • 企业运营过程中,系统将产生出大量的运营数据,保障多台服务器操作日志的统一顺序输出
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值