Redis中AKF原则的应用

Redis 单机 、单节点、单实例

缺点:1. 单点故障(一台服务如果挂了,整个系统不可用了)
     2. 容量有限
     3. 压力 过大
为了解决 单机的 问题 ,引入了AKF 原则
AKF 
X轴:直接水平复制应用进程来扩展系统(全量,镜像)
Y轴 :  将业务、功能拆分出来扩展系统
Z轴:基于用户信息扩展系统(根据 优先级、逻辑拆分)

在这里插入图片描述

通过上面的AKF 拆分 一遍多后,带来了数据一致性问题
解决方案:
1. 同步阻塞方式(所有阶段阻塞直到数据全部一致),强一致性 ,但是强一致性 会破坏可用性(为什么一边多?就是要解决可用性问题的,这里就违背初衷了);
2. 异步方式  
     1. 弱一致性。容忍数据丢失一部分
     2. 最终一致性 (在最终一致性前,有可能 从不同的从机上取到不同的数)

在这里插入图片描述

综上,主从复制,HA高可用(哨兵保证高可用) 都是 AKF 中X 轴的,可以解决 单点故障 和 压力过大问题,但是 不能解决容量有限问题。解决容量有限问题,有以下几种解决方法:
在这里插入图片描述
在这里插入图片描述

  1. 分业务,逻辑
    Y轴:1. 客户端融入一部分逻辑 进行业务拆分,比如 商品的key 放在redis1 , 用户key 放在 reids2 …

  2. 数据分片(sharding 分片)
    但是 如果 业务已经 拆不开了,但是数据还是很大 ,这个时候 可以 采用数据分片方案。
    2-1. 客户端加 算法 hash + 取模 ,弊端 :取模的数必须固定,否则会造成全局洗牌,这样会印象分布式下的扩展性。
    2-2 . 客户端 加 算法 random(随机),但是 随机放进去后,没办法找到取出来。这种 方式 主要适用场景 是 消息队列(消息太多,消费不及时时,用多台redis做缓冲,相当于 kafka) ,放的时候 lpush, 取的时候 lpop;
    2-3. 客户端加 算法 kemate (一致性哈希,没有取模,key和node 都参与计算,规划出一个环形哈希环,数据经过 hash 映射 找到 距离最近的 redis服务器的物理节点)。
    优点:新增一个redis 服务 物理节点,可以分担其他节点压力,不会造成全局洗牌
    缺点:新增节点造成一小部分数据不能命中。
    造成问题: 击穿,压到数据库。
    解决方案:去取离我最近的2个物理节点,没取到 再去 数据库。这种方式 稍显笨拙,增加代码复杂度。但是 也有可能算了半天 ,结果 key失效了等等问题,所以 哈希环这种 方式 更倾向于作为缓存,而不是数据库,否则会因为解决一个问题 而又出现 其他的各种问题,不值得。
    补充知识点:加多个虚拟节点,比如 有两台redis 服务器, 每台redis做hash时,加上10个数做hash,这样环上就从原来的两个物理节点变成20 个物理节点了,可以解决数据的倾斜问题。

集群模式,redis的链接成本很高,为了解决这个问题 ,可以加入代理层。

用 代理层解决redis 的链接成本很高问题

在这里插入图片描述
这里的 代理 可以使用predixy (predixy 是一款 高性能 全特征redis代理,支持 redis-sentinel 和 redis-cluster)、 twemproxy (twemproxy 里面 可以很方便的设置 取模,随机,一致性哈希 等算法)、codis 、redis-cerberus 等

如果前面 客户端并发很高,一个proxy 扛不住的时候,可以 对 proxy 做集群,如果怕代理 也出现问题,可以在代理前面 再加一层 LVS, 对LVS做一个主备,主备之间可以 用 keepalived 来管理, 而且 keepalived 除了管理 LVS 外,还可以 监控 代理。
为什么要再 代理 前面加 lvs ?
因为,多台代理有多个ip , LVS 有一个 VIP 可以 固定一个ip地址,这样 物理 后端多么复杂,对客户端来说 都是 透明的,客户端只需要记住一个地址。
在这里插入图片描述

上面的 sharding分区 中 ,数据分块的三种方式 的弊端 是 都不能做数据库用(多加redis服务时,算法都会有影响),为了解决这个问题,可以使用 预分区 的概念

预分区 就是 刚开始数据分区时 用一个较大是数 去 取模,然后 再 redis 中加上 槽位(哈希槽)的 概念。

比如刚开始 只有 两个redis服务,取模的时候 取10的模,模数值的范围 0,1,2,3…9 ,那 redis1 中 放 模数为 0,1,2,3,4 的 key, redis2 中 放 模数为 5, 6,7,8,9 的key ,如果 再加一个 redis , 那 就只需要 让 redis1 移出来 2 个槽位 给redis3, 让 redis 2 也移出来 2个槽位 给 redis3 即可。

新增redis 移动槽位后,怎么 知道 如何 去哪一台 redis 上 找数据呢?redis 中的 cluster模式 解决了这个问题。cluster 模型 是一种 无主模型,客户端想连谁连谁,客户端连到 某个redis之后,如果这个redis没有,它会让 客户端 再跳转到 另一个 redis 去。

给 每个 redis 上 都加 上 之前 取模的算法和映射关系 ,这样每个 redis 除了知道自己 有哪些key 外,还知道 其他的 key 分布在 哪个redis 上。 比如 ,在 client get k1 , 直接 请求 到 redis2 上了,如果 redis2中有 就直接返回结果,如果 没有 就 用 它里面 维护的 那个 取模算法 算出 这个 key 分布在 哪一个 redis 上,然后 让 client 重定向到 那个 redis 去取值。

无论是上面 哪种分治模型(数据分治),聚合操作很难实现,例如 如果数据在不同的redis , 事务, 或者对 两个list 取交集 等 很难实现, 尽量把 需要做事务的 key 放在 同一个redis 中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值