likes
comments
collection
share

Redis 核心原理串讲(下),架构演进之高扩展

作者站长头像
站长
· 阅读数 6

Redis 核心原理总览(全局篇)

正文开始之前,我们先思考下「如何造一个缓存组件?」

该片段是 Redis 原理知识地图,请仔细阅读!(基于 redis6.2

1)最小可用版:

  • 要快:缓存最核心的目的是支持快速访问,硬件层面一般选择「内存」
  • 远程访问:作为缓存组件,要支持单独部署,可以利用现有开源网络库,也可以自己实现。

大部分语言都提供了内存操作,条件 1 很容易满足,条件 2 要支持远程访问,就要和 TCP 连接打交道,我们可以利用开源的网络库,比如 C 版的 libc 等。

原理篇第一部分:将围绕一条请求探索 redis 高性能的核心原理。

2)进阶版:

第一步我们已经有了缓存组件最基本的雏形,并且已经达到了高性能的处理能力,这个时候我们可能有更多的诉求:

  • 稳定:即 尽可能不丢数据、无故障或故障后快速恢复、自动处理故障的能力
  • 可扩展:单机容量或者 QPS 达到上限,支持水平扩展能力。

原理篇第二部分:将围绕 redis 架构演进进行剖析。

全局知识地图:

Redis 核心原理串讲(下),架构演进之高扩展

前言

本文围绕「架构主线」来透视 Redis「高可靠」的核心原理,在正文开始之前,我们先思考几个问题:

  • 数据要如何切分,在扩缩容过程迁移量最小?
  • 分片元数据如何维护?中心化 or 去中心化?
  • 如何平滑的从单机版升级到 cluster 集群版

如果你对以上问题了然于胸,这篇文章读起来很容易,权当帮你串联、回顾知识点,如果不是很清楚也没关系,且听我细细道来!


一、数据分片

1、集群?

即使硬件技术按照「摩尔定律」的速度快速升级,单机容量也很难支撑当前的海量数据场景。

想当年,集群的概念还未盛行时,那些优秀的工程师抠破脑袋的去升级硬件,效果你懂得 ...

当有人提出使用多台机器承载数据的方案后,多年的梦魇被打破,集群的时代 ---- 来了。

集群数据分配?

选定一种规则,将数据尽可能均匀的分配到集群的各台机器上,当然在这里插入图片描述 ,也要方便「取出来」

很多人应该想到了 ----「哈希取模」,所有数据经过哈希函数一计算,得到机器编号,数据就存在该机器上,当然,取数据也是相同的方式。

2、分片?

分片,顾名思义,将完整数据集分成多块(分片),然后将这些分片分配至集群中的各台机器上。

对集群的管理,本质也是对分片的管理。

3、分片固定?

上面的分片思路是正确的,但还有致命缺点 ---- 当集群新增或者减少机器节点时,整个数据就乱了,所有数据要重新进行分配,效率极低。

解决方案:即「固定分片」,不管集群机器数量如何变化,只要分片数量不变动,数据与分片的映射关系就不变。

当集群机器数量变更时,我们只需要将变更的机器上的分片进行迁移即可,不会存在大规模「重新洗牌」的局面。

我画了张图,你可以参考下:

Redis 核心原理串讲(下),架构演进之高扩展

值得注意的是,机器与数据没有直接关系,只和分片有直接关联。

4、元数据

你应该注意到了,集群中分片与机器的关系十分重要,所谓 “林子大了什么鸟都有”,同样,机器多了什么故障都有可能出现:

  • 机器变更
  • 分片均衡/迁移
  • ...

只要发生了变化,都需要维护这套映射关系。

这套映射关系,我们也习惯称为「元数据」,在分布式集群中应该是非常常见。可以这样说,很多分布式机制、算法都是围绕这套元数据展开

业界有两种常见的元数据维护方案:

  • 中心化:由中心化的节点来维护,所有请求都先到中心节点,该节点查询元数据后告诉你该访问集群中的具体节点。
  • 去中心化:不需要中心节点,那元数据谁来维护?

值得提一下:集群中的每个节点都维护一套,一般客户端也要缓存一份,这么多份数据,最大的问题是什么?一致性,也就是涉及到一些「分布式一致性协议」选择了

二、集群

目前市面上 Redis 有两种主流的集群方案,本质区别:多元数据的管理采用「中心化」还是「去中性化」的方案。

1、代理集群

代表:社区集群解决方案

官方集群解决方案出来的晚一些,那会,市场对集群需求性大,衍生出很多开源的代理集群解决方案。

采用典型的「中心化」方案,所有请求先经过代理节点,代理节点维护了「元数据」映射关系,也就知道这个请求应该请求哪个集群节点。

1)社区早期集群方案:Codis、Temproxy:

这些方案不具备 HA(高可用)的能力,所以需要单独部署 HA,我画了张图,你可以参考下:

Redis 核心原理串讲(下),架构演进之高扩展

2)predixy 代理:支持多种 redis 运行模式, 对客户端友好:

这种方案会更加友好,也是目前比较流行的方案,你可以这样理解:

为了解耦「客户端」与「服务端」的关联(各种 SDK ...),使用代理这种中间节点(你可以想想现实中的房产中介),繁琐的工作交给代理节点来完成。

然后,客户端就像连接单个节点一样,连接到代理节点,而代理节点的背后可以是:

  • 单机部署
  • 主从 + 哨兵集群的高可用部署
  • Redis Cluster 官方集群部署

是不是很方便,各大云厂商大多都是这种模式。我画了张图,你可以参考下:

Redis 核心原理串讲(下),架构演进之高扩展

2、分片集群

redis cluster 是官方提供的分布式集群解决方案,相对于单机版 redis 拥有更高的存储容量和更高的吞吐量。

换句话说,海量存储的终极方案,就是搞集群,多机器。简单总结三大特性:

  • 去中心化
  • Gossip 协议
  • 内置 HA(高可用)

我画了张图,你可以参考下:

Redis 核心原理串讲(下),架构演进之高扩展

去中心化:

redis cluster 集群采用「去中心化」的方式,集群中的每个节点以及客户端都会存储(或者说缓存)一份相同的元数据信息。

由于元数据可能会更新,因此整个集群采用 Gossip 协议进行数据交换,该协议的特点是 一传十、十传百的类似于流言的方式,集群节点越多,完成一次全同步需要的时间越长

所以,你会看到这种去中心化的方案,本质还是受限于集群节点总体大小,比如,很难支撑超超大集群规模(1w+节点、10w+节点),官方建议是不超过 1000 节点。

基于此,在业务上做拆分,使用不同的 redis 集群也是不错的方案。

高可用:

Cluster 集群,内置 HA 的能力,简单理解,集群内自有一套故障检测规则,并且是分布式的,这样才能避免主观下线因素。

内部的所有主节点成为最终的裁判,拥有故障判决权和新主节点的投票选举权,基于此,也就不再需要额外的哨兵来参与故障转移(其实这部分工作就相当于哨兵的工作)

对于高可用,我们首先要有足够的副本(从节点),然后是主节点(拥有选举权)以及要合适的故障检测机制、共识选举算法、执行故障转移等。

3、代理 + 分片集群

特点:

对客户端友好、无历史包袱

为啥需要这种模式?

你想想,Cluster 集群的特殊型在于「去中心化」,客户端也需要缓存元数据 ...

因此,客户端的 SDK 要做更多的工作来适配,当你启用 Cluster 集群时,你的所有客户端 SDK 是不是都要升级?成本就大了。

这个时候有一种平滑的操作,像使用单机版的 redis 一样,是不是很 Nice?

我大致画了张图,你可以参考下:

Redis 核心原理串讲(下),架构演进之高扩展

值得注意的是,集群中每个节点只存一部分数据,所以有些 redis 命令可能有些限制

三、生产实践

拿生产上使用的 Redis 例子来看看,为了方便,我们直接使用了 腾讯云的 Redis,其主要提供了两种架构:

标准架构:

代理节点 + (主从 + HA 高可用集群 ---- 类似于哨兵):

Redis 核心原理串讲(下),架构演进之高扩展

集群架构:

代理节点 + Redis Cluster 分片集群:

Redis 核心原理串讲(下),架构演进之高扩展

你可以看到的是,腾讯云提供给的这两种模式都属于我们介绍的:「代理 + Redis 服务」:

  • 代理 + 单机高可用模式
  • 代理 + 集群模式

对客户端十分友好,你只需要连接到一个代理节点即可,后面的 HA、集群你都不需要关心 !!!


总结

一台机器容量不够了或者 QPS 撑不住了?

  • 代理集群:社区版,如 twemproxy、codis,在代理层做逻辑分片、路由等,节点间无交流。
  • 分片集群:官方版,无中心化,节点间采用 Gossip 协议通信,官方建议集群节点不超过 1000
  • 代理 + 分片集群:对客户端友好, 推荐使用官方版集群,另外可以在官方版集群架构下使用一层代理,对客户端支持友好。

好,我们再来回顾下文章开头提到的几个问题,看看你是否都已经清楚了呢?

  • ❓ 数据要如何切分,在扩缩容过程迁移量最小?
  • ❓ 分片元数据如何维护?中心化 or 去中心化?
  • ❓ 如何平滑的从单机版升级到 cluster 集群版?
转载自:https://juejin.cn/post/7303398827225514003
评论
请登录