可以关注我的个人博客和公众号,第一时间发布最新的干货文章
个人博客网站:
微信公众号:spacedong
前言
在 Redis 中的列表是一个非常灵活的数据结构,提供了非常多的操作 API ,可以根据 API 的组合来满足需要的业务场景。
目录
- Redis列表( List )的常用方法及演示
-
Redis中列表( List )内部结构和源码解析
- 内部结构
- 源码解析
- 实际业务中列表( List )的使用场景
列表常用方法
1. 左右边插入键值对
//左边插入
redis 127.0.0.1:6379> LPUSH spacedong test1
"1"
//右边插入
redis 127.0.0.1:6379> RPUSH spacedong test2
"2"
//左边弹出
127.0.0.1:6379:3>LPOP spacedong
"test1"
//右边弹出
127.0.0.1:6379:3>RPOP spacedong
"test2"
2. 获取指定的区域的元素
127.0.0.1:6379:3>LRANGE spacedong 0 2
1) "test1"
2) "test2"
3. 通过索引获取列表中的元素
127.0.0.1:6379:3>LINDEX spacedong 1
"test2"
4. 修改特定位置的值
127.0.0.1:6379:3>LINDEX spacedong 1
"test2"
127.0.0.1:6379:3>LSET spacedong 1 test3
"OK"
127.0.0.1:6379:3>LINDEX spacedong 1
"test3"
5. 阻塞队列的实现
- BRPOP key timeout ,
timeout 如果指定为0,则客户端会一直等待下去,如果 timeout 指定多少秒,那么就会多少秒后返回。返回的第一个值是key,返回的第二个值是具体的元素。如果该key没有具体的元素时,返回为空。
//插入元素到key中
127.0.0.1:6379:3>LPUSH spacedong test1
"1"
//弹出key中的元素
127.0.0.1:6379:3>BRPOP spacedong 3
1) "spacedong"
2) "test3"
列表( List )的内部结构和源码解析
- 列表的数据结构
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
[图片上传失败...(image-9ffc86-1536663518125)]
在列表中的每个节点的数据结构都是一个双向链表结构,在 Redis 中则是实现了自己的链表结构,如下图所示
typedef struct list {
// 表头节点
listNode *head;
// 表尾节点
listNode *tail;
// 链表所包含的节点数量
unsigned long len;
// 节点值复制函数
void *(*dup)(void *ptr);
// 节点值释放函数
void (*free)(void *ptr);
// 节点值对比函数
int (*match)(void *ptr, void *key);
} list;
[图片上传失败...(image-72926d-1536663518125)]
- head 指向头部节点,获取的时间复杂度为 O(1)
- tail 指向尾部节点,获取的时间复杂度为 O(1)
- len 保存着列表的长度信息,本文中的是 3 ,获取的时间复杂度为O(1)
- dup 函数用于复制链表节点所保存的值
- free 函数用于释放链表节点所保存的值
- match 函数则用于对比链表节点所保存的值和另一个输入值是否相等。
实际业务中 List 的使用场景
- 一个是粉丝关注列表,收藏列表等,这种的业务需求是比较频繁和常见的。
- 作为消息队列的使用,虽然有 RabbitMQ、Kafka 等消息队列,List也是可以当为轻量级别的消息队列来使用的。
- 如果仅仅是把 list 当做一个容器来存储数据的话,那么用 Hash 这个字符串就可以了,Hash 使用的效果会更好。
想要获得更多的优质技术文章,可以关注下方的微信公众号 spacedong
为优质的文章而赞赏,这是为作者能持续输出的最大肯定!