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. 强制脱离:客户端强制终止和服务器的连接,或者服务器停机。

如知AI笔记 如知AI笔记

如知笔记——支持markdown的在线笔记,支持ai智能写作、AI搜索,支持DeepseekR1满血大模型

如知AI笔记 27 查看详情 如知AI笔记

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

阻塞因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 结构都被处理完为止。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/539835.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月9日 14:35:29
下一篇 2025年11月9日 14:36:06

相关推荐

  • css中列表样式是什么

    css中列表样式是:1、css有序列表【ol】和css无序列表【ul】;2、css列表标号样式【list-style-type】;3、css标号样式的显示方式【list-style-position】。 本教程操作环境:windows7系统、css3版,DELL G3电脑。 css中列表样式是: 1…

    2025年12月24日
    000
  • css列表怎么横着排列

    css列表横着排列的方法:可以利用【display:inline】属性把【】标签设定为内联元素来实现横向排列效果。display属性规定了元素应该生成的框的类型。 思路: 设定 标签的display:inline,把设定为内联元素来实现横向排列的效果。 (推荐教程:css视频教程) 属性介绍: 立即…

    2025年12月24日
    000
  • Redis3.2开启远程访问详细步骤

    redis是一个开源的使用ansi c语言编写、支持网络、可基于内存亦可持久化的日志型、key-value数据库,并提供多种语言的api。redis支持远程访问,详细步骤小编已为大家整理出来了,具体步骤如下: redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf打开r…

    好文分享 2025年12月24日
    000
  • Redis配置文件redis.conf详细配置说明

    本文列出了redis的配置文件redis.conf的各配置项的详细说明,简单易懂,有需要的盆友可以参考哦。 redis.conf 配置项说明如下 redis配置文件详解 # vi redis.confdaemonize yes #是否以后台进程运行pidfile /var/run/redis/red…

    好文分享 2025年12月24日
    000
  • Flask应用中动态图片更新与上传教程

    本教程详细介绍了如何在flask web应用中展示静态图片,并通过%ignore_a_1%实现图片的定时刷新,解决浏览器缓存问题。同时,文章还涵盖了如何在flask后端处理图片上传,并将其与前端展示及刷新机制相结合,提供了一个完整的图片管理与动态显示解决方案。 1. Flask应用中静态图片的基本展…

    2025年12月23日 好文分享
    000
  • PHP 多语言网站切换:会话管理与翻译函数实践

    本教程详细介绍了使用 php 构建多语言网站的实现方法。文章涵盖了如何通过 url 参数和会话管理实现语言切换,以及如何设计一套健壮的翻译加载与显示机制,以避免常见的变量未定义和字符串偏移错误。通过封装的辅助函数,确保翻译内容正确加载和渲染,提升代码的可维护性和用户体验。 构建多语言网站的核心挑战 …

    2025年12月23日
    000
  • 将独立Python逻辑集成到Django Web应用:以计时器项目为例

    本教程旨在指导初学者如何将一个独立的Python命令行计时器应用改造并集成到Django Web项目中。文章将详细介绍如何通过Django的视图、表单和模板机制处理用户输入、执行核心Python逻辑,并最终在HTML页面上展示结果,同时探讨将命令行应用特性迁移到Web环境的关键考量。 理解从命令行到…

    2025年12月23日
    000
  • 如何将Python后端逻辑与Django和HTML进行集成

    本教程旨在指导初学者如何将独立的Python命令行应用程序转换为基于Django的Web应用。文章将详细阐述如何通过Django的视图、URL配置和表单系统,将Python逻辑与HTML前端进行交互,实现用户输入捕获和结果展示。重点在于重构Python代码以适应Web环境,并利用Django For…

    2025年12月23日
    000
  • 将Python命令行应用集成到Django Web项目:以计时器为例

    本文将指导您如何将一个独立的python命令行计时器应用程序改造并集成到django web项目中。我们将详细介绍如何利用django的视图、模板和表单系统来捕获用户输入,并将原有的python逻辑适配到web环境,同时探讨在web应用中处理后台任务和用户通知的策略,帮助初学者顺利过渡。 从命令行到…

    好文分享 2025年12月23日
    000
  • 部署与调度Node.js爬虫:从本地执行到云端集成

    本教程详细指导如何部署和调度一个基于node.js的网页爬虫,使其能够每日自动运行并将其数据提供给前端应用。文章将区分客户端与服务器端javascript的运行环境,介绍本地任务调度方法,并探讨将爬虫集成到在线服务以实现数据共享的策略,同时涵盖数据持久化、cors处理及部署最佳实践。 1. 理解No…

    2025年12月23日
    000
  • HTML5WebSocket怎么通信_HTML5WebSocket实现实时通信的原理与代码

    WebSocket基于TCP实现全双工通信,通过HTTP握手升级协议后进行持久化双向数据传输,适用于聊天、通知等高频交互场景;前端使用JavaScript的WebSocket API建立连接并监听事件,后端可用Node.js的ws库创建服务器;需注意代理配置、自动重连、JSON格式消息及安全认证等问…

    2025年12月23日
    000
  • 实现实时UI更新:利用SSE与WebSocket告别传统轮询

    本文探讨了如何在不依赖传统http轮询的情况下,实现用户界面(ui)的实时动态更新,尤其适用于聊天应用中的用户活动状态显示。文章详细介绍了两种主流技术:服务器发送事件(sse)和websocket,并阐明了它们的工作原理、适用场景及选择依据。通过采用这些技术,服务器能够主动向客户端推送数据,从而避免…

    好文分享 2025年12月23日
    000
  • HTML5在线如何实现实时视频聊天 HTML5在线通信功能的开发方法

    实现实时视频聊天主要依赖WebRTC技术,1. 通过getUserMedia获取音视频流,RTCPeerConnection建立P2P连接,RTCDataChannel传输数据;2. 使用Node.js+Socket.IO搭建信令服务器交换SDP与ICE信息;3. 借助STUN/TURN服务器穿透N…

    2025年12月23日
    000
  • Web内容访问控制:用户认证、会话管理与数字版权保护(DRM)

    本文旨在提供一个全面的指南,介绍如何在web应用中实现基于用户登录状态的内容访问控制。我们将详细探讨利用会话和cookie进行用户认证的机制,包括登录流程、会话管理及安全性考量。此外,文章还将深入讨论数字版权管理(drm)技术,如widevine、playready和fairplay,以应对视频内容…

    2025年12月23日
    000
  • 如何实现HTML在线实时聊天_HTML在线实时聊天功能实现与消息推送方案

    核心是WebSocket实现双向通信,替代传统HTTP轮询;前端用JavaScript创建连接并监听消息,后端如Node.js或Spring Boot提供支持;备选方案包括SSE和长轮询;配合心跳、重连、消息队列等机制保障稳定性。 要在HTML网页上实现在线实时聊天,核心是解决消息的即时推送问题。传…

    2025年12月23日
    000
  • Discord用户头像链接的动态获取与持久性挑战

    本文探讨了discord用户头像链接的持久性问题。由于discord为上传图片生成随机url,直接获取一个“始终更新且链接不变”的用户头像链接是不可行的。唯一可靠的方法是通过discord api动态获取用户的最新头像url,并利用其用户id作为稳定标识符。 Discord用户头像URL的本质与限制…

    2025年12月23日
    000
  • HTML表单重复提交漏洞怎么避免_表单重复提交导致数据异常漏洞避免方法

    答案:避免HTML表单重复提交需前端禁用按钮、后端令牌验证与幂等设计、数据库唯一约束协同防御。 HTML表单重复提交,这事儿说起来挺头疼的,因为它不仅影响用户体验,更可能直接导致数据异常,比如订单重复创建、支付重复扣款,甚至一些敏感操作被多次执行。在我看来,避免这类漏洞,本质上是一场客户端与服务器端…

    2025年12月23日
    000
  • HTML数据如何实现实时采集 HTML数据流式处理的架构设计

    答案:构建低延迟、高吞吐的实时HTML流处理系统需分四步:1. 采集层用轻量HTTP或无头浏览器动态抓取,结合增量识别与分布式集群提升效率;2. 解析层采用流式解析器与规则抽取,提取结构化数据并容错降级;3. 流架构通过消息队列解耦,接入Flink等引擎做实时计算与多端输出;4. 保障层实现重试、限…

    2025年12月23日
    000
  • HTML数据如何实现分布式采集 HTML数据分布式爬虫的架构设计

    答案:构建分布式HTML采集系统需整合任务调度、去重、存储与监控模块,以Redis为核心协调任务分发与去重,通过消息队列实现负载均衡,结合布隆过滤器减少重复抓取,利用无状态工作节点支持弹性扩展,依托ZooKeeper保障高可用,并集成反爬适配与请求控制机制,确保系统稳定高效运行。 要实现HTML数据…

    好文分享 2025年12月23日
    000
  • HTML数据如何构建数据API HTML数据接口的开发与部署

    答案:将HTML转为API需先解析稳定结构化数据,再用Flask等框架提供JSON接口。1. 确认HTML有清晰标签与更新规律;2. 用Python爬取并解析页面,封装为REST API;3. 部署至云服务器或Serverless平台;4. 加缓存、设请求头、控频次以提升稳定性。 直接把HTML数据…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信