概述
用途场景
Redis
最常见的用途之一是作为缓存系统,用于加速应用程序性能- 缓存经常访问的数据(如用户信息、页面内容、热点数据等)
- 减少数据库的压力,降低查询响应时间
1 2 |
SET user:1234 '{"name": "Alice", "age": 25}' EX 3600 # 设置 1 小时过期 GET user:1234 # 快速获取用户数据 |
Redis
可以用来实现 分布式锁,以解决分布式系统中的并发问题- 防止多个服务或进程同时修改同一个资源
- 确保资源访问的互斥性
1 |
SET lock:resource "locked" NX EX 10 # 设置 10 秒的分布式锁 |
Redis
可以用来存储用户会话(Session
),尤其在需要共享会话的分布式系统中Web
应用中存储登录状态、购物车信息等- 不同服务器之间共享会话数据
Redis
的原子操作(如INCR
、DECR
)非常适合实现 实时计数器- 统计页面访问量(
PV
/UV
) - 统计用户操作(如点赞、评论数等)
- 限流控制,如限制某个接口的每秒请求次数
- 统计页面访问量(
1 |
INCR page:home:views # 增加页面访问计数 |
Redis
支持 发布/订阅(Pub
/Sub
) 和基于列表(List
)的队列模式,用于实现消息队列- 构建简单的消息队列系统
- 在微服务中实现组件之间的异步通信
Redis
的 有序集合(Sorted Set
) 非常适合实现排行榜- 游戏中的玩家积分排行榜
- 电商平台的商品热度排名
1 2 3 |
ZADD leaderboard 100 player1 ZADD leaderboard 200 player2 ZRANGE leaderboard 0 -1 WITHSCORES # 获取排行榜 |
Redis
的键值可以设置过期时间,用于临时数据存储或延迟任务调度- 设置验证码有效期
- 处理延迟任务,例如延迟消息投递
1 |
SET captcha:123456 "valid" EX 300 # 设置验证码有效期为 5 分钟 |
Redis
提供了Geo
功能,可以存储和查询地理位置相关的数据- 计算两点之间的距离
- 查找某点附近的地点(如外卖配送站、用户位置等)
1 2 3 |
GEOADD locations 13.361389 38.115556 "Palermo" GEOADD locations 15.087269 37.502669 "Catania" GEODIST locations "Palermo" "Catania" km # 计算距离 |
Redis
提供了Streams
数据结构,支持日志、事件流等实时数据处理- 实时日志收集
- 事件流分析
1 2 |
XADD mystream * field1 value1 XREAD COUNT 2 STREAMS mystream 0 # 读取事件流 |
Redis
可以用作轻量级的配置中心,存储应用程序的配置信息- 存储动态配置信息,方便应用读取和更新
- 支持集中管理配置
特点
- 高性能
Redis
是以 内存 为基础的数据存储,读写性能极高
- 丰富的数据结构
Redis
支持多种灵活的数据结构,满足不同场景需求
- 内存存储与持久化支持
Redis
是一个内存数据库,但它也支持将数据持久化到磁盘
- 单线程模型
Redis
是单线程模型(从Redis 6.0
开始支持多线程IO
)
- 支持分布式
Redis
可以轻松部署为分布式架构,支持以下模式- 主从复制
- 高可用
- 分布式集群
- 发布/订阅机制
Redis
内置了简单的 消息系统
- 数据过期与自动清理
Redis
支持对每个键设置过期时间(TTL
)
Lua
脚本支持Redis
支持Lua
脚本,可以将多个操作组合成原子操作
- 高可用和故障恢复
Redis
提供高可用机制,确保服务在出现故障时仍可用
- 易用性
Redis
的安装和使用非常简单,且支持多种客户端库- 几乎支持所有主流编程语言(如
Python
、Java
、C++
)
- 扩展功能
Redis
不仅是一个内存数据库,还支持多种扩展功能
数据结构
- 字符串
- 单个键值对的值可以是字符串、整数或浮点数,最大支持
512MB
- 单个键值对的值可以是字符串、整数或浮点数,最大支持
- 哈希(
Hash
)- 存储键值对集合的映射(类似于
Python
的字典) - 适合存储对象的属性
- 存储键值对集合的映射(类似于
1 2 |
HSET user:1001 name "Alice" age "30" HGET user:1001 name |
- 列表(
List
)- 存储有序的字符串列表(双向链表)
- 支持从头部和尾部插入/弹出元素
1 2 3 |
LPUSH tasks "Task1" RPUSH tasks "Task2" LRANGE tasks 0 -1 |
- 集合(
Set
)- 存储无序、唯一的字符串集合
- 支持集合运算(交集、并集、差集)
1 2 |
SADD myset "value1" "value2" SINTER set1 set2 |
- 有序集合(
Sorted Set
)- 类似集合,但每个元素附带一个分数,用于排序
- 元素唯一,分数可以重复
1 2 3 |
ZADD leaderboard 100 player1 ZADD leaderboard 200 player2 ZRANGE leaderboard 0 -1 WITHSCORES |
- 位图(
Bitmap
)- 操作二进制位的数组
1 2 |
SETBIT user:signin 5 1 GETBIT user:signin 5 |
HyperLogLog
- 用于估算集合中不重复元素的数量,允许误差
- 内存占用固定(
~12 KB
)
1 2 |
PFADD visitors "user1" "user2" PFCOUNT visitors |
- 地理位置(
Geo
)- 存储地理位置信息(经纬度)
- 支持计算两地之间的距离
- 支持查询指定半径内的元素
1 2 |
GEOADD locations 13.361389 38.115556 "Palermo" GEODIST locations "Palermo" "Catania" |
- 流(
Stream
)- 用于日志和事件流处理的高级数据结构
- 类似消息队列,但提供更多功能
1 2 |
XADD mystream * field1 value1 XREAD STREAMS mystream 0 |
一些操作
启动客户端
1 |
redis-cli |
退出客户端
1 |
exit |
连接到不同的 Redis 实例
- 比如远程服务器
1 2 3 |
redis-cli -h 192.168.1.100 -p 6379 redis-cli -h 192.168.1.100 -p 6379 -a yourpassword |
设置一个键值对
1 |
SET mykey "Hello, Redis" |
获取一个键的值
1 |
GET mykey |
删除一个键
1 |
DEL mykey |
检查键是否存在
1 |
EXISTS mykey |
列出所有的键
1 |
KEYS * |
设置一个过期时间(单位:秒)
1 |
SETEX mykey 10 "Hello, Redis with expiration" |
查看当前数据库的键数量
1 |
DBSIZE |
清空当前数据库的所有键
1 |
FLUSHDB |
哈希(Hash)
简述
- 哈希类型是
Redis
支持的数据结构之一,用来存储键值对
设置哈希字段
1 |
HSET myhash field1 "value1" |
获取哈希字段的值
1 |
HGET myhash field1 |
获取哈希的所有字段和值
1 |
HGETALL myhash |
列表(List)
简述
- 列表是
Redis
中的另一种数据结构,用于存储一系列有序元素
将元素添加到列表的头部
1 |
LPUSH mylist "item1" |
将元素添加到列表的尾部
1 |
RPUSH mylist "item2" |
获取列表中的所有元素
1 |
LRANGE mylist 0 -1 |
一些问题
发布订阅模式怎么实现
- 订阅阶段
- 客户端
C2
和C3
启动时,通过应用服务器S
调用Redis
的SUBSCRIBE
接口,订阅频道Test
Redis
将这些订阅与客户端的连接(TCP
长连接)关联起来,记录在Redis
内部的“频道-连接映射表”中
- 客户端
- 发布阶段
C1
客户端向服务器程序S
发送请求,要求向频道Test
发布一条消息- 服务器程序
S
调用Redis
的PUBLISH
接口,将消息发布到频道Test
- 消息分发阶段
Redis
检查频道Test
的订阅列表,发现有C2
和C3
的连接订阅了该频道Redis
通过现有的TCP
长连接,将消息立即推送给C2
和C3
关于上面的长连接
- 客户端
C2
和C3
启动时,通过中间的应用服务器与Redis
建立的长连接确实是基于TCP
的通信,并且该连接会一直保持,直到客户端主动断开或连接因其他原因(如网络异常、超时等)被关闭- 一旦连接建立,
Redis
会将这条连接与订阅的频道(如Test
)进行关联 - 之后,
Redis
会通过这条连接向客户端推送该频道的消息
- 一旦连接建立,
队列模式怎么实现
- 一些任务描述(比如一个任务是由
JSON
描述的,包含了发起时间,任务类型,以及其他信息)被添加到Redis
的队列中 - 然后服务器工作线程从队列中取出一条任务描述后,进行解析,然后进行处理
- 关于任务
- 将队列用于存放任务时,不能为队列里面的键值对设置过期时间,但可以为整个队列设置一个过期时间
任务调度怎么实现
Redis
用于任务调度的核心思想就是通过存储任务描述信息(例如订单ID
和JSON
字符串)来管理任务队列- 任务处理系统则从
Redis
中获取这些任务并进行处理
怎么做缓存
Redis
缓存通常用于存储有过期时间的数据,目的是减少对数据库的访问,提高数据的读取速度- 设置过期时间是
Redis
缓存的一大优势,通过设置过期时间,Redis
能够自动清除过期的数据,保持缓存数据的新鲜度
怎么做分布式锁
Redis
做分布式锁的原理是利用Redis
的原子操作来实现跨多个分布式系统的锁机制- 分布式锁常用于多个进程或服务器之间的资源共享和竞争控制,确保在同一时刻只有一个客户端能够获得锁并操作共享资源
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Vim编辑器的操作03/17
- ♥ WinDbg语法规则07/11
- ♥ Git_状况汇总03/19
- ♥ Reading 2021 《查拉图斯特拉如是说》06/16
- ♥ x86_64汇编学习记述二08/07
- ♥ STL_了解05/02
热评文章
- * 暂无