主页

索引

模块索引

搜索页面

存储高可用架构

一个高可用存储方案设计角度:

数据如何复制?
各个节点的职责是什么?
如何应对复制延迟?
如何应对复制中断?

常见的高可用存储架构有:

1. 主备
2. 主从
3. 主主
4. 集群
5. 分区

双机高可用架构

常见的双机高可用架构:

1. 主备
2. 主从
3. 主备/主从切换
4. 主主

主备复制

备注

主备复制是最常见也是最简单的一种存储高可用方案,主备架构中的 “备机” 主要还是起到一个备份作用,并不承担实际的业务读写操作,如果要把备机改为主机,需要人工操作。几乎所有的存储系统都提供了主备复制的功能,例如 MySQL、Redis、MongoDB 等。

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage1.webp

优点:

主要是就是『简单』
对于客户端来说,不需要感知备机的存在
    即使灾难恢复后,原来的备机被人工修改为主机后,
    对于客户端来说,只是认为主机的地址换了而已,无须知道是原来的备机升级为主机。
对于主机和备机来说,双方只需要进行数据复制即可,无须进行状态判断和主备切换这类复杂的操作。

缺点:

备机仅仅只为备份,并没有提供读写操作,硬件成本上有浪费。
故障后需要人工干预,无法自动恢复。
    人工处理的效率是很低的,故障时间会很长
    人工在执行恢复操作的过程易出错,因为这类操作不常见,实际操作可能遇到各种意想不到的问题。

主从复制

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage2.png

与主备复制相比,优点有:

主从复制在主机故障时,读操作相关的业务可以继续运行
主从复制架构的从机提供读操作,发挥了硬件的性能

缺点:

主从复制架构中,客户端需要感知主从关系,并将不同的操作发给不同的机器进行处理,复杂度比主备复制要高
主从复制架构中,从机提供读业务,如果主从复制延迟比较大,业务会因为数据不一致出现问题
故障时需要人工干预

双机切换

主备复制和主从复制方案存在两个共性的问题:

主机故障后,无法进行写操作。
如果主机无法恢复,需要人工指定新的主机角色。

设计关键

  1. 主备间状态判断:

    a. 主要包括两方面:状态传递的渠道,以及状态检测的内容。
    b. 状态传递的渠道:是相互间互相连接,还是第三方仲裁?
    c. 状态检测的内容:例如机器是否掉电、进程是否存在、响应是否缓慢等。
    
  2. 切换决策:

    主要包括几方面:切换时机、切换策略、自动程度。
    a. 切换时机
        什么情况下备机应该升级为主机?
        是机器掉电后备机才升级,还是主机上的进程不存在就升级,
        还是主机响应时间超过 2 秒就升级,还是 3 分钟内主机连续重启 3 次就升级等。
    b. 切换策略
        原来的主机故障恢复后
        要再次切换,确保原来的主机继续做主机,
        还是原来的主机故障恢复后自动成为新的备机?
    c. 自动程度
        切换是完全自动的,还是半自动的?
        例如,系统判断当前需要切换,但需要人工做最终的确认操作(例如,单击一下 “切换” 按钮)。
    
  3. 数据冲突解决:

    当原有故障的主机恢复后,新旧主机之间可能存在数据冲突。
    以上设计点并没有放之四海而皆准的答案,不同的业务要求不一样,
      所以切换方案比复制方案不只是多了一个切换功能那么简单,而是复杂度上升了一个量级。
    形象点来说,如果复制方案的代码是 1000 行,那么切换方案的代码可能就是 10000 行,
      多出来的那 9000 行就是用于实现上面我所讲的 3 个设计点的。
    

常见架构

根据状态传递渠道的不同,常见的主备切换架构有三种形式:

互连式、中介式和模拟式。

互连式架构

备注

故名思议,互连式就是指主备机直接建立状态传递的渠道。

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage3.png

架构图请注意与主备复制架构对比

“状态传递” 的通道,这个通道就是用来传递状态信息的。这个通道的具体实现可以有很多方式:

可以是网络连接(例如,各开一个端口),也可以是非网络连接(用串口线连接)。
可以是主机发送状态给备机,也可以是备机到主机来获取状态信息。
可以和数据复制通道共用,也可以独立一条通道。
状态传递通道可以是一条,也可以是多条,还可以是不同类型的通道混合(例如,网络 + 串口)。

客户端这里也会有一些相应的改变,常见的方式有:

1. 为了切换后不影响客户端的访问,主机和备机之间共享一个对客户端来说唯一的地址。
    例如虚拟 IP,主机需要绑定这个虚拟的 IP。
2. 客户端同时记录主备机的地址,哪个能访问就访问哪个;
    备机虽然能收到客户端的操作请求,但是会直接拒绝,拒绝的原因就是 “备机不对外提供服务”。

主要的缺点在于:

1. 如果状态传递的通道本身有故障
    那么备机也会认为主机故障了从而将自己升级为主机,而此时主机并没有故障,最终就可能出现两个主机。
2. 虽然可以通过增加多个通道来增强状态传递的可靠性,但这样做只是降低了通道故障概率而已
    不能从根本上解决这个缺点,而且通道越多,后续的状态决策会更加复杂,
    因为对备机来说,可能从不同的通道收到了不同甚至矛盾的状态信息。

中介式架构

备注

中介式指的是在主备两者之外引入第三方中介,主备机之间不直接连接,而都去连接中介,并且通过中介来传递状态信息,其架构图如下:

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage4.png

主机和备机不再通过互联通道传递状态信息,而是都将状态上报给中介这一角色

优点:

中介式架构在状态传递和决策上更加简单明了
1. 连接管理更简单
2. 状态决策更简单

缺点:

关键代价就在于如何实现中介本身的高可用。
如果中介自己宕机了,整个系统就进入了双备的状态,写操作相关的业务就不可用了

这就陷入了一个递归的陷阱
https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage5-mongo.png

MongoDB 的 Replica Set 采取的就是这种方式

备注

开源方案已经有比较成熟的中介式解决方案,例如 ZooKeeper 和 Keepalived。

模拟式

备注

模拟式指主备机之间并不传递任何状态数据,而是备机模拟成一个客户端,向主机发起模拟的读写操作,根据读写操作的响应情况来判断主机的状态。

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage6.png

互连式切换架构: 主备机之间只有数据复制通道,而没有状态传递通道,备机通过模拟的读写操作来探测主机的状态,然后根据读写操作的响应情况来进行状态决策。

与互连式切换相比,优点:

实现更加简单,因为省去了状态传递通道的建立和管理工作。

缺点:

因为模拟式读写操作获取的状态信息只有响应信息(例如,HTTP 404,超时、响应时间超过 3 秒等)
没有互连式那样多样(除了响应信息,还可以包含 CPU 负载、I/O 负载、吞吐量、响应时间等)
基于有限的状态来做状态决策,可能出现偏差

主主复制

备注

主主复制指的是两台机器都是主机,互相将数据复制给对方,客户端可以任意挑选其中一台机器进行读写操作

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage7-master-master.png

相比主备切换架构,主主复制架构具有如下特点:

两台都是主机,不存在切换的概念。
客户端无须区分不同角色的主机,随便将读写操作发送给哪台主机都可以。

其独特的复杂性,具体表现在:

如果采取主主复制架构,必须保证数据能够双向复制,而很多数据是不能双向复制的

备注

主主复制架构对数据的设计有严格的要求,一般适合于那些临时性、可丢失、可覆盖的数据场景。例如,用户登录产生的 session 数据(可以重新登录生成)、用户行为的日志数据(可以丢失)、论坛的草稿数据(可以丢失)等

数据集群

根据集群中机器承担的不同角色来划分,集群可以分为两类:

数据集中集群
数据分散集群

1. 数据集中集群

备注

数据集中集群与主备、主从这类架构相似,我们也可以称数据集中集群为 1 主多备或者 1 主多从。虽然架构上是类似的,但由于集群里面的服务器数量更多,导致复杂度整体更高一些

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage8.png

复杂度整体更高一些,具体体现在:

1. 主机如何将数据复制给备机
    主备和主从架构中,只有一条复制通道,而数据集中集群架构中,存在多条复制通道。
    多条复制通道:
      首先: 会增大主机复制的压力,某些场景下需考虑如何降低主机复制压力,或者降低主机复制给正常读写带来的压力
      其次: 多条复制通道可能导致多个备机之间数据不一致,某些场景下需对备机之间的数据一致性进行检查和修正
2. 备机如何检测主机状态
    主备和主从架构中,只有一台备机需要进行主机状态判断。
    在数据集中集群架构中,多台备机都需要对主机状态进行判断,
    而不同的备机判断的结果可能是不同的,如何处理不同备机对主机状态的不同判断,是一个复杂的问题。
3. 主机故障后,如何决定新的主机
    主从架构中,如果主机故障,将备机升级为主机即可;
    而在数据集中集群架构中,有多台备机都可以升级为主机,但实际上只能允许一台备机升级为主机,
    那么究竟选择哪一台备机作为新的主机,备机之间如何协调,这也是一个复杂的问题。

    目前开源的数据集中集群以 ZooKeeper 为典型,
    ZooKeeper 通过 ZAB 算法来解决上述提到的几个问题,但 ZAB 算法的复杂度是很高的。

2. 数据分散集群

备注

数据分散集群指多个服务器组成一个集群,每台服务器都会负责存储一部分数据;同时,为了提升硬件利用率,每台服务器又会备份一部分数据。

数据分散集群的复杂点在于如何将数据分配到不同的服务器上,算法需要考虑这些设计点:

1. 均衡性
算法需要保证服务器上的数据分区基本是均衡的,不能存在某台服务器上的分区数量是另外一台服务器的几倍的情况
2. 容错性
当出现部分服务器故障时,算法需要将原来分配给故障服务器的数据分区分配给其他服务器
3. 可伸缩性
当集群容量不够,扩充新的服务器后,算法能够自动将部分数据分区迁移到新服务器,并保证扩容后所有服务器的均衡性
https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage9-hadoop.png

Hadoop 的实现就是独立的服务器负责数据分区的分配,这台服务器叫作 Namenode。

下面是 Hadoop 官方的解释,能够说明集中式数据分区管理的基本方式:

1. HDFS 采用 master/slave 架构。
    一个 HDFS 集群由一个 Namenode 和一定数目的 Datanodes 组成。
2. Namenode 是一个中心服务器,负责管理文件系统的名字空间(namespace),以及客户端对文件的访问。
3. Datanode 在集群中一般是一个节点一个,负责管理它所在节点上的存储。
    HDFS 暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。
    从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组 Datanode 上。
4. Namenode 执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。
    它也负责确定数据块到具体 Datanode 节点的映射。
    Datanode 负责处理文件系统客户端的读写请求。
    在 Namenode 的统一调度下进行数据块的创建、删除和复制操作。
https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage9-es.png

与 Hadoop 不同的是,Elasticsearch 集群通过选举一台服务器来做数据分区的分配,叫作 master node

其中 master 节点的职责 如下

The master node is responsible for lightweight cluster-wide actions
  such as creating or deleting an index, tracking which nodes are part of the cluster,
  and deciding which shards to allocate to which nodes.
It is important for cluster health to have a stable master node.

两种集群对比

备注

数据分散集群和数据集中集群的不同点在于,数据分散集群中的每台服务器都可以处理读写请求,因此不存在数据集中集群中负责写的主机那样的角色。但在数据分散集群中,必须有一个角色来负责执行数据分配算法,这个角色可以是独立的一台服务器,也可以是集群自己选举出的一台服务器。如果是集群服务器选举出来一台机器承担数据分区分配的职责,则这台服务器一般也会叫作主机,但我们需要知道这里的 “主机” 和数据集中集群中的 “主机”,其职责是有差异的。

备注

数据集中集群架构中,客户端只能将数据写到主机;数据分散集群架构中,客户端可以向任意服务器中读写数据。正是因为这个关键的差异,决定了两种集群的应用场景不同。一般来说,数据集中集群适合数据量不大,集群机器数量不多的场景。例如,ZooKeeper 集群,一般推荐 5 台机器左右,数据量是单台服务器就能够支撑;而数据分散集群,由于其良好的可伸缩性,适合业务数据量巨大、集群机器数量庞大的业务场景。例如,Hadoop 集群、HBase 集群,大规模的集群可以达到上百台甚至上千台服务器。

数据分区

备注

前面我们讨论的存储高可用架构都是基于硬件故障的场景去考虑和设计的,主要考虑当部分硬件可能损坏的情况下系统应该如何处理,但如出现一个城市甚至一个地区的所有基础设施瘫痪的情况。基于硬件故障而设计的高可用架构不再适用,我们需要基于地理级别的故障来设计高可用架构,这就是数据分区架构产生的背景。

设计一个良好的数据分区架构,需要从多方面去考虑:

1. 数据量
    数据量的大小直接决定了分区的规则复杂度。

    例如,使用 MySQL 来存储数据,假设一台 MySQL 存储能力是 500GB,那么
      2TB 的数据就至少需要 4 台 MySQL 服务器;
      而如果数据是 200TB,并不是增加到 800 台的 MySQL 服务器那么简单。
    管理 800 台服务器,复杂度会发生本质的变化,具体表现为:
      a. 800 台服务器里面可能每周都有一两台服务器故障,
          从 800 台里面定位出 2 台服务器故障,很多情况下并不是一件容易的事情,运维复杂度高。
      b. 增加新的服务器,分区相关的配置甚至规则需要修改
          而每次修改理论上都有可能影响已有的 800 台服务器的运行。
      c. 如此大量的数据,如果在地理位置上全部集中于某个城市,风险很大
          遇到了水灾、大停电这种灾难性的故障时,数据可能全部丢失,因此分区规则需要考虑地理容灾
    因此,数据量越大,分区规则会越复杂,考虑的情况也越多。

2. 分区规则
    地理位置有近有远,因此可以得到不同的分区规则,包括洲际分区、国家分区、城市分区。

    具体采取哪种或者哪几种规则,需要综合考虑业务范围、成本等因素:
    a. 洲际分区:
        由于跨洲通讯的网络延迟已经大到不适合提供在线服务了,因此洲际间的数据中心可以不互通或者仅仅作为备份;
    b. 国家分区:
        不同国家有不同语言、法律、业务等,国家间的分区一般也仅作为备份;
    c. 城市分区:
        网络延迟较低,业务相似,分区同时对外提供服务,可以满足业务异地多活之类的需求。

3. 复制规则
    数据分区指将数据分散在多个地区,在灾难下,虽然部分数据受影响,但整体并没有全部被影响,本身就相当于一个高可用方案了
    但仅仅做到这点还不够,因为每个分区本身的数据量虽然只是整体数据的一部分,但还是很大,
        这部分数据如果损坏或者丢失,损失同样难以接受。
    因此即使是分区架构,同样需要考虑复制方案。

常见的分区复制规则有三种:

1. 集中式
2. 互备式
3. 独立式

集中式

备注

集中式备份指存在一个总的备份中心,所有的分区都将数据备份到备份中心

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage10-1.png

集中式备份架构的优缺点是:

1. 设计简单
    各分区之间并无直接联系,可以做到互不影响。
2. 扩展容易
    如果要增加第四个分区(例如,武汉分区),只需要将武汉分区的数据复制到西安备份中心即可,其他分区不受影响。
3. 成本较高
    需要建设一个独立的备份中心。

互备式

备注

互备式备份指每个分区备份另外一个分区的数据

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage10-2.png

互备式备份架构的优缺点是:

1.  设计比较复杂
    各个分区除了要承担业务数据存储,还需要承担备份功能,相互之间互相关联和影响。
2.  扩展麻烦
    如果增加一个武汉分区,则需要修改广州分区的复制指向武汉分区,然后将武汉分区的复制指向北京分区。
    而原有北京分区已经备份了的广州分区的数据怎么处理也是个难题:
        不管是做数据迁移,还是广州分区历史数据保留在北京分区,新数据备份到武汉分区,无论哪种方式都很麻烦
3. 成本低,直接利用已有的设备。

独立式

备注

独立式备份指每个分区自己有独立的备份中心

https://img.zhaoweiguo.com/knowledge/images/architectures/availabilitys/storage10-3.png

独立式备份架构的优缺点是:

1. 设计简单,各分区互不影响。
2. 扩展容易,新增加的分区只需要搭建自己的备份中心即可。
3. 成本高,每个分区需要独立的备份中心,备份中心的场地成本是主要成本,因此独立式比集中式成本要高很多

主页

索引

模块索引

搜索页面