一、前言

Redis 提供了5种数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要。

原文解析

Redis 中的 list 是我们经常使用到的一种数据类型,根据使用方式的不同,可以应用到很多场景中。

二、操作命令

List数据类型在 Redis 中的相关命令:

命令 描述 用法
LPUSH 1.将一个或多个值value插入到列表key的表头
2.如果有多个value值,那么各个value值按从左到右的顺序依次插入表头
3.key不存在,一个空列表会被创建并执行LPUSH操作
4.key存在但不是列表类型,返回错误
LPUSH key value [value ...]
LPUSHX 1.将值value插入到列表key的表头,当且仅当key存在且为一个列表
2.key不存在时,LPUSHX命令什么都不做
LPUSHX key value
LPOP 1.移除并返回列表key的头元素 LPOP key
LRANGE 1.返回列表key中指定区间内的元素,区间以偏移量start和stop指定
2.start和stop都以0位底
3.可使用负数下标,-1表示列表最后一个元素,-2表示列表倒数第二个元素,以此类推
4.start大于列表最大下标,返回空列表
5.stop大于列表最大下标,stop=列表最大下标
LRANGE key start stop
LREM 1.根据count的值,移除列表中与value相等的元素
2.count>0表示从头到尾搜索,移除与value相等的元素,数量为count
3.count<0表示从从尾到头搜索,移除与value相等的元素,数量为count
4.count=0表示移除表中所有与value相等的元素
LREM key count value
LSET 1.将列表key下标为index的元素值设为value
2.index参数超出范围,或对一个空列表进行LSET时,返回错误
LSET key index value
LINDEX 1.返回列表key中,下标为index的元素 LINDEX key index
LINSERT 1.将值value插入列表key中,位于pivot前面或者后面
2.pivot不存在于列表key时,不执行任何操作
3.key不存在,不执行任何操作
LINSERT key BEFORE
LLEN 1.返回列表key的长度
2.key不存在,返回0
LLEN key
LTRIM 1.对一个列表进行修剪,让列表只返回指定区间内的元素,不存在指定区间内的都将被移除 LTRIM key start stop
RPOP 1.移除并返回列表key的尾元素 RPOP key
RPOPLPUSH 在一个原子时间内,执行两个动作:
1.将列表source中最后一个元素弹出并返回给客户端
2.将source弹出的元素插入到列表desination,作为destination列表的头元素
RPOPLPUSH source destination
RPUSH 1.将一个或多个值value插入到列表key的表尾 RPUSH key value [value ...]
RPUSHX 1.将value插入到列表key的表尾,当且仅当key存在并且是一个列表
2.key不存在,RPUSHX什么都不做
RPUSHX key value

实践:别偷懒,动手一下,try it out

三、应用场景

1、lpush+lpop=Stack(栈)

2、lpush+rpop=Queue(队列)

3、lpush+ltrim=Capped Collection(有限集合)

4、lpush+brpop=Message Queue(消息队列)

5、排行榜,数据最新列表等等

四、底层解析

结构图上显示,List类型有两种实现方式:

举例说明,创建列表对象 numbers

1、使用压缩列表(ziplist)实现的列表对象

结构如下

2、使用双端链表(linkedlist)实现的列表对象

结构如下

五、疑问思考

压缩列表与双端链表是什么样的结构?

1、压缩列表(ziplist)

压缩列表(ziplist)是Redis为了节省内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值。

结构如下

压缩列表的每个节点构成如下

1)previous_entry_ength:以字节为单位,记录了压缩列表中前一个字节的长度。previous_entry_ength 的长度可以是1字节或者5字节:

  如果前一节点的长度小于254字节,那么 previous_entry_ength 属性的长度为1字节,前一节点的长度就保存在这一个字节里面。

  如果前一个节点的长度大于等于254,那么 previous_entry_ength 属性的长度为5字节,其中属性的第一字节会被设置为0xFE(十进制254),而之后的四个字节则用于保存前一节点的长度。

  利用此原理即当前节点位置减去上一个节点的长度即得到上一个节点的起始位置,压缩列表可以从尾部向头部遍历,这么做很有效地减少了内存的浪费。

2)encoding:记录了节点的 content 属性所保存数据的类型以及长度。

3)content:保存节点的值,节点的值可以是一个字节数组或者整数,值的类型和长度由节点的 encoding 属性决定。

2、双端链表(linkedlist)

链表是一种常用的数据结构,C 语言内部是没有内置这种数据结构的实现,所以Redis自己构建了链表的实现。

链表节点定义:

typedef  struct listNode{
//前置节点
struct listNode *prev;
//后置节点
struct listNode *next;
//节点的值
void *value;
}listNode

多个 listNode 可以通过 prev 和 next 指针组成双端链表,结构如下

另外Redis还提供了操作链表的数据结构:

typedef struct list{
//表头节点
listNode *head;
//表尾节点
listNode *tail;
//链表所包含的节点数量
unsigned long len;
//节点值复制函数
void (*free) (void *ptr);
//节点值释放函数
void (*free) (void *ptr);
//节点值对比函数
int (*match) (void *ptr,void *key);
}list;

list结构为链表提供了表头指针 head ,表尾指针 tail 以及链表长度计数器 len ,dup、free、match 成员则是用于实现多态链表所需的类型特定函数。

Redis链表实现的特性

  • 双端:链表节点带有 prev 和 next 指针,获取某个节点的前置节点和后置节点复杂度都是O(1)。
  • 无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问以NULL为终点。
  • 带表头指针和表尾指针:通过list结构的 head 和 tail 指针,程序获取链表的表头节点和表尾结点的复杂度都是O(1)。
  • 带链表长度计数器:程序使用 list 结构的 len属性对 list持有的链表节点进行计数,程序获取链表中节点数量的复杂度为O(1)。
  • 多态:链表节点使用 void* 指针来保存节点值,并且通过 list 结构的 dup、 free、match 三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值。

疑问:Redis列表什么时候会使用 ziplist 编码,什么时候又会使用 linkedlist 编码呢?下节再说...

《闲扯Redis三》Redis五种数据类型之List型的更多相关文章

  1. 《闲扯Redis一》五种数据类型之String型

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  2. Redis支持的五种数据类型

    redis支持的五种数据类型: 1.string(字符串) 2.hash(哈希) Redis hash 是一个键值(key=>value)对集合. Redis hash是一个string类型的f ...

  3. 【Redis】一、Redis简介及五种数据类型

    (一)Redis简介   Redis(Remote Dictionary Server)是一个使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value的开源 ...

  4. 《闲扯Redis六》Redis五种数据类型之Hash型

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  5. 《闲扯Redis九》Redis五种数据类型之Set型

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  6. Redis安装及五种数据类型

    redis是非关系型数据库,也叫内存数据库.数据是键值对的形式,通过key查找value 安装Radis:6379 sudo apt-get update sudo apt-get install r ...

  7. Redis学习笔记--五种数据类型的使用场景

    String 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...

  8. <Redis> 入门二 五种数据类型的操作、通用key的操作、发布订阅

    文档参考:http://www.redis.net.cn/ string - > key value 简单的keyvalue,常规计数:例如微博数,粉丝数 set     -> key v ...

  9. redis五种数据类型的使用场景

    string 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...

随机推荐

  1. 前端javascript知识(一)

    介绍一下 JS 的基本数据类型. Undefined.Null.Boolean.Number.String 介绍一下 JS 有哪些内置对象. Object 是 JavaScript 中所有对象的父对象 ...

  2. 关于使用fastjson出现的问题:com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 1, fastjson-version 1.2.44

    先说下需求:是从redis中根据keys批量获取数据集合,再通过fastjson转为对象集合 代码如下: 在postman测试后,出现错误如下: 刚开始以为是使用fstjson方法不对,后面先通过打断 ...

  3. 4,Java中的多线程

    1,创建线程 ··· 继承Thread类:     必须覆写Thread的run方法. ··· 实现Runnable接口:     必须实现run方法,再传入到Thread(Runnable t)构造 ...

  4. 搭建flutter开发

    最近入坑flutter,dart还没开始学,搭环境就干了我一天半,不容易,记录一下, 我们先立个目标,这是我已经配好的,我是真的有强迫症,需要打四个对勾,真的不容易,我们一个一先说一下每一个都代表什么 ...

  5. RedisTemplate:我不背锅,是你用错了

    今天分享一个RedisTemplate的问题,感兴趣的可以继续看下去了,不感兴趣的继续撩妹去吧! 如下图:一位朋友给了我一个报错的图片,为啥为啥取不到值? 我也有点懵,第一反应就是RedisTempl ...

  6. CyclicBarrier源码探究 (JDK 1.8)

    CyclicBarrier也叫回环栅栏,能够实现让一组线程运行到栅栏处并阻塞,等到所有线程都到达栅栏时再一起执行的功能."回环"意味着CyclicBarrier可以多次重复使用,相 ...

  7. aosp 制作 rom 刷机 添加厂家二进制驱动 及 出厂镜像

    首先介绍下背景知识. aosp 仅是一套源码,不含厂家驱动. CM安卓的厂家驱动是自行提取的. 一般的安卓手机分区,有 boot , system, user , Baseband 基带, recov ...

  8. Kaggle 题目 nu-cs6220-assignment-1

    Kaggle题目 nu-cs6220-assignment-1 题目地址如下: https://www.kaggle.com/c/nu-cs6220-assignment-1/overview 这是个 ...

  9. Hadoop集群搭建(六)~安装JDK

    前面集群的准备工作都做完了,本篇记录安装JDK,版本位1.8 1,在opt目录下创建software和module文件夹:software用来放安装包,module为安装目录 2,把JDK和hadoo ...

  10. kafka启动报错"A broker is already registered on the path /brokers/ids/1"解决方案

    问题 kafka挂掉后,启动报错日志如下 [2020-03-19 17:50:58,123] FATAL Fatal error during KafkaServerStartable startup ...