Redis常用数据类型深度解析:从理论到最佳实践
Redis常用数据类型深度解析:从理论到最佳实践
- 一、引言
- 二、Redis数据类型全景图
- 三、核心数据类型详解
- **1. String(字符串)**
- **2. Hash(哈希表)**
- **3. List(列表)**
- **4. Set(集合)**
- **5. Sorted Set(有序集合)**
- **6. Bitmap(位图)**
- **7. HyperLogLog(基数统计)**
- **8. Geospatial(地理空间)**
- **9. Stream(流)**
- 四、选型决策树
- 五、性能优化建议
- 六、总结
一、引言
Redis(Remote Dictionary Server)作为高性能的键值存储系统,凭借其丰富的数据类型和原子性操作,成为现代分布式系统中不可或缺的组件。其核心优势在于**“为不同场景提供最合适的数据结构”**。本文将深入剖析Redis的9种常用数据类型,结合实际场景,揭示它们的底层原理与最佳实践。
二、Redis数据类型全景图
Redis支持的数据类型可归纳为以下9类:
- String(字符串)
- Hash(哈希表)
- List(列表)
- Set(集合)
- Sorted Set(有序集合)
- Bitmap(位图)
- HyperLogLog(基数统计)
- Geospatial(地理空间)
- Stream(流)
三、核心数据类型详解
1. String(字符串)
结构:二进制安全的字符串,最大512MB。
核心命令:
SET key value [EX seconds] # 设置键值(带过期时间)
GET key # 获取值
INCR key # 原子递增
APPEND key value # 追加字符串
应用场景:
- 缓存加速:存储用户会话、页面缓存
- 计数器:文章阅读量(
INCR
) - 分布式锁:
SET key uuid NX EX 30
注意事项: - 大字符串(>10KB)可能导致内存碎片
- 使用
MSET/MGET
批量操作减少网络开销
2. Hash(哈希表)
结构:键值对集合,适合存储对象。
核心命令:
HSET user:1000 name "John" age 30 # 设置多个字段
HGET user:1000 name # 获取单个字段
HGETALL user:1000 # 获取所有字段
HINCRBY user:1000 score 5 # 字段值递增
应用场景:
- 用户画像:存储用户的姓名、年龄、积分等属性
- 商品信息:商品详情的多字段存储
优势: - 相比JSON字符串,可独立操作字段,节省网络带宽
- 内存优化:使用
ziplist
编码(小哈希)减少内存占用
3. List(列表)
结构:双向链表,支持头部和尾部操作。
核心命令:
LPUSH news:latest 1001 # 头部插入
RPOP orders # 尾部弹出
LRANGE chat:room1 0 10 # 获取范围元素
BLPOP task_queue 30 # 阻塞式弹出(队列)
应用场景:
- 消息队列:
LPUSH
+BRPOP
实现生产者-消费者模型 - 最新列表:存储最新的50条新闻(配合
LTRIM
) - 分页查询:按时间轴展示用户动态
陷阱: - 避免超长列表(>1000元素)导致查询性能下降
- 优先使用
LPUSH/RPOP
而非随机访问(LINDEX
复杂度O(n))
4. Set(集合)
结构:无序且唯一的元素集合。
核心命令:
SADD tags:article:1001 tech redis # 添加元素
SINTER user:1000:tags user:1001:tags # 求交集
SISMEMBER tags:article:1001 redis # 判断成员存在性
应用场景:
- 标签系统:文章标签、用户兴趣标记
- 共同好友:
SINTER
计算两个用户的共同好友 - UV统计:存储访问用户ID(自动去重)
优化技巧: - 小集合使用
intset
编码节省内存 - 大数据集合操作(如
SUNION
)可能阻塞服务端,建议在从节点执行
5. Sorted Set(有序集合)
结构:元素关联一个分数(score),按分数排序。
核心命令:
ZADD leaderboard 95 "user:A" # 添加带分数元素
ZRANGE leaderboard 0 9 WITHSCORES # 获取Top10
ZRANK leaderboard "user:A" # 获取排名
ZREVRANGEBYSCORE leaderboard 100 80 # 按分数范围查询
应用场景:
- 实时排行榜:游戏积分排行榜、热搜榜单
- 延迟队列:用分数存储执行时间戳,定时轮询
- 范围查询:查找价格在$50-$100的商品
底层结构: - 结合
跳跃表(SkipList)
和哈希表
实现高效范围查询和单点访问
6. Bitmap(位图)
结构:基于String的位操作,支持按位存储布尔值。
核心命令:
SETBIT user:sign:1000 20231015 1 # 记录签到
BITCOUNT user:sign:1000 # 统计签到总数
BITOP AND result user:sign:1000 user:sign:1001 # 位运算
应用场景:
- 用户签到:每日签到状态记录
- 特征标记:标记用户是否具备某些属性(如VIP、已实名)
- 实时统计:统计活跃用户数(
BITCOUNT
)
优势: - 极端压缩存储:1亿用户签到仅需12MB内存(1bit/day)
7. HyperLogLog(基数统计)
结构:概率型数据结构,用于估算集合基数(唯一元素数量)。
核心命令:
PFADD ip:20231015 192.168.1.1 # 添加元素
PFCOUNT ip:20231015 # 估算唯一IP数
PFMERGE ip:total ip:20231015 ip:20231016 # 合并统计
应用场景:
- UV统计:统计每日独立访客(误差约0.81%)
- 大数据去重:统计全网热搜词条数
特点: - 固定使用12KB内存,可计算接近2^64个元素的基数
- 结果非精确,适用于允许误差的大数据场景
8. Geospatial(地理空间)
结构:基于Sorted Set存储经纬度,支持地理位置计算。
核心命令:
GEOADD cities 116.405285 39.904989 "北京" # 添加坐标
GEORADIUS cities 116.40 39.90 100 km WITHCOORD # 附近100km城市
GEOHASH cities "北京" # 获取地理哈希值
应用场景:
- 附近的人:查找用户周围5公里的商家
- 路径规划:计算两个坐标的直线距离(
GEODIST
)
底层实现: - 使用
GEOHASH
将经纬度编码为Sorted Set的Score值
9. Stream(流)
结构:日志型数据结构,支持多消费者组和消息回溯。
核心命令:
XADD order_stream * user_id 1001 amount 99.5 # 添加消息
XREAD COUNT 10 STREAMS order_stream 0 # 读取消息
XGROUP CREATE order_stream group1 $ # 创建消费者组
应用场景:
- 消息队列:替代Kafka实现轻量级消息队列
- 事件溯源:记录用户操作日志(支持按时间查询)
核心功能: - 消息ID自动生成(时间戳+序列号)
- 消费者组实现负载均衡和消息确认(ACK)
四、选型决策树
如何选择数据类型?通过以下问题快速决策:
- 是否需要排序? → 是 → Sorted Set
- 是否需要去重? → 是 → Set或HyperLogLog
- 是否存储对象? → 是 → Hash
- 是否频繁追加数据? → 是 → List或Stream
- 是否涉及位操作? → 是 → Bitmap
五、性能优化建议
- 监控内存使用:定期执行
MEMORY USAGE key
分析大Key - 避免Big Key:单个String不超过10KB,集合元素不超过5000
- 选择高效编码:小数据使用
ziplist
、intset
等紧凑结构 - 批处理操作:使用
Pipeline
减少网络往返时间 - 设置过期时间:通过
EXPIRE
避免数据无限增长
六、总结
Redis的每种数据类型都是为特定场景量身定制的工具:
- String是瑞士军刀,但切忌滥用
- Hash/Set/Sorted Set处理结构化数据
- Bitmap/HyperLogLog以极小内存解决统计难题
- Stream构建可靠消息流
正确选择数据类型,可使性能提升10倍以上。记住:“没有最好的结构,只有最合适的结构”。未来,随着Redis模块化的发展(如RedisGraph、RedisJSON),更多场景将被覆盖,但核心数据类型始终是构建高效系统的基石。
相关文章:
Redis常用数据类型深度解析:从理论到最佳实践
Redis常用数据类型深度解析:从理论到最佳实践 一、引言二、Redis数据类型全景图三、核心数据类型详解**1. String(字符串)****2. Hash(哈希表)****3. List(列表)****4. Set(集合&…...
DeepSeek-V3 模型更新,加量不加价
DeepSeek V3-0324 是 DeepSeek V3 系列的重要升级版本,虽然被官方称为「小版本迭代」,但其在技术能力、开源策略和用户体验上均有显著提升。以下是主要新特性功能和核心变化: 推理能力 基准测试性能显著提升: MMLU-Pro࿱…...
Vue项目的 Sass 全局基础样式格式化方案,包含常见元素的样式重置
步骤 1:创建全局样式文件 在项目中创建文件:src/assets/scss/global.scss 内容如下: // 全局盒模型设定(边框计入宽高) *, *::before, *::after {box-sizing: border-box;margin: 0;padding: 0; }// 基础元素样式重置…...
【Spring篇】Spring的生命周期
一、Bean 生命周期的核心阶段 1. 实例化(Instantiation) • 触发时机:容器启动时(单例 Bean)或请求时(原型 Bean)。 • 实现方式: 通过反射(Class.newInstance() 或构造…...
Qt中通过QLabel实时显示图像
Qt中的QLabel控件用于显示文本或图像,不提供用户交互功能。以下测试代码用于从内置摄像头获取图像并实时显示: Widgets_Test.h: class Widgets_Test : public QMainWindow {Q_OBJECTpublic:Widgets_Test(QWidget *parent nullptr);~Widgets…...
[数据结构]1.时间复杂度和空间复杂度
这里写目录标题 1. 算法复杂度2. 时间复杂度2.1 执行次数2.2 大O渐进表示法2.3 常见时间复杂度计算eg1eg2eg3eg4eg5eg6eg7eg8eg9 3. 空间复杂度eg1eg2eg3eg4 4. 常见复杂度对比5. 复杂度练习eg1 1. 算法复杂度 衡量一个算法的好坏,一般是从时间空间两个维度来衡量&…...
【每日算法】Day 6-1:哈希表从入门到实战——高频算法题(C++实现)
摘要 :掌握高频数据结构!今日深入解析哈希表的核心原理与设计实现,结合冲突解决策略与大厂高频真题,彻底掌握O(1)时间复杂度的数据访问技术。 一、哈希表核心思想 哈希表(Hash Table) 是一种基于键值对的…...
物联网平台架构介绍
物联网是连接物理设备、传感器、软件等的网络系统,使设备能够自动收集、交换和处理数据,实现智能化识别、定位、跟踪、监控和管理。随着物联网技术的飞速发展,物联网平台架构的设计变得至关重要,它决定了物联网系统的性能、可扩展…...
TCP/IP三次握手的过程,为什么要3次?
一:过程 第一次(SYN): 客户端发送一个带有SYN标志的TCP报文段给服务器,设置SYN1,并携带初始序列号Seqx(随机值),进入SYN_SENT状态。等待服务器相应。 第二次(…...
开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(四)
一、前言 语音转文本技术具有重要价值。它能提高信息记录和处理的效率,使人们可以快速将语音内容转换为可编辑、可存储的文本形式,方便后续查阅和分析。在教育领域,可帮助学生更好地记录课堂重点;在办公场景中,能简化会议记录工作。同时,该技术也为残障人士提供了便利,让…...
Qt开发:QInputDialog的使用
文章目录 一、QInputDialog的介绍二、 QInputDialog的基本用法三、使用 QInputDialog的实例四、QInputDialog的信号与槽 一、QInputDialog的介绍 QInputDialog 是 Qt 提供的一个对话框类,用于获取用户输入的文本、整数或浮点数。它提供了简单易用的静态方法和可定制…...
【系统架构设计师】软件质量管理
目录 1. 说明2. 软件质量保证2.1 说明2.2 质量保证的主要目标2.3 目标2.4 主要作用2.5 主要任务 3. 软件质量保证3.1 说明3.2 ISO 90003.3 CMM 4. 例题4.1 例题1 1. 说明 1.软件质量就是软件与明确地和隐含地定义的需求相一致的程度,更具体地说,软件质量…...
医院挂号预约小程序|基于微信小程序的医院挂号预约系统设计与实现(源码+数据库+文档)
医院挂号预约小程序 目录 基于微信小程序的医院挂号预约系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序用户端 2、系统服务端 (1) 用户管理 (2)医院管理 (3)医生管理 …...
UE4-UE5虚幻引擎,前置学习一--Console日志输出经常崩溃,有什么好的解决办法
有些差异 这么牛逼的引擎,居然有这种入门级别的问题,一触发清理,大概率(80%)会崩溃 无论虚幻5还是UE4都有这个问题,挺烦人的 实在忍不了了,这次,今天 就想问问有什么好的处理方法么?&#x…...
javaSE.多维数组
1 final 引用类型 final int[] arr 继承Object 的引用类型,不能改变引用的对象 存的其实是引用 数组类型数组,其实存的是引用 int [][] arr new int[][] { {1,2,3}, {4,5,6} };int [] a arr[0]; int [] b arr[1];...
Linux输入系统应用编程
什么是输入系统 Linux 输入系统是处理用户输入设备(如键盘、鼠标、触摸屏、游戏手柄等)的软件架构。在应用编程层面,它提供了与这些输入设备交互的接口。 主要组成部分 输入设备驱动层:直接与硬件交互的驱动程序 输入核心层:内核中的输入子…...
leetcode11.盛水最多的容器
双指针问题,指向前后边界,每次只移动高度较小的那个 class Solution { public:int maxArea(vector<int>& height) {int leftIndex0,rightIndexheight.size()-1;int result0;while(leftIndex<rightIndex){resultmax(result,(rightIndex-lef…...
ngx_http_index_loc_conf_t
定义在 src\http\modules\ngx_http_index_module.c typedef struct {ngx_array_t *indices; /* array of ngx_http_index_t */size_t max_index_len; } ngx_http_index_loc_conf_t; ngx_http_index_loc_conf_t 是 Nginx 中用于管理 index 指…...
[C++面试] 你了解视图吗?
一、入门 1、什么是 C 视图(View)?请简要说明其概念和用途 它提供了对序列(如数组、容器等)的非拥有性、只读或可写的访问。(就像是个透明的放大镜,它能让你去看一组数据,但它自己…...
NetMizer-日志管理系统-远程命令执行漏洞挖掘
漏洞描述:NetMizer 日志管理系统 cmd.php中存在远程命令执行漏洞,攻击者通过传入 cmd参数即可命令执行 1.fofa搜素语句 title"NetMizer 日志管理系统" 2.漏洞验证 网站页面 验证POC /data/manage/cmd.php?cmdid...
UDP通信实现
一、Socket简介(套接字) TCP/IP 五层网络模型的应用层编程接口称为Socket API, Socket( 套接字 ) ,它是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换…...
Browserlist 使用指南:应对浏览器兼容性问题的解决方案
前言 在前端开发中,我们经常需要处理各种不同的浏览器兼容性问题。每个浏览器的版本众多,处理这些问题可能会让人感到头疼。幸运的是,有一个名为 Browserlist 的工具可以大大简化这项工作。本文将介绍 Browserlist 的作用和使用方法…...
[蓝桥杯 2023 省 A] 异或和之和
题目来自洛谷网站: 暴力思路: 先进性预处理,找到每个点位置的前缀异或和,在枚举区间。 暴力代码: #include<bits/stdc.h> #define int long long using namespace std; const int N 1e520;int n; int arr[N…...
ABC391题解
A 算法标签: 模拟 #include <iostream> #include <algorithm> #include <cstring> #include <map>using namespace std;const int N 8; map<string, string> mp;int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);mp.insert({…...
React - LineChart组件编写(用于查看每日流水图表)
一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …...
什么情况下需要使用二级指针
当你需要一个函数修改另一个函数中的指针变量时(改变指针变量的指向),你必须传递该指针的地址,也就是"指向指针的指针"。这是C语言中实现"引用传递"效果的标准方式。 函数A中声明了一个结构体指针变量mys&am…...
动态规划(8.下降路径最小和(medium))
题目链接:931. 下降路径最小和 - 力扣(LeetCode) 解法: 关于这⼀类题,由于我们做过类似的,因此「状态表示」以及「状态转移」是比较容易分析出来的。 比较难的地方可能就是对于「边界条件」的处理。 1. 状…...
自动插入分号机制
📜 JS 自动分号插入(ASI)机制详解 自动分号插入(Automatic Semicolon Insertion)是 JavaScript 中一个独特而重要的特性,它影响着代码的解析和执行方式。 🌟 核心概念速览 ASI 引擎自动补充分号 当 JavaScript 解析器遇到特定语法情况时&a…...
C语言贪吃蛇实现
When the night gets dark,remember that the Sun is also a star. 当夜幕降临时,请记住太阳也是一颗星星。 ————《去月球海滩篇》 目录 文章目录 一、《贪吃蛇》游戏介绍 二、WIN32部分接口简单介绍 2.1 控制台窗口大小设置 2.2 命令行窗口的名称的变更 2…...
基于数据挖掘的网络入侵检测关键技术研究
标题:基于数据挖掘的网络入侵检测关键技术研究 内容:1.摘要 随着互联网的迅速发展,网络安全问题日益严峻,网络入侵行为对个人、企业和国家的信息安全构成了巨大威胁。本文的目的是研究基于数据挖掘的网络入侵检测关键技术,以提高网络入侵检测…...
git上传大文件到远程仓库中
git 上传大文件报错 上传大文件文件到远程仓库上面,出现错误(gitee-100M,github-50M) remote: error: File: f422c55c723a183a1944cbec840c0171042c8251 135 MB, exceeds 100.00 MB. 意思是单个文件超过100M导致上传失败。 安装LFS curl…...
计算机网络基础之三种交换技术及其性能分析
一. 交换技术基础 1. 三种交换技术 电路交换:用于电话网络报文交换:用于电报网络分组交换:用于现代计算机网络 2. 人类历史上的通信网络 #mermaid-svg-AeGvrkUbCkicFOIo {font-family:"trebuchet ms",verdana,arial,sans-serif;…...
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机解决方案技术路线感知模块运动模块导航模块补充 实验结果 ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机 行走控制器不能依赖于稳定和周期性的步态,而必…...
【AI学习笔记】AI造神时代的潘式理论与智能进化
背景前摇: 周会分享选题,决定选择这篇华为蓝军部长潘少钦先生所著的文章,原题目为《AI如此强大,我是否要改行?》。选择这篇文章的理由是,其不仅有充实扎实的AI基础知识作为铺垫,更具有独特鲜明…...
CVE-2021-45232未授权接口练习笔记
CVE-2021-45232 是 Apache APISIX Dashboard 中的一个严重权限漏洞,类似于攻击者无需密码即可拿到整个网关系统的“万能钥匙”。攻击者利用此漏洞,可直接操控网关流量转发规则,甚至远程执行代码,引发服务器沦陷。 默认账户密码导致…...
远场分量(平面波角谱)与倏逝波
远场分量(平面波角谱)与倏逝波的详细解释 在光学和电磁学中,远场分量(平面波角谱)和倏逝波是描述光场传播特性的两个核心概念,尤其在衍射理论、近场光学和超分辨成像中至关重要。以下是它们的物理意义、数…...
修改Flutter工程中Android项目minSdkVersion配置
Flutter项目开发过程中,根据模板自动生成.android项目,其中app>build.gradle中minSdkVersion的值是19,但是依赖了一个三方库,它的Android sdk 最小版本只支持到21,运行报错如下: 我们可以手动修改.andro…...
后端返回了 xlsx 文件流,前端怎么下载处理
当后端返回一个 .xlsx 文件流时,前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。 实现步骤 发送请求获取文件流: 使用 fetch 或 axios 等工具向后端发送请求,确保响应类型设置为 blob(二进制数据流)。 创建…...
js中async+await+promise的用法及常见问题总结
文章目录 概况asyncawaitPromise总结常见问题 概况 在ts/js中,async 和 await 是用于简化异步操作的关键字,一般与Promise联用(不理解Promise可以看一下这篇《JS中Promise用法(简要说明)》)。它们的核心作…...
单纯形法之大M法
1. 问题背景与标准化 在求解某些线性规划问题时,往往难以直接找到初始的基本可行解。特别是当约束中存在等式或 “≥” 类型的不等式时,我们需要引入人工变量来构造一个初始可行解。 考虑如下标准形式问题(假设为最大化问题)&am…...
一个数组分为两个sum相等的数组
vector,问是否可以拆成两部分,使其两部分的总和相同,用代码写一下 #include <iostream> #include <vector>using namespace std;bool canPartition(vector<int>& nums) {int sum 0;for (int num : nums) {sum num;…...
Socket如何实现客户端和服务器间的通信
使用Socket实现客户端和服务器间的通信 Socket是一种网络编程接口,广泛用于实现客户端和服务器之间的通信。在网络应用程序中,Socket提供了一种简单而强大的机制来建立和管理网络连接。本文将详细介绍如何使用Python的Socket模块来实现基本的客户端和服…...
崖山数据库(YashanDB)部署全流程详解
文章目录 引言 第1部分:环境准备 服务器要求 初始环境调整 第2部分:yasboot工具介绍 yasboot核心功能 yasboot进程架构 第3部分:YashanDB安装步骤 创建安装用户 目录规划 命令行安装流程 步骤1:生成配置文件 步骤2&a…...
07_JavaScript函数作用域_递归
目录 一、作用域(重点) 二、变量的使用规则 (重点) 2.1 访问规则 2.2 赋值规则 三、递归函数 (难点) 了解 四、对象 4.1 对象的创建 一、作用域(重点) 什么是作用域 ? 作用…...
基于大模型预测的初治菌阳肺结核诊疗方案研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 二、初治菌阳肺结核概述 2.1 疾病定义与病理机制 2.2 流行病学特征 2.3 传统诊疗方法与局限性 三、大模型在初治菌阳肺结核预测中的应用原理 3.1 大模型技术简介 3.2 数据收集与预处理 3.3 模型构建与训练 3.4 模型…...
C# Modbus TCP/IP学习记录
Modbus协议中,角色分为主站(Mater)、从站(Slave);数据类型分为线圈(Coil)、离散输入(Input)、保持寄存器(HoldingRegister)、输入寄存…...
斜线、短横、空格,三种分隔日期的优雅解析(Python | DeepSeek)
标准日期解析操作,str.replace链式如灵蛇蜿蜒,三元表达式像空灵仙家妙法。 笔记模板由python脚本于2025-03-25 22:32:24创建,本篇笔记适合三元表达式、字符串操作修习的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值:在…...
Skynet 中 snlua 服务启动整体流程分析
前言: 在 Skynet 中,Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里,而能够将 Lua 环境嵌入到 Skynet 框架下,并与 Skynet 消息调度机制完美结合,正是 snlua 服务所承担的核心功能。 本文将…...
RWA代币化崛起中的香港机遇:数字金融新枢纽的破局之道
引言:全球资产代币化浪潮中的香港坐标 在2025年全球金融数字化重构的关键节点,RWA(现实世界资产代币化)市场以年均740%的增速重塑价值流动规则。香港凭借独特的政策创新、跨境枢纽优势及庞大的资产储备,正从传统金融中…...
Docker Compose介绍
基本概念 Docker-Compose是Docker官方的开源项目,负责实现对docker容器集群的快速编排。 可以这么理解,docker compose是docker提出的一个工具软件,可以管理多个docker容器组成一个应用,只需要编写一个YAML格式的配置文件docker…...