2023.12.28 关于 Redis 数据类型 List 内部编码、应用场景
目录
List 编码方式
早期版本
现今版本
List 实际应用
多表之间的关联关系
消息队列
频道(多列表)消息队列
微博 Timeline
栈 & 队列
List 编码方式
早期版本
- 早期版本 List 类型的内部编码方式有两种
- ziplist(压缩列表)
- linkedlist(链表)
- 两个配置项
- list-max-ziplist-entries 配置
- list-max-ziplist-value 配置
注意:
- 现版本 Redis 已不再使用这两个配置项
- 且上述的 两种编码方式 为早期版本 Reids 中的 List 类型内部编码方式
现今版本
- 现今版本 Redis 使用 quicklist 作为 List 类型的内部编码方式
- quicklist 相当于 ziplist 和 linkedlist 的结合
- quicklist 整体上还是一个 linkedlist ,但 linkedlist 的每个节点均为一个 ziplist
特点:
- 每个节点上的 ziplist 不会太大,且这多个 ziplist 通过链式结构链接起来
配置项:
- 该配置项描述了每个节点 ziplist 的阈值
- 当 ziplist 满足阈值,便将其分裂成多个列表节点,即多个 ziplist
- 再将这多个 ziplist 通过链式结构链接起来
注意:
- 观察上图注释信息,ziplist 的阈值为可选项
- 所以我们还需针对当前业务场景,来选择合适的阈值!
实例理解
- 我们通过 object encoding key 来查看编码方式
List 实际应用
多表之间的关联关系
- 可将 list 作为 数组 这样的结构来存储多个元素
实例理解
- 使用 MySQL 表示学生和班级信息
- 上图 MySQL 表结构 可以很方便的实现 查询指定班级中有哪些同学
- Redis 所提供的查询功能 是不如 MySQL 的
- 所以我们可以通过往 Redis 中插入 List 类型键值对直接将 学生 和 班级信息 进行关联
- 结合上图实例,Redis 通过 List 类型 便可以将 学生 和 班级信息 关联起来
- 从而能很轻易的实现 查询指定班级中有哪些同学
注意:
- 此处除了使用 Hash 类型表示学生信息,也可使用 String + JSON 的方式来表示学生信息
- 即 具体 Redis 中的数据是如何组织的,都需根据实际的业务情况来决定
消息队列
- 生产者消费者模型
- 上图的 brpop 为阻塞操作
- 当列表为空时,brpop 命令便会阻塞等待,一直等到其他客户端向列表中 lpush 元素为止
重点理解:
- 此处 只有一个消费者能抢到元素
通俗理解:
- 谁先执行的 brpop 命令,谁就能拿到这个新 lpush 的元素
- 该设定便能很好的构成 "轮询" 效果
实例理解
- 假设此时列表为空,三个消费者(A、B、C)按顺序执行 brpop 命令进行阻塞等待
- 即执行顺序为 消费者A ——> 消费者B ——> 消费者C
- 当有新元素到达列表时,该新元素将被 消费者A 获取,且 brpop 命令立即返回,标志着 消费者A 完成了一次消费操作
- 若消费者A 想要继续消费,必须再次执行 brpop 命令
- 此时执行顺序变为 消费者B ——> 消费者C ——> 消费者A
- 如果再有新元素到达,消费者B 将获取该元素,且 brpop 命令立即返回,标志着 消费者 B 完成了一次消费操作
总结:
- 上述实例所描述的这种轮询方式,即消费者们按照固定的顺序交替执行 brpop 命令
- 很好的实现了对阻塞队列的有序消费
频道(多列表)消息队列
- 多列表/频道 这种场景是比较常见的
实例理解
- 日常使用的程序,比如抖音
- 一个频道 用来传输短视频数据
- 一个频道 用来传输弹幕
- 还可以有多个频道,用来传输点赞、转发、收藏、评论数据
优点:
- 多频道模式 一定程度上保证了在某种数据发生问题的时候,不会对其他数据造成影响
- 具有一定的 解耦合 作用
微博 Timeline
- 每个用户都拥有属于自己的 Timeline(微博列表),现需要分页展示文章列表
- 此时便可以考虑使用列表,因为列表不但是有序的,且支持按照索引范围获取元素
实例理解
- 每篇微博使用 哈希结构存储
- 此处包含三个属性(title、timestamp、content)
hmset mblog:1 title xx timestamp 1476536196 content xxxxx ... hmset mblog:n title xx timestamp 1476536196 content xxxxx
- 向用户 Timeline 添加微博,使用 List 类型
- 此处使用 user:<uid>:mblogs 作为微博的键
lpush user:1:mblogs mblog:2 mblog:4 ... lpush user:k:mblogs mblog:n
- 分页获取用户的 Timeline
- 此处假设获取用户1 的前 5 篇微博
keylist = lrange user:1:mblogs 0 4 for key in keylist {hgetall key }问题一:
- 当前一页中有多少数据是不确定,所以有可能会导致 for 循环比较大
- 从而会触发多次 hgetall 命令,即多次 网络请求
解决方法:
- 使用 pipeline(流水线、管道)
- 虽然此处是多个 Redis 命令,但是通过 pipeline 我们可以将这些命令合并成一个 网络请求 进行通信
- 由此可以大大降低 客户端 和 服务器 之间的交互次数
问题二:
- lrange 在列表两端表现较好,获取列表中间的元素表现较差
解决方案:
- 将文章对应的 list 进行切分
- 假设某用户发布了 1w 篇微博,则 list 的长度为 1w
- 如果将这 1w 篇微博拆分成 10 份,即 每份1k 篇微博
- 此时如果想获取第 5k 篇左右的微博
- 即直接找到第五个列表,进行遍历即可
- 通过这样的拆分方式便能降低单个 list 的长度,并加快中间位置元素的查询速度
栈 & 队列
- 同侧存取(lpush+lpop 或 rpush+rpop)为栈
- 异侧存取(lpush+rpop 或 rpush+lpop)为队列
相关文章:
2023.12.28 关于 Redis 数据类型 List 内部编码、应用场景
目录 List 编码方式 早期版本 现今版本 List 实际应用 多表之间的关联关系 消息队列 频道(多列表)消息队列 微博 Timeline 栈 & 队列 List 编码方式 早期版本 早期版本 List 类型的内部编码方式有两种 ziplist(压缩列表…...
uni-app page新建以及page外观配置
锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…...
问题:执行conda init 提示 No action taken,然后无法正确激活环境
执行完下面代码后, conda activate base 报错,提示先执行conda init,于是再执行下面代码 conda init发现还报错提示提示 No action taken。 解决方法: 打开一个新的终端窗口,您应该就可以正常使用conda命令。(把其…...
SpringBoot 增量/瘦身部署jar 包
背景 SpringBoot 项目的部署一般采用全量jar 包方式部署相关项目,如果我们对相关的Contrller\Service\Dao\Mapper 层进行相关业务调整就需要重新编译全量jar 包(包大小约为200M左右)实在太麻烦了。 本文:重点讲解使用SpringBoot 的增量/瘦身…...
AI客服的评分机制及自动化测试
智能客服的评分机制及自动化测试 使用pytest来编写智能客服的测试框架: 准备一个CSV文件来存储测试用例和预期结果。编写测试脚本,其中包含测试用例的读取、发送请求、评分逻辑和结果验证。使用pytest断言来验证测试结果。 首先安装pytest和requests库…...
【Matlab】ELM极限学习机时序预测算法
资源下载: https://download.csdn.net/download/vvoennvv/88681649 一,概述 ELM(Extreme Learning Machine)是一种单层前馈神经网络结构,与传统神经网络不同的是,ELM的隐层神经元权重以及偏置都是随机产生的…...
m3u8网络视频文件下载方法
在windows下,使用命令行cmd的命令下载m3u8视频文件并保存为mp4文件。 1.下载ffmpeg,访问FFmpeg官方网站:https://www.ffmpeg.org/进行下载 ffmpeg下载,安装,操作说明 https://blog.csdn.net/m0_53157282/article/det…...
相机内参标定理论篇------张正友标定法
一、为什么做相机标定? 标定是为了得到相机坐标系下的点和图像像素点的映射关系,为摄影几何、计算机视觉等应用做准备。 二、为什么需要张正友标定法? 张正友标定法使手工标定相机成为可能,使相机标定不再需要精密的设备帮助。…...
鸿蒙 Window 环境的搭建
鸿蒙操作系统是国内自研的新一代的智能终端操作系统,支持多种终端设备部署,能够适配不同类别的硬件资源和功能需求。是一款面向万物互联的全场景分布式操作系统。 下载、安装与配置 DevEco Studio支持Windows系统和macOS系统 Windows系统配置华为官方推…...
新一代大语言模型在Amazon Bedrock引领人工智能潮流
亚马逊Bedrock平台推出全新Amazon Titan大语言模型,为大型数据集预处理提供强大支持。亚马逊云科技开发者大会演讲重点介绍了Amazon Titan在文本大语言模型领域的创新,以及如何通过Bedrock平台实现定制化应用。 亚马逊Bedrock平台的主要产品经理Brent S…...
kafka实现延迟消息
背景 我们知道消息中间件mq是支持延迟消息的发送功能的,但是kafka不支持这种直接的用法,所以我们需要独立实现这个功能,以下是在kafka中实现消息延时投递功能的一种方案 kafka实现延时消息 主要的思路是增加一个检测服务,这个检…...
python+django高校教材共享管理系统PyCharm 项目
本中原工学院教材共享平台采用的数据库是mysql,使用nodejs技术开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。系统所要实现的功能分析,对于现在网络方便的管理&…...
三子棋(c语言)
前言: 三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小,三子棋在很多时候会出现和…...
09.kubernetes 部署calico / flannel网络插件
脚本中实现了 calico 和 flannel 这两种主流的网络插件,选择其中一种部署即可 1、calico calico架构 Calico是一个三层的虚拟网络解决方案,它把每个节点都当作虚拟路由器(vRouter),并把每个节点上的Pod都当作是节点路由器后的一个终端设备并为其分配一个IP地址。各节点…...
【DevOps 工具链】搭建 项目管理软件 禅道
文章目录 1、简介2、环境要求3、搭建部署环境3.1. 安装Apache服务3.2. 安装PHP环境(以php7.0为例 )3.3. 安装MySQL服务 4、搭建禅道4.1、下载解压4.2、 配置4.2.1、 启动4.2.2、自启动4.2.3、确认是否开机启动 5、成功安装 1、简介 禅道是国产开源项目管…...
ES6的默认参数和rest参数
✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…...
深入理解WPF MVVM:探索数据绑定与命令的优雅之道
引言: WPF(Windows Presentation Foundation)是一种用于创建富客户端应用程序的框架,而MVVM(Model-View-ViewModel)则是一种在WPF中使用的架构模式。MVVM提供了一种优雅的方式来组织和管理应用程序的代码&a…...
ssrf之gopher协议的使用和配置,以及需要注意的细节
gopher协议 目录 gopher协议 (1)安装一个cn (2)使用Gopher协议发送一个请求,环境为:nc起一个监听,curl发送gopher请求 (3)使用curl发送http请求,命令为 …...
SVN下载安装(服务器与客户端)
1.下载 服务器下载:Download | VisualSVN Server 客户端下载:自行查找 2. 服务器安装 双击执行 运行 下一步 同意下一步 下一步 选中安装目录 3. 客户端安装 双击执行 下一步 4. 服务器创建仓库 5. 服务器创建用户 6. 客户端获取资源 文件夹右键...
SpringIOC之ApplicationObjectSupport
博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...






