
四.redis中级
1.Pipeline
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:
- 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
- 服务端处理命令,并将结果返回给客户端。
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
好处:
可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。
2. 缓存雪崩
大片key在同一时间失效,请求全落到数据库了,db挂掉了。
解决:过期时间设置随机值或者热点数据设置永不过期。
3. 缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,用户不断发起请求压垮数据库。
解决:
- 在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。
- 布隆过滤器:利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。
4. 缓存击穿
跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
解决:设置热点数据永远不过期。或者加上互斥锁就能搞定
五.redis集群
1. 主从
解决读写分离的问题。分为主库 master、从库 slave。一般主库可以写数据,从库只读自动同步主库更新的数据。集群情况下,有节点宕机会导致请求不可用;主机宕机可能会导致数据不一致;从机重启同步数据需要考虑主机的 io 压力。生产环境建议使用哨兵和cluster方法
2. 哨兵
Redis Sentinel,哨兵机制,解决主从节点高可用的问题。监控主从服务器运行状态;检测到 master 宕机时,会发布消息进行选举,自动将 slave 提升为 master
总结下哨兵组件的主要功能:
- 集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
- 消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
- 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
- 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
3. Cluster
Redis Cluster,分布式解决方案,解决单点故障与扩展性以及哨兵机制中每台 Redis 服务器都存储相同的数据浪费内存的问题。实现了 Redis 的分布式存储,也就是每台 Redis 节点上存储不同的内容
redis哈希槽:redis 集群没有使用一致性 hash,而是引入了哈希槽的概念。
redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 算法计算的结果,对 16384 取模后放到对应的编号在 0-16383 之间的哈希槽,集群的每个节点负责一部分哈希槽
4.一些问题
(1)Redis集群方案不可用的情况?
- 集群主库半数宕机(根据 failover 原理,fail 掉一个主需要一半以上主都投票通过才可以)
- 集群某一节点的主从全数宕机
(2)Redis 集群会有写操作丢失吗?
- 过期 key 被清理
- 最大内存不足,导致 Redis 自动清理部分 key 以节省空间
- 主库故障后自动重启,从库自动同步
- 单独的主备方案,网络不稳定触发哨兵的自动切换主从节点,切换期间会有数据丢失
(3)Redis集群之间是如何复制?
- 2.8 版以前,Redis 通过同步(sync)和指令传播(command propagate)两个操作完成同步
- 同步(sync):将从节点的数据库状态更新至与主节点的数据库状态一致
- 指令传播(command propagate):主节点数据被修改,会主动向从节点发送执行的写指令,从节点执行之后,两个节点数据状态又保持一致
- 2.8 版开始新增 PSYNC 指令,PSYNC 具有两种模式:
- 完整重同步(full resynchronization),与 SYNC 过程基本一致
- 部分重同步(partial resynchronization),借助复制偏移量、复制积压缓冲区、服务器运行 ID ,完成主从节点断开连接后,从节点重连主节点后,条件允许,主节点将连接断开期间执行的写指令发送给从节点,从节点接收并执行写指令,将数据库更新至主节点当前状态
(4)Redis集群支持最大节点数是多少?
16384 个。原因如下:
Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 算法计算的结果,对 16384 取模后放到对应的编号在 0-16383 之间的哈希槽,集群的每个节点负责一部分哈希槽