K-V 存储与Redis

文章目

  • 什么是缓存击穿、缓存穿透、缓存雪崩?
    • 缓存雪崩
    • 缓存穿透
      • 如何解决?
    • 缓存击穿
      • 如何解决?
  • Redis 过期策略和内存淘汰策略
  • 怎么实现Redis的高可用?其实就是多点部署
    • 主从模式
    • 哨兵模式
      • 哨兵模式的作用
    • 集群模式
  • MySQL与Redis 如何保证双写一致性
  • Redis 的 Hash 冲突怎么办
  • Redis 与 Memcached 的区别
  • [Gossip 协议详解](https://zhuanlan.zhihu.com/p/162970961)
    • Gossip协议是基于六度分隔理论(Six Degrees of Separation)哲学的体现,简单的来说,一个人通过6个中间人可以认识世界任何人。
    • 传播过程
    • 消息类型 (Anti-Entropy(反熵传播)和Rumor-Mongering(谣言传播))
      • 反熵传播:传播全量数据
      • 谣言传播:传播增量数据
    • 通信方式
  • 轻松理解CAP理论

什么是缓存击穿、缓存穿透、缓存雪崩?

缓存雪崩

指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。

  • 解决其实很简单:
  1. 让其到期时间均匀即可。
  2. 或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。

缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

如何解决?

  1. 如果是非法请求,我们在 API 入口,对参数进行校验,过滤非法值。
  2. 如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。但是如果有写请求进来的话,需要更新缓存哈,以保证缓存一致性,同时,最后给缓存设置适当的过期时间。(业务上比较常用,简单有效)
  3. 使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。(利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return)

缓存击穿

指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db

如何解决?

  1. 使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载 db 数据库数据和设置缓存。否则就去重试获取缓存。
    如果redis里的数据为空的话,就请求数据库,就在请求数据库这一步给它上锁,那么这时候就只有一个线程,能获取到这个锁,所以也就只有一个线程能操作数据库,那么这个时候对数据库的压力就非常小,当查询到这个数据之后,就把缓存重新写到redis中去,其他没有抢到锁的线程,让它先睡几毫秒,然后再重新去redis里面去查询。分布式锁实现方式:redis 和 zookeeper
  2. “永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。

Redis 过期策略和内存淘汰策略

彻底弄懂Redis的内存淘汰策略

Redis单机数据库的实现,持久化以及过期淘汰策略

怎么实现Redis的高可用?其实就是多点部署

通过三种模式实现:

  • 主从模式
  • 哨兵模式
  • 集群模式

主从模式

主节点负责读写,从节点只负责读操作。主从节点会进行数据同步,机制就是主从同步机制。

主从同步机制有两种:全量复制,增量复制。一般当 slave 第一次启动连接 master,或者认为是第一次连接,就采用全量复制,全量复制流程如下:
K-V 存储与Redis_第1张图片
这里的 AOF 写命令,就可以等价于 epoll 中的 overlist 。如果后续再发生更新,那就是增量
更新
操作。

  • replicationFeedSlaves 函数:把用户执行的命令发送到所有的slave节点,让slave节点执行。
  1. 判断用户执行的命令是否有数据更新
  2. 判断 slave节点是否为空

哨兵模式

主从模式中,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址。显然,多数业务场景都不能接受这种故障处理方式。Redis 从 2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。

哨兵模式,由一个或多个Sentinel实例组成的Sentinel系统,它可以监视所有的Redis主节点和从节点,并在被监视的主节点进入下线状态时,自动将下线主服务器属下的某个从节点升级为新的主节点。但是呢,一个哨兵进程对Redis节点进行监控,就可能会出现问题(单点问题),因此,可以使用多个哨兵来进行监控Redis节点,并且各个哨兵之间还会进行监控。
K-V 存储与Redis_第2张图片

哨兵模式的作用

  • 发送命令,等待Redis服务器(包括主服务器和从服务器)返回监控其运行状态;
  • 哨兵监测到主节点宕机,会自动将从节点切换成主节点,然后通过发布订阅模式通知其他的从节点,修改配置文件,让它们切换主机。
  • 哨兵之间还会相互监控,从而达到高可用。

集群模式

哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,并且不好在线扩容。因此,Cluster集群应运而生,它在 Redis3.0 加入的,实现了 Redis 的分布式存储。对数据进行分片,也就是说每台Redis节点上存储不同的内容,来解决在线扩容的问题。并且,它也提供复制和故障转移的功能。

节点之间使用 Gossip 协议通信,交换的信息内容包括节点出现故障、新节点加入、主从节点变更信息、slot信息等等。常用的Gossip消息分为4种,分别是:ping、pong、meet、fail。

使用:Hash Slot 插槽算法
Redis 集群的数据分布之分片

MySQL与Redis 如何保证双写一致性

  • 缓存延时双删
  • 删除缓存重试机制
  • 读取biglog异步删除缓存

Redis 的 Hash 冲突怎么办

  • 链式解决
  • 渐进式 rehash

Redis 与 Memcached 的区别

  • Redis 的键数据类型更多
  • 速度快
  • 可以持久化数据

Gossip 协议详解

Gossip协议是基于六度分隔理论(Six Degrees of Separation)哲学的体现,简单的来说,一个人通过6个中间人可以认识世界任何人。

传播过程

  • 种子节点周期性的散播消息 【假定把周期限定为 1 秒】。
  • 被感染节点随机选择 N 个邻接节点散播消息【假定fan-out(扇出)设置为6,每次最多往6个节点散播】。
  • 节点只接收消息不反馈结果。
  • 每次散播消息都选择尚未发送过的节点进行散播
  • 收到消息的节点不再往发送节点散播:A -> B,那么B进行散播的时候,不再发给 A。

消息类型 (Anti-Entropy(反熵传播)和Rumor-Mongering(谣言传播))

反熵传播:传播全量数据

谣言传播:传播增量数据

通信方式

  • 推送模式、拉取模式、Push/Pull
  1. Push: 节点 A 将数据 (key,value,version) 及对应的版本号推送给 B 节点,B 节点更新 A 中比自己新的数据
  2. Pull:A 仅将数据 key, version 推送给 B,B 将本地比 A 新的数据(Key, value, version)推送给 A,A 更新本地
  3. Push/Pull:与 Pull 类似,只是多了一步,A 再将本地比 B 新的数据推送给 B,B 则更新本地

轻松理解CAP理论

CAP 即:

  • Consistency(一致性):强调的是数据正确且最新
  • Availability(可用性):强调的是系统返回不出错,但是返回的结果不一定是最新的
  • Partition tolerance(分区容忍性):会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。
    K-V 存储与Redis_第3张图片

你可能感兴趣的:(Redis,redis)