Redis技术梳理
2024-03-18 15:35:06 12 举报
AI智能生成
基础 缓存异常 集群方案 优缺点
作者其他创作
大纲/内容
缓存异常
缓存雪崩
缓存同一时间大面积的失效
过期时间设置随机,防止同一时间大量数据过期现象发生
加锁排队
缓存穿透
缓存和数据库中都没有的数据
接口层增加校验,id<=0的直接拦截
将key-value对写为key-null,缓存有效时间可以设置短点,如30秒。防止反复用同一个id暴力攻击
布隆过滤器判断在不在数据库
哈希表,多次hash
有一定的误识别率和删除困难
所有的Hash函数告诉我们该元素在集合中,才能确定在集合中
缓存击穿
热点数据缓存时间到期
设置热点数据永远不过期
加互斥锁
缓存预热
将相关的缓存数据直接加载到缓存系统
缓存降级
根据一些关键数据进行自动降级,也可以配置开关实现人工降级
Redis出现问题,不去数据库查询,而是直接返回默认值给用户
数据库双写时的数据一致性
先更新数据库,然后再删除缓存
一致性:缓存删除失败,数据不一致
高并发下:A去查突然失效查脏数据,B更新数据库,B写入缓存,A写入缓存->数据不一致
先删除缓存,然后再更新数据库
高并发下:A删除,B读数据库脏数据,B写入,A更新数据库->数据不一致
不更新缓存
有大量冷数据占用资源,用到缓存才去算缓存
集群方案
哨兵模式
集群监控:负责监控 redis master 和 slave
消息通知:如果某个 redis 实例有故障,通知给管理员。
故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
判断一个 master node 是否宕机了,大部分的哨兵都同意,分布式选举
配置中心:故障转移,通知 client 客户端新的 master 地址。
核心知识
至少需要 3 个实例
哨兵 + redis 主从的部署架构,是不保证数据零丢失的,只能保证高可用性。
Cluster 方案(服务端路由查询)
分布式寻址算法
hash 算法(大量缓存重建)
一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡解决数据倾斜问题)
redis cluster 的 hash slot哈希槽 算法 16384
主从架构
每份数据分片会存储在多个互为主从的多节点
多个节点间的数据不保持一致性
先写主节点,再同步到从节点(支持配置为阻塞同步)
当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
扩容时时需要需要把旧节点的数据迁移一部分到新节点
优点
支持动态扩容
具备Sentinel的监控和自动Failover(故障转移)能力
免去了proxy代理的损耗
连接集群中任何一个可用节点
基于客户端分配
采用哈希算法将Redis数据的key进行散列,通过hash函数,特定的key会映射到特定的Redis节点上
Redis实例彼此独立,相互无关联
不支持动态增删节点,每个客户端都需要更新调整
连接不能共享,当应用规模增大时,资源浪费制约优化
基于代理服务器分片
请求到一个代理组件,代理解析客户端的数据,并将请求转发至正确的节点
切换成本低
代理层多了一次转发,性能有所损耗
主从架构
一主多从,主负责写,并且将数据复制到其它的 slave 节点,从节点负责读。所有的读请求全部走从节点。支撑读高并发。
redis replication -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发
核心机制
异步方式复制
发送一个 PSYNC
full resynchronization 全量复制,master 会启动一个后台线程,开始生成一份 RDB 快照文件
将这个 RDB 发送给 slave,slave 会先写入本地磁盘,然后再从本地磁盘加载到内存中
master 会将内存中缓存的写命令发送到 slave
必须开启 master node 的持久化
在 master 宕机重启的时候数据是空的,然后可能一经过复制, slave node 的数据也丢了
从备份中挑选一份 rdb 去恢复 master,这样才能确保启动的时候,是有数据的
lave node 可以自动接管 master node,但也可能 sentinel 还没检测到 master failure,master node 就自动重启了,还是可能导致上面所有的 slave node 数据被清空
分区缺点
涉及多个key的操作通常不会被支持
不能对两个集合求交集
被存储到不同的Redis实例
同时操作多个key,则不能使用Redis事务.
数据处理会非常复杂
必须从不同的Redis实例和主机同时收集RDB / AOF文件
动态扩容或缩容可能非常复
Redis集群在运行时增加或者删除Redis节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。
分布式锁
SETNX SET if Not eXists
当且仅当 key 不存在,将 key 的值设为 value。给定的 key 已经存在,则 SETNX 不做任何动作
解决 Redis 的并发竞争 Key
分布式锁(zookeeper 和 redis 都可以实现分布式锁)
每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。
判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。
同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。完成业务流程后,删除对应的子节点释放锁。
Redlock
互斥访问,即永远只有一个 client 能拿到锁
最终 client 都可能拿到锁,不会出现死锁的情况
只要大部分 Redis 节点存活就可以正常提供服务
优缺点
优点
读写性能优异
支持数据持久化
支持事务,所有操作都是原子性的,支持对几个操作合并后的原子性执行。
数据结构丰富
主从复制,进行读写分离
缺点
较小数据量的高性能操作和运算
不具备自动容错和恢复功能
需要等待机器重启或者手动切换前端的IP才能恢复
主机宕机,宕机前有部分数据未能及时同步到从机
降低了系统的可用性
较难支持在线扩容
不用 map/guava
本地缓存
生命周期随着 jvm 的销毁而结束
每个实例都需要各自保存一份缓存,缓存不具有一致性
快的原因
完全基于内存
查找和操作的时间复杂度都是O(1)
数据结构简单
单线程
避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
多路 I/O 复用模型,非阻塞 IO
memcached
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
都支持分布式
基础
数据类型
STRING
LIST
SET
HASH
ZSET
jumplist
多层链表+二分法
应用场景
计数器
缓存
会话缓存
统一存储多台应用服务器的会话信息
查找表
DNS 记录
消息队列(发布/订阅功能)
List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息
分布式锁
SETNX
随机value,比较相同才删除解锁
持久化
RDB(默认)快照
dump.rdb
fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化
比 AOF 的启动效率更高
AOF
将Redis执行的每次写命令记录到单独的日志文件中
会优先选择AOF恢复
每进行一次 命令操作就记录到 aof 文件中一次
AOF 文件比 RDB 文件大,且恢复速度慢
rdb 启动效率低
AOF文件比RDB更新频率高,优先使用AOF还原数据
过期键的删除策略
用于处理过期的缓存数据
定时过期
占用大量的CPU资源
惰性过期 用
当访问一个key
定期过期 用
扫描一定数量的数据库的expires字典中一定数量的key
过期时间和永久有效 EXPIRE和PERSIST
内存淘汰策略
allkeys-lru
用于处理内存不足时的需要申请额外空间的数据
线程模型
文件事件处理器
多个套接字、IO多路复用程序、文件事件分派器(单线程)、事件处理器
使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字
根据套接字目前执行的任务来为套接字关联不同的事件处理器
事务
要么全部被执行,要么全部都不执行
MULTI、EXEC、DISCARD、WATCH等一组命令的集合,一个事务中所有命令都会被序列化
WATCH
为 Redis 事务提供 check-and-set (CAS)行为。 可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。
DISCARD
客户端可以清空事务队列,并放弃执行事务
三个阶段
事务开始 MULTI
命令不会立即被执行,而是被放到一个队列中
命令入队
事务执行 EXEC
执行所有事务块内的命令
不支持回滚
在事务失败时不进行回滚,而是继续执行余下的命令
隔离性
单进程程序,并且它保证在执行事务时,不会对事务进行中断
不支持原子性
不保证原子性,且没有回滚
异步队列
使用list类型保存数据信息,rpush生产消息,lpop消费消息,当lpop没有消息时,可以sleep一段时间,然后再检查有没有信息,
如果不想sleep的话,可以使用blpop, 在没有信息的时候,会一直阻塞,直到信息的到来。
redis可以通过pub/sub主题订阅模式实现一个生产者,多个消费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。
0 条评论
下一页