search
HomeDatabaseMysql Tutorial Redisbook学习笔记(3)数据类型之列表

REDIS_LIST(列表)是LPUSH、LRANGE等命令的操作对象,它使用REDIS_ENCODING_ZIPLIST和REDIS_ENCODING_LINKEDLIST这两种方式编码:编码的选择创建新列表时Redis

REDIS_LIST (列表) 是LPUSH 、LRANGE 等命令的操作对象, 它使用

REDIS_ENCODING_ZIPLIST 和REDIS_ENCODING_LINKEDLIST 这两种方式编码:

wKioL1MITs2QL2gQAACErY08a4I028.jpg


编码的选择

创建新列表时Redis 默认使用REDIS_ENCODING_ZIPLIST 编码,当以下任意一个条件被满足

时,列表会被转换成REDIS_ENCODING_LINKEDLIST 编码:

试图往列表新添加一个字符串值, 且这个字符串的长度超过

server.list_max_ziplist_value (默认值为64 )。

ziplist 包含的节点超过server.list_max_ziplist_entries (默认值为512 )。

列表命令的实现

因为两种底层实现的抽象方式和列表的抽象方式非常接近,所以列表命令几乎就是通过一对一

地映射到底层数据结构的操作来实现的。

我们将焦点放在BLPOP 、BRPOP 和BRPOPLPUSH 这个几个阻塞命令的实现原理上。

阻塞的条件

BLPOP 、BRPOP 和BRPOPLPUSH 三个命令都可能造成客户端被阻塞,以下将这些命令统

称为列表的阻塞原语。

阻塞原语并不是一定会造成客户端阻塞:

只有当这些命令被用于空列表时,它们才会阻塞客户端。

如果被处理的列表不为空的话,它们就执行无阻塞版本的LPOP 、RPOP 或RPOPLPUSH

命令。

作为例子,以下流程图展示了BLPOP 决定是否对客户端进行阻塞过程:

wKioL1MITxuS-8G0AADG24Rbqgo857.jpg

阻塞

当一个阻塞原语的处理目标为空键时,执行该阻塞原语的客户端就会被阻塞。

阻塞一个客户端需要执行以下步骤:

1. 将客户端的状态设为“正在阻塞” ,并记录阻塞这个客户端的各个键,以及阻塞的最长时限

(timeout)等数据。

2. 将客户端的信息记录到server.db[i]->blocking_keys 中(其中i 为客户端所使用的数

据库号码)。

3. 继续维持客户端和服务器之间的网络连接,但不再向客户端传送任何信息,造成客户端

阻塞。

步骤2 是将来解除阻塞的关键,server.db[i]->blocking_keys 是一个字典,字典的键是那

些造成客户端阻塞的键,而字典的值是一个链表,链表里保存了所有因为这个键而被阻塞的客

户端(被同一个键所阻塞的客户端可能不止一个):

wKiom1MIT2aySd1_AAClIHH4ifM237.jpg

在上图展示的blocking_keys 例子中,client2 、client5 和client1 三个客户端就正被

key1 阻塞,而其他几个客户端也正在被别的两个key 阻塞。

当客户端被阻塞之后,脱离阻塞状态有以下三种方法:

1. 被动脱离:有其他客户端为造成阻塞的键推入了新元素。

2. 主动脱离:到达执行阻塞原语时设定的最大阻塞时间。

3. 强制脱离:客户端强制终止和服务器的连接,或者服务器停机。

以下内容将分别介绍被动脱离和主动脱离的实现方式。

阻塞因LPUSH 、RPUSH 、LINSERT 等添加命令而被取消

通过将新元素推入造成客户端阻塞的某个键中,可以让相应的客户端从阻塞状态中脱离出来

(取消阻塞的客户端数量取决于推入元素的数量)。

LPUSH 、RPUSH 和LINSERT 这三个添加新元素到列表的命令, 在底层都由一个

pushGenericCommand 的函数实现,这个函数的运作流程如下图:

wKioL1MIT5agg5ZJAAFkgli-0eE983.jpg

当向一个空键推入新元素时,pushGenericCommand 函数执行以下两件事:

1. 检查这个键是否存在于前面提到的server.db[i]->blocking_keys 字典里,如果是的

话,那么说明有至少一个客户端因为这个key 而被阻塞,程序会为这个键创建一个

redis.h/readyList 结构,并将它添加到server.ready_keys 链表中。

2. 将给定的值添加到列表键中。

readyList 结构的定义如下:

typedef struct readyList { redisDb *db; robj *key; } readyList;

readyList 结构的key 属性指向造成阻塞的键,而db 则指向该键所在的数据库。

举个例子,假设某个非阻塞客户端正在使用0 号数据库,而这个数据库当前的blocking_keys

属性的值如下:

wKioL1MIT_Hwx0q9AACa453oTDI826.jpg

如果这时客户端对该数据库执行PUSH key3 value ,那么pushGenericCommand 将创建一个

db 属性指向0 号数据库、key 属性指向key3 键对象的readyList 结构,并将它添加到服务器

server.ready_keys 属性的链表中:

wKiom1MIUDTRmqrEAACEjWBbm8A032.jpg

在我们这个例子中,到目前为止,pushGenericCommand 函数完成了以下两件事:

1. 将readyList 添加到服务器。

2. 将新元素value 添加到键key3 。

虽然key3 已经不再是空键,但到目前为止,被key3 阻塞的客户端还没有任何一个被解除阻塞

状态。

为了做到这一点,Redis 的主进程在执行完pushGenericCommand 函数之后,会继续调用

handleClientsBlockedOnLists 函数,这个函数执行以下操作:

1. 如果server.ready_keys 不为空, 那么弹出该链表的表头元素, 并取出元素中的

readyList 值。

2. 根据readyList 值所保存的key 和db ,在server.blocking_keys 中查找所有因为key

而被阻塞的客户端(以链表的形式保存)。

3. 如果key 不为空,那么从key 中弹出一个元素,并弹出客户端链表的第一个客户端,然

后将被弹出元素返回给被弹出客户端作为阻塞原语的返回值。

4. 根据readyList 结构的属性,删除server.blocking_keys 中相应的客户端数据,取消

客户端的阻塞状态。

5. 继续执行步骤3 和4 ,直到key 没有元素可弹出,或者所有因为key 而阻塞的客户端都

取消阻塞为止。

6. 继续执行步骤1 ,直到ready_keys 链表里的所有readyList 结构都被处理完为止。

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
es和redis区别es和redis区别Jul 06, 2019 pm 01:45 PM

Redis是现在最热门的key-value数据库,Redis的最大特点是key-value存储所带来的简单和高性能;相较于MongoDB和Redis,晚一年发布的ES可能知名度要低一些,ES的特点是搜索,ES是围绕搜索设计的。

一起来聊聊Redis有什么优势和特点一起来聊聊Redis有什么优势和特点May 16, 2022 pm 06:04 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于redis的一些优势和特点,Redis 是一个开源的使用ANSI C语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式存储数据库,下面一起来看一下,希望对大家有帮助。

实例详解Redis Cluster集群收缩主从节点实例详解Redis Cluster集群收缩主从节点Apr 21, 2022 pm 06:23 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis Cluster集群收缩主从节点的相关问题,包括了Cluster集群收缩概念、将6390主节点从集群中收缩、验证数据迁移过程是否导致数据异常等,希望对大家有帮助。

Redis实现排行榜及相同积分按时间排序功能的实现Redis实现排行榜及相同积分按时间排序功能的实现Aug 22, 2022 pm 05:51 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,希望对大家有帮助。

详细解析Redis中命令的原子性详细解析Redis中命令的原子性Jun 01, 2022 am 11:58 AM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于原子操作中命令原子性的相关问题,包括了处理并发的方案、编程模型、多IO线程以及单命令的相关内容,下面一起看一下,希望对大家有帮助。

实例详解Redis实现排行榜及相同积分按时间排序功能的实现实例详解Redis实现排行榜及相同积分按时间排序功能的实现Aug 26, 2022 pm 02:09 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,下面一起来看一下,希望对大家有帮助。

一文搞懂redis的bitmap一文搞懂redis的bitmapApr 27, 2022 pm 07:48 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了bitmap问题,Redis 为我们提供了位图这一数据结构,位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已,希望对大家有帮助。

一起聊聊Redis实现秒杀的问题一起聊聊Redis实现秒杀的问题May 27, 2022 am 11:40 AM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于实现秒杀的相关内容,包括了秒杀逻辑、存在的链接超时、超卖和库存遗留的问题,下面一起来看一下,希望对大家有帮助。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.