详解Redis中列表(List)的使用方法和内部结构

前言

在 Redis 中的列表是一个非常灵活的数据结构,提供了非常多的操作 API ,可以根据 API 的组合来满足需要的业务场景。

目录

  • Redis列表( List )的常用方法及演示
  • Redis中列表( List )内部结构和源码解析
    • 内部结构
    • 源码解析
  • 实际业务中列表( List )的使用场景

列表常用方法

1. 左右边插入键值对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//左边插入
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. 获取指定的区域的元素

1
2
3
127.0.0.1:6379:3>LRANGE spacedong 0 2
1) "test1"
2) "test2"

3. 通过索引获取列表中的元素

1
2
127.0.0.1:6379:3>LINDEX spacedong 1
"test2"

4. 修改特定位置的值

1
2
3
4
5
6
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没有具体的元素时,返回为空。
1
2
3
4
5
6
7
8
//插入元素到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 )的内部结构和源码解析

  • 列表的数据结构
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef struct listNode {

    // 前置节点
    struct listNode *prev;

    // 后置节点
    struct listNode *next;

    // 节点的值
    void *value;

    } listNode;

image
在列表中的每个节点的数据结构都是一个双向链表结构,在 Redis 中则是实现了自己的链表结构,如下图所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

  • head 指向头部节点,获取的时间复杂度为O(1)
  • tail 指向尾部节点,获取的时间复杂度为O(1)
  • len 保存着列表的长度信息,获取的时间复杂度为O(1)
  • dup 函数用于复制链表节点所保存的值
  • free 函数用于释放链表节点所保存的值
  • match 函数则用于对比链表节点所保存的值和另一个输入值是否相等。

实际业务中 List 的使用场景

  • 一个是粉丝关注列表,收藏列表等,这种的业务需求是比较频繁和常见的。
  • 作为消息队列的使用,虽然有RabbitMQ、Kafka等消息队列,List也是可以当为轻量级别的消息队列来使用的。
  • 如果仅仅是把 list 当做一个容器来存储数据的话,那么用 Hash 这个字符串就可以了,Hash 使用的效果会更好。
spacedong wechat
愿意交个朋友吗~
觉得有收获么