Redis基础入门

文章目录

  • Redis基础入门
    • [一、 Redis 基础特性与架构认知](#一、 Redis 基础特性与架构认知)
      • [1. NoSQL 数据库分类及特点](#1. NoSQL 数据库分类及特点)
      • [2. Redis 核心高性能密码](#2. Redis 核心高性能密码)
      • [3. 全局通用基础命令与帮助系统](#3. 全局通用基础命令与帮助系统)
    • [二、 核心数据类型详解与底层原理](#二、 核心数据类型详解与底层原理)
      • [(一) String 字符串结构](#(一) String 字符串结构)
        • [1. 底层原理:SDS (Simple Dynamic String)](#1. 底层原理:SDS (Simple Dynamic String))
        • [2. 常用基础命令全集](#2. 常用基础命令全集)
        • [3. 生产环境应用场景深度解析](#3. 生产环境应用场景深度解析)
      • [(二) Hash 哈希结构](#(二) Hash 哈希结构)
        • [1. 底层原理:ziplist (压缩列表) / listpack → \rightarrow → hashtable (哈希表)](#1. 底层原理:ziplist (压缩列表) / listpack → \rightarrow → hashtable (哈希表))
        • [2. 常用基础命令全集](#2. 常用基础命令全集)
        • [3. 购物车场景深化与优缺点](#3. 购物车场景深化与优缺点)
      • [(三) List 列表类型](#(三) List 列表类型)
        • [1. 底层原理:quicklist (快速列表)](#1. 底层原理:quicklist (快速列表))
        • [2. 常用基础命令全集](#2. 常用基础命令全集)
        • [3. List 模拟常见数据结构与缺陷](#3. List 模拟常见数据结构与缺陷)
      • [(四) Set 集合类型](#(四) Set 集合类型)
        • [1. 特性与底层原理](#1. 特性与底层原理)
        • [2. 常用基础命令全集](#2. 常用基础命令全集)
        • [3. 生产环境大 key 警告](#3. 生产环境大 key 警告)
      • [(五) ZSet 有序集合类型](#(五) ZSet 有序集合类型)
        • [1. 特性与底层原理](#1. 特性与底层原理)
        • [2. 常用基础命令全集](#2. 常用基础命令全集)
        • [3. 经典排行榜场景深度设计](#3. 经典排行榜场景深度设计)

Redis基础入门

一、 Redis 基础特性与架构认知

1. NoSQL 数据库分类及特点

  • 键值型 (Key-Value): Redis。极高的读写性能,常用于缓存、分布式锁。
  • 列族跨度 (Column-Family): HBase。基于 Google Bigtable,适合海量数据存储与实时随机读写。
  • 图形数据库 (Graph): Neo4j。专注于社交网络、风控等复杂关系网络的图遍历。
  • 文档型 (Document): MongoDBElasticsearch
  • MongoDB: 灵活的 JSON 文档结构,适合 Schema 经常变动的业务。
  • Elasticsearch : 基于倒排索引 (Inverted Index),专为全文检索和大数据分析而生。

2. Redis 核心高性能密码

  • 纯内存操作: 所有数据存放在内存中,内存响应时间约为 100 纳秒,这是 Redis 极高的根本原因。

  • 单线程模型 (核心机制): Redis 的核心网络 I/O 和键值对读写是由单个线程完成的。

  • 优势: 避免了不必要的上下文切换和锁竞争。

  • 注意 : Redis 6.0 之后引入了 多线程 I/O,但它只用来处理网络数据的读写和协议解析,执行命令的核心依然是单线程。

  • I/O 多路复用 (Multiplexing): 采用 epoll 机制,使单个线程能够高效监听数万个客户端连接,不阻塞在某一个特定的网络连接上。

3. 全局通用基础命令与帮助系统

bash 复制代码
# 查看当前数据库中的所有 Key(线上生产环境严禁使用,会造成单线程卡死)
KEYS *

# 检查指定 Key 是否存在。返回 1 表示存在,0 表示不存在
EXISTS key

# 返回 Key 所存储的数据类型(如 string, hash, list, set, zset)
TYPE key

# 删除一个或多个指定 Key。返回成功删除的个数
DEL key [key ...]

# 清空当前数据库中的所有 key
FLUSHDB

# 清空所有数据库的所有 key(全删,生产环境高危命令)
FLUSHALL

# 退出当前客户端连接
QUIT
万能帮助系统 (help)
bash 复制代码
# 查看某个分组下的所有命令(例如 help @string, help @hash)
help @<group>

# 查看具体某个命令的详细语法帮助(例如 help set)
help <command>

# 在命令行连续按 Tab 键,可循环切换查看可用的帮助主题
help <tab>

二、 核心数据类型详解与底层原理

(一) String 字符串结构

1. 底层原理:SDS (Simple Dynamic String)

Redis 没有直接使用 C 语言的传统字符串(以 \0 结尾的字符数组),而是自己构建了简单动态字符串 (SDS)

为什么用 SDS?

  • 常数复杂度获取长度: C 字符串需要 O ( n ) O(n) O(n) 遍历,SDS 内部维护了 len 属性,获取长度只需 O ( 1 ) O(1) O(1)。
  • 杜绝缓冲区溢出: SDS 在拼接字符串时会先检查空间是否足够,不足则自动扩容。
  • 减少内存重分配次数: 采用空间预分配和惰性空间释放机制。
  • 二进制安全: 允许存储包含空字符 \0 的图片、音频等二进制数据。
2. 常用基础命令全集
bash 复制代码
# 存储一个键值对。EX/PX:设置秒级/毫秒级过期时间;NX:键不存在才设置;XX:键存在才设置
SET key value [EX seconds|PX milliseconds] [NX|XX]

# 获取指定 Key 的 Value。若不存在返回 nil
GET key

# 批量存储多个键值对(原子操作)
MSET key value [key value ...]

# 批量获取多个 Key 的 Value
MGET key [key ...]

# 存入一个不存在的字符串键值对。存在则什么都不做(成功返回 1,失败返回 0)
SETNX key value

# 设置一个新键值对,并直接指定过期时间(秒)
SETEX key seconds value

# 给一个现有的 Key 设置过期时间(秒)
EXPIRE key seconds

# 查看 Key 的剩余生存时间(秒)。返回 -1 表示永不过期,-2 表示 Key 不存在
TTL key

# 【原子加减命令】将 Key 储存的数字值加 1。如果 Key 不存在,会先初始化为 0 再加 1
INCR key

# 将 Key 储存的数字值减 1
DECR key

# 将 Key 储存的数字值加上指定的整型增量值
INCRBY key increment

# 将 Key 储存的数字值减去指定的整型减量值
DECRBY key decrement

# 对浮点数进行原子增加(String 也能存浮点数)
INCRBYFLOAT key increment
3. 生产环境应用场景深度解析
  • 单值缓存: SET key valueGET key

  • 对象缓存(两种主流设计):

  • 方式一(整存整取 JSON)SET user:1 '{"name":"roy","balance":1888}'

  • 方式二(高频更新字段)MSET user:1:name roy user:1:balance 1888 → \rightarrow → 获取时 MGET user:1:name user:1:balance

  • 分布式锁的完整闭环:

  • 加锁(带超时防死锁)SET lock:product:10001 random_value EX 10 NX

  • 高阶注意点 : 释放锁时不能直接 DEL。如果 A 业务超时,锁自动释放,B 拿到了锁;此时 A 执行完去 DEL,会把 B 的锁删掉。正确做法: 比较 random_value 是否一致,一致再删除,这个复合操作必须使用 Lua 脚本 保证原子性。

  • 大值拆分 (BigKey 规避): String 的 Value 最大为 512MB ,但生产环境建议控制在 10KB 以内,否则会引发网络阻塞和 Redis 变慢。

(二) Hash 哈希结构

1. 底层原理:ziplist (压缩列表) / listpack → \rightarrow → hashtable (哈希表)
  • 当 Hash 的字段少且值小时,为了极端节省内存,底层使用 ziplist(新版本为 listpack),它是一块连续的内存。
  • 当元素个数超过 hash-max-ziplist-entries(默认 512)或某个 Value 大于 hash-max-ziplist-value(默认 64 字节)时,自动转为 hashtable(类似于 Java 的 HashMap,具有 O ( 1 ) O(1) O(1) 复杂度)。
2. 常用基础命令全集
bash 复制代码
# 存储哈希表单个字段的键值对
HSET key field value

# 获取哈希表中指定字段的值
HGET key field

# 仅当哈希表中该字段不存在时才存储
HSETNX key field value

# 批量存储哈希表的多个字段(注:新版 HSET 已支持批量,等同于 HMSET)
HMSET key field value [field value ...]

# 批量获取哈希表多个字段的值
HMGET key field [field ...]

# 删除哈希表中的一个或多个指定字段
HDEL key field [field ...]

# 返回哈希表中字段(field)的数量
HLEN key

# 返回哈希表中所有的键值对(生产环境严禁在大 Key 上执行,若 field 太多会阻塞单线程)
HGETALL key

# 获取哈希表中的所有字段名(field)
HKEYS key

# 获取哈希表中的所有值(value)
HVALS key

# 给哈希表指定字段的数值增加一个整型增量
HINCRBY key field increment

# 增量式迭代获取哈希表内容,生产环境用来代替 HGETALL 的安全命令
HSCAN key cursor [MATCH pattern] [COUNT count]
3. 购物车场景深化与优缺点
  • 用户购物车高级设计:

  • Key: cart:user:1001 (用户ID)

  • Field: 10088 (商品 SkuID) → \rightarrow → Value: 1 (数量)

  • 添加/增加数量 : HINCRBY cart:1001 10088 1

  • 统计商品总数 : HLEN cart:1001

  • 删除商品 : HDEL cart:1001 10088

  • 获取全车商品 : HGETALL cart:1001

  • 优点: 同类数据归类整合,方便管理;相比 String,CPU、内存消耗更小,存储空间更节省。

  • 缺点: 过期时间只能作用在大 key 上,不能给 field 单独设置过期时间;在 Redis 集群架构下不适合大规模使用(容易导致数据倾斜)。

(三) List 列表类型

1. 底层原理:quicklist (快速列表)
  • 老版本底层为 ziplistlinkedlist(双向链表),支持正负索引(正数从 0 开始,负数从 -1 倒序)。
  • 现行版本统一采用 quicklistquicklist 是一个双向链表,但链表中的每个节点都是一个 ziplist。既有链表两端操作快的优势,又避免了普通链表节点前后指针过度占用内存的问题(双端操作性能极高,中间索引操作性能低)。
2. 常用基础命令全集
bash 复制代码
# 从列表表头(左端)插入一个或多个元素
LPUSH key value [value ...]

# 从列表表尾(右端)插入一个或多个元素
RPUSH key value [value ...]

# 移除并返回列表的表头(左端)元素
LPOP key

# 移除并返回列表的表尾(右端)元素
RPOP key

# 获取指定索引区间内的元素(例如 LRANGE list 0 -1 代表获取全部元素)
LRANGE key start stop

# 获取列表的长度
LLEN key

# 【阻塞式命令】表头阻塞弹出。如果队列无元素则进入阻塞等待,timeout 为最大等待时间(秒),设为 0 表示永久阻塞
BLPOP key [key ...] timeout

# 表尾阻塞弹出。长轮询机制,数据一到立刻感知,几乎零延迟
BRPOP key [key ...] timeout
3. List 模拟常见数据结构与缺陷
  • 数据结构组合拳:

  • 栈 (Stack) = LPUSH + LPOP

  • 队列 (Queue) = LPUSH + RPOP

  • 阻塞队列 (MQ) = LPUSH + BRPOP

  • 致命缺陷:

  1. 没有 ACK 机制: 一旦消息通过 RPOP/BRPOP 弹出,如果消费者在处理过程中崩溃,消息就彻底丢失了。
  2. 不支持一条消息多方消费: 一个消息只能被一个消费者 Pop 走。
  • 注意点: 列表最大容量为 2 32 − 1 2^{32}-1 232−1(约 40 亿元素),在实际开发中需要警惕大 Key 问题。

(四) Set 集合类型

1. 特性与底层原理
  • 特性: 元素无序、不可重复。
  • 底层原理(intset → \rightarrow → hashtable): 如果集合内元素都是整数,且数量较少,底层使用 intset(一块连续且高度紧凑的内存)。一旦存入字符串,或者元素数量超标,立刻转为 hashtable(Value 均为 null 的散列表)。
2. 常用基础命令全集
bash 复制代码
# 向集合内存入元素,重复的元素会自动被忽略
SADD key member [member ...]

# 从集合中删除一个或多个元素
SREM key member [member ...]

# 获取集合中的所有元素(无序)
SMEMBERS key

# 获取集合中元素的总个数
SCARD key

# 判断某个元素是否在集合中(返回 1 在,0 不在)
SISMEMBER key member

# 随机从集合中获取指定个数的元素,不删除原集合元素(常用于抽奖不剔除资格)
SRANDMEMBER key [count]

# 随机从集合中弹出指定个数的元素(常用于抽奖且中奖人不能重复中奖)
SPOP key [count]

# 【集合运算命令-交集】计算多个集合的交集
SINTER key [key ...]

# 计算交集并将结果存入新集合 destination 中
SINTERSTORE destination key [key ...]

# 【集合运算命令-并集】计算多个集合的并集
SUNION key [key ...]

# 计算并集并将结果存入新集合
SUNIONSTORE destination key [key ...]

# 【集合运算命令-差集】计算多个集合的差集(注意顺序:以第一个 key 集合为主体)
SDIFF key [key ...]

# 计算差集并将结果存入新集合
SDIFFSTORE destination key [key ...]
3. 生产环境大 key 警告
  • 避坑指南: 集合计算的时间复杂度较高(如交集为 O ( N × M ) O(N \times M) O(N×M))。若集合内元素达到千万级,直接执行交并集运算会导致 Redis 瞬间卡死。
  • 正确实践: 将数据带回客户端(Java/Go)在业务层计算,或者使用 SINTERSTORE 将结果异步存入新集合。

(五) ZSet 有序集合类型

1. 特性与底层原理
  • 特性: 元素不可重复,每个元素关联一个 score(分值),按分值从小到大自动排序。
  • 底层原理(ziplist/listpack → \rightarrow → skiplist + dict):
  • dict (哈希表): 用来建立 member -> score 的映射,保证根据元素找分数达到 O ( 1 ) O(1) O(1)。
  • skiplist (跳跃表): 用于根据分数排序。它通过在普通链表上建立多层索引,实现类似二分查找的效果,检索复杂度为 O ( log ⁡ N ) O(\log N) O(logN)。
2. 常用基础命令全集
bash 复制代码
# 添加一个或多个带分值的元素。如果元素已存在,则更新其分数
ZADD key score member [[score member] ...]

# 从有序集合中删除一个或多个元素
ZREM key member [member ...]

# 获取指定元素的分值
ZSCORE key member

# 给指定元素的分值增加一个增量值(可为负数)
ZINCRBY key increment member

# 获取有序集合中元素的总个数
ZCARD key

# 获取索引区间内的元素。WITHSCORES 连同分数一起返回;REV 代表倒排(从大到小)
ZRANGE key start stop [WITHSCORES] [REV]

# 【集合运算-并集】计算多个有序集合的并集并存入新 Key。numkeys 指定参与计算的 Key 数量
ZUNIONSTORE destkey numkeys key [key ...] [WEIGHTS weight ...] [AGGREGATE SUM|MIN|MAX]

# 【集合运算-交集】计算交集并存入新 Key
ZINTERSTORE destkey numkeys key [key ...] [WEIGHTS weight ...] [AGGREGATE SUM|MIN|MAX]

参数解释: WEIGHTS 可以设置各个集合的乘法权重比;AGGREGATE 可以设置当成员分值重复时,最终分值是求和(SUM)、取最小值(MIN)还是最大值(MAX)。

3. 经典排行榜场景深度设计
  • 多维权重聚合(如:7日榜单合并):
redis 复制代码
# 合并 7 天的每日热点数据,分值求和
ZUNIONSTORE hotNews:7day 7 hotNews:day1 hotNews:day2 hotNews:day3 hotNews:day4 hotNews:day5 hotNews:day6 hotNews:day7 WEIGHTS 1 1 1 1 1 1 1 AGGREGATE SUM

# 合并后展示前十名
ZRANGE hotNews:7day 0 9 WITHSCORES REV
相关推荐
2501_915106321 小时前
深入解析HTTPS抓包原理、中间人攻击及反抓包技术攻防
数据库·网络协议·ios·小程序·https·uni-app·iphone
迷枫7121 小时前
DM8 数据共享集群 DSC 学习总结:共享存储、集群组件与常见误区
数据库·学习
码不停蹄的玄黓1 小时前
MySQL索引类型
数据库·mysql
有想法的py工程师1 小时前
PostgreSQL 设置唯一主键的生产事故复盘与最佳实践
数据库·oracle
或与且与或非1 小时前
postgresql+rabbitmq集群搭建方案
数据库·postgresql·rabbitmq
AllData公司负责人1 小时前
亲测丝滑,体验跃迁|AllData通过集成开源项目Cube-Studio,降低机器学习落地门槛
java·大数据·数据库·人工智能·机器学习·开源·cube-studio
KaMeidebaby2 小时前
卡梅德生物技术快报|抗体的制备与纯化:分子实验实操:番茄 sHSP 重组表达与抗体的制备与纯化工艺
前端·数据库·人工智能·其他·算法·百度·新浪微博
幻灭行度2 小时前
Redis ACL 实现多账号权限隔离
数据库·redis·oracle
Kurisu5752 小时前
深度解析:Go 语言 GMP 调度器模型与内核线程探测
java·数据库·golang