关于常见分布式组件高可用设计原理的理解和思考

文章目录

  • 1. 数据存储场景和存储策略
    • 1.1 镜像模式-小规模数据
    • 1.2 分片模式-大规模数据
  • 2. 数据一致性和高可用问题
    • 2.1 镜像模式如何保证数据一致性
    • 2.2 镜像模式如何保证数据高可用
      • 2.2.1 HA模式
      • 2.2.2 分布式选主模式
    • 2.3 分片模式如何数据一致性和高可用
  • 3. 大规模数据集群的架构设计模式
    • 3.1 中心化模式
    • 3.2 去中心化模式
  • 4. 大规模数据集群故障转移模式
    • 4.1 自动修复
    • 4.2 人工修复
  • 5. 故障转移也是有限度的
  • 6. 系统稳定性的一些建议
    • 6.1 梳理系统核心链路
    • 6.2 鸡蛋不要放在一个篮子里
    • 6.3 淘汰糟糕的iaas设备
    • 6.4 更完善的监控和告警
  • 7. 参考文档

随着接触的分布式系统(产品)越来越多,关于分布式系统的数据存储逐渐有了一些理解,进行统一整理和梳理。

1. 数据存储场景和存储策略

在进行分布式系统设计时,面临的数据场景不同,因此对应的产品在进行架构设计时也采用了不同的存储策略。但是总的说来,主要包括如下两类。

1.1 镜像模式-小规模数据

小规模数据场景主要包括: 元数据、少量业务数据等。这种数据类型的特点是,存储的数据量一般都比较小(比如10G以内)。通常情况下,单个节点能够满足数据的存储、读写性能要求,因此该类型的分布式产品在设计时通常使用镜像模式进行存储。单节点保存所有数据(业务数据+元数据),通过多节点(主从模式,强同步或者半强同步)形成多副本,从而保证数据的一致性。主从模式能够避免数据不一致的问题,不同节点通过复杂的选主逻辑选择最合适的节点作为leader,leader节点响应客户端的写请求,从节点响应客户端的读请求(不同产品有差异)。该类型常见的产品如zk、etcd等。

参考zk的架构图如下
在这里插入图片描述

1.2 分片模式-大规模数据

大规模数据场景主要包括:大数据、日志、图片、大量文档数据等,这种数据类型的特点是,存储的数据规模大(TB级别甚至更高)。通常情况下,单节点无法满足数据存储需求(单节点的磁盘、cpu内存等成为瓶颈),因此该类型的分布式产品在设计时通常使用分片模式进行存储。 将一个完整的业务数据(比如大索引)拆分成多个分片进行存储,不同分片分散在不同的节点上,从而规避单节点性能不足问题。这种类型的架构模式需要master角色,保存整个集群的元数据,从而形成上帝视角,用于进行数据分配、调度等职责。常见的产品如hdfs、hbase、es等

参考es的架构图如下
在这里插入图片描述

2. 数据一致性和高可用问题

数据一致性和高可用是分布式场景下,面临的2个最核心问题。后续将重点开展镜像模式是如何实现数据一致性和高可用的。分片模式通常是在镜像模式下进行相应的组合而成。

2.1 镜像模式如何保证数据一致性

镜像模式下,由于单节点已经保存了所有的数据(元数据+业务数据),因此在架构上只需要进行选主+多副本,就可以解决避免数据一致性和高可用问题。
在这里插入图片描述

数据一致性:通过选主选择出集群的leader节点,响应客户端的写需求,并且通过数据强同步(或者半强同步)将数据同步到其他的节点,从而保证数据一致性。

当客户端进行数据写入时,形成一个写入的事务,会面临多种情况。

1,集群的leader节点+所有(或者多个)节点完成数据写入,才能认为数据已经完成写入,并返回给客户端,此时客户端才能认为数据已经写入到集群中,客户端进行事务提交,一个完整的数据事务完成。此时集群需要承诺客户端,写入的数据不丢失。

2,如果客户端在发起写入事务后,集群内部不同节点出现了异常(比如一个非leader节点突然宕机),面对这种情况不同的产品的响应策略不同(一些产品直接返回失败,一些产品会跳过异常的节点继续写入其他节点尽可能保证写入成功)。但是整体上的一个策略是,如果不满足集群的leader节点+所有(或者多个)节点完成数据写入,会将返回结果返回客户客户端,由客户端决定这条数据的去留(重试或者丢弃)。这种模式下,数据的一致性需要客户端进行参与,如果客户端忽略了集群的异常返回(或者返回码),就会可能导致数据丢失。

相关的写入流程可以参考etcd的写入流程
在这里插入图片描述

3,不同的产品在设计上不同

有些产品把**集群的leader节点+所有(或者多个)**的决定权保留给客户端,客户端在写入的时候选择对应的模式,通常有如下几种模式

  • 直接返回
  • 数据写入leader就返回
  • leader+所有节点写入成功就返回
  • leader+多个节点写入成功就返回

比如kafka在客户端写入数据是需要客户端指定acks策略。

有些产品则不允许客户端做出相关的选择,只有一种集群的内部定义的模式。

因此不同的客户端需要根据不同的产品特性进行相关的适配。

2.2 镜像模式如何保证数据高可用

镜像模式下,通过leader+多节点的方式实现数据多副本,从而实现数据高可用,不同产品的选主有差异,通常的选主方式有2种

  • HA模式
  • 分布式选主模式

2.2.1 HA模式

HA模式的实现方式有很多种,最常见的方式是,通过分布式锁实现,比如在zk中注册一个临时节点。

1,成功在zk中创建了临时目录的节点获取对应的分布式锁权限,从而成为leader,并且需要定期到zk中发送心跳,给临时目录续期。临时目录有一个特点,如果在ttl时间内没有被续期,就会自动消失。

2, 其余节点通过watch的方式监听这个临时目录,如果原leader在ttl时间内没有同步心跳,临时目录就会自动消失,zk给所有的watch客户端发送相关的事件

3, 收到zk的事件,集群的节点都抢锁(在zk中创建临时目录),抢到锁的节点升级为新leader

4,新leader发送广播告知所有的节点,新leader已经产生。

5,通常新leader产生后,老leader可能还存活,需要一定的策略将老leader降级,从能避免脑裂,比如hdfs的nn通过fencing策略将老leader降级(先rpc降级,如果rpc降级失败,则ssh到对应的机器上杀死进程)。

2.2.2 分布式选主模式

常见的选择主协议有Paxos,Raft,ZAB等多种协议进行选主逻辑,获取超过半数(n+1/2)投票的节点成为leader。由于不同节点之间的数据可能有差异,因此选举出leader后,需要根据情况进行合并数据(将不同节点的事务进行合并,形成完整的数据)。

不同协议的选主逻辑差异,可以参考 Paxos,Raft,ZAB的差异对比

通常情况下,通过一致性选主协议进行数据选主的集群,需要获取超过半数节点投票才能成为leader,因此通常部署单数节点,能够容忍集群内部网络隔离异常。并且集群能够容忍的异常节点数量是(n-1)/2,相对于双数节点部署,单数节点部署能够更节省资源,也更加合理。

raft的选主逻辑大致如下,其他协议的选主逻辑也跟raft大致差不多。

1,初始状态
在这里插入图片描述
Raft 每个节点初始化后的心跳超时时间都是随机的,如上所示,节点 C 的超时时间最短(120ms),任期编号都为 0,角色都是跟随者。

2,请求投票
在这里插入图片描述
此时没有一个节点是leader,节点等待心跳超时后,会推荐自己为候选人,向集群其他节点发起请求投票信息,此时任期编号 +1,自荐会获得自己的一票选票。

3,跟随者投票
在这里插入图片描述
跟随者收到请求投票信息后,如果该候选人符合投票要求后,则将自己宝贵(因为每个任期内跟随者只能投给先来的候选人一票,后面来的候选人则不能在投票给它了)的一票投给该候选人,同时更新任期编号。

4,当选leader
在这里插入图片描述
当节点 C 赢得大多数选票后,它会成为本次任期的leader。

5,leader与跟随者保持心跳
在这里插入图片描述
leader周期性发送心跳消息给其他节点,告知自己是leader,同时刷新跟随者的超时时间,防止跟随者发起新的leader选举。

2.3 分片模式如何数据一致性和高可用

分片模式在一定程度上是将大数据按照分片进行拆分,形成多个小分片,在每个小分片的整体数据一致性和高可用逻辑(主从多副本)跟镜像模式是一致的。

比如hdfs的架构如下
在这里插入图片描述

将hdfs进行拆分,主要分为2块

1,NN节点(2个nn),保存集群的元数据,构建集群的数据全局视角,使用HA模式进行实现高可用。

2,DN节点,将文件以block作为基础存储单元分散在不同的DN节点,单个block通常有3个副本,3个副本分散在不同机器/机架上,并进行内部选主。

如上2个模块, 均是将大系统拆分成小模块,利用镜像模式的基础方法实现数据一致性和高可用。

3. 大规模数据集群的架构设计模式

通常针对大规模集群,在系统架构的设计上主要是分2类

  • 中心化模式
  • 去中心化模式

量者有比较大的区别,并且优缺点也比较明显

3.1 中心化模式

所谓中心化模式,就是在集群内部选择一些节点(角色)存储集群的元数据,从而构建集群的数据全局视角,不同产品的实现方式有差异。

例如

  • hdfs的nn节点,通过dn定期汇报状态和数据给nn,从而构建和修正集群的数据,通过nn能够获取hdfs集群的集群数据状态。
  • kafka通过controller存储和集群的topic和partition信息
  • es通过master节点存储集群的元数据

中心化模式
优点:集群变更客户端不感知,统一由master节点管控
缺点:master节点存储所有的元数据(通常通过HA模式选主),master需要响应大量的http、rpc请求进行数据读写请求,因此master节点容易成为性能瓶颈

3.2 去中心化模式

去中心化模式,是指集群中没有节点(角色)负责构建集群的全局视角,约定一些固定的数据存储算法。客户端如果需要进行数据读写,需要根据约定的数据存储算法(比如哈希)计算对应的数据以及存储数据所对应的节点。客户端在跟对应的节点进行通信,进行读写数据。

典型的产品是,redis-cluster。

去中心化的模式
优点:客户端自己完成数据查找逻辑,因而节省了数据查找环节,能够解决中心化模式的master节点性能压力
缺点:对于集群的扩、容规则有一定的限制,如果不合理的扩、缩容姿势、以及算法的变更,可能会导致客户端无法通过约定的算法找到准确对应的数据存储的节点。

4. 大规模数据集群故障转移模式

在日常生产环境中,节点宕机/磁盘异常,是很常见的现象,因此分布式系统应当能够容忍常规的异常,不影响集群使用。不同产品在设计上有差异,通常有如下2种模式

  • 自动隔离,自动修复:系统内部自动检测,如果出现了节点宕机/磁盘异常,将读写从异常节点中摘除,并自动进行数据转移和修复,通常不需要人工参与
  • 自动隔离,人工修复:系统内部自动检测,系统内部自动检测,如果出现了节点宕机/磁盘异常,将读写从异常节点中摘除。需要人工介入进行修复。

自动隔离,应该都很容易理解,就是将读写从异常节点中摘除,避免客户端异常。差别主要在自动修复和人工修复上,两者各有优劣势。

4.1 自动修复

咋一看,好像如果集群能够自修复当然是最好的,这样不用人工介入,只需要等自动修复完成就好。但是实际情况来看,效果可能并不好。

最主要的限制是来自2个: 生产环境复杂,自动修复的时机和自动修复的进度,难以掌握。

比如 hdfs集群,由于1个节点异常了,会触发自动修复逻辑。自动修复主要是拷贝异常的数据到新节点,在新的节点生成合适的数据副本,但是

1, 数据拷贝需要占用一定的磁盘读写和网络读写带宽,hdfs的数据量巨大,如果不能得到合理控制可能会把机器的磁盘io和带宽打满,从而影响线上业务。
2, 再比如,机器可能1h就完成修复,并且上线了,步骤1中完成的读写修复,似乎可能多余了。 并且由于节点重新上线,又会重新触发数据balance,又会导致集群的磁盘读写和网络读写的带宽,恢复过程也可能比较久。

看起来机器宕机1h在生产中并不是难以容忍的异常,并且也几乎很少有概率会导致数据丢失,但是却触发了2次的数据同步,占用了磁盘读写和网络带宽,并可能会影响生产任务。虽然最终能够完成修复,但是额外带来了风险,效率并不高。

4.2 人工修复

人工修复,就是需要人工介入。 比如如上的hdfs集群异常,如果不进行自动修复,1h后机器修复正常开机并加入到集群,并不需要复杂的数据迁移和复制,由于磁盘数据都在只需要做简单的数据校验,就能够恢复正常,集群恢复的效率和速度要高很多。

但是代价就是,需要实时监控和人工介入,运维工作的量比较大,并且在一定时间内需要承担数据丢失的风险,毕竟副本少了一个。

不同产品的设计出发点不同,有些倾向于自动修复,有些倾向于人工修复,各有利弊。我个人倾向于做一个这种,设置自动修复的窗口期(比如12h),如果不能再窗口期内人工修复,就触发自动修复,取得数据风险和运维重量折中。

5. 故障转移也是有限度的

经常听到有人说,集群不是分布式吗,怎么单机故障了,集群就异常了?其实综合各种生产实践来看。常规情况下,如果单机设备异常的的比较干脆(机器宕机、磁盘不可读写)大多数的分布式产品是能够容忍的,并且效果还是有保证的。

但是分布式系统的故障容忍和转移,也是有限度的,并不是无限的单机故障(异常)都能容忍。主要的原因是来自,通常分布式产品内部的节点异常,是用过探活心跳来实现,如果探活能够成功,但是对应的节点性能很糟糕,难以满足读写的要求,就会导致由于一个慢节点,把集群完全拖垮的情况。成为单机故障的噩梦。

通常遇到的单机故障,容易导致集群被拖垮的现象不多,但是常见的有

  • 机器hang住或者负载很高,能够ping通,tcp都正常,但是机器执行不了任何命令
  • 机器的磁盘io性能很差,数据读写都很慢

如上2种都是日常生产常见的现象,很少有分布式组件能够逃过这两种因素,能够自动完成容灾剔除,成为单机故障的噩梦

6. 系统稳定性的一些建议

为了尽可能的保证生产稳定性,应当在系统架构设计上做一些更好的可靠性建设,基于日常经验进行整理

6.1 梳理系统核心链路

一个分布式系统重,不同组件的重要度是不同的,核心链路涉及相关的组件和架构,是需要定期梳理和改进的。一个系统里面,几个不同的产品单独拆开用,没问题,但是合并在一起却可能出现不兼容的现象,因此在架构上需要进行梳理。

核心组件和链路,需要

  • 区分核心链路和非核心链路
    精力重点投入在核心链路上,特别是架构中的骨干环节。非核心链路可能会出现问题,但是不是大故障,通常还是能够容忍的。

  • 合理的容量设计和压测
    系统的容量模型和容量设计,是一个很复杂且很困难的事情,但是需要再内部测试环境尽可能的模拟和压测,能够得到一定的参考依据,生产上能够得到一定的参考数据。

  • 核心链路混沌演练
    只要真正生产的演练,才能发现问题,纸面上的理论验证都不如实际的操作演练,问题才能真正的暴露。

6.2 鸡蛋不要放在一个篮子里

核心链路的数据、部署等,尽可能的做拆分,在系统架构上,我倾向于去中心化这个概念。在关键的容灾上,往往能够起到意想不到的效果

6.3 淘汰糟糕的iaas设备

  • 淘汰糟糕的iaas设备
    在生产环境上,导致分布式组件异常的,90%以上的因素来自糟糕的iaas设备,而不是来自分布式组件本身的逻辑设计bug,特别是开源的组件,都是久经考验,大体上还是比较有保证的。一个良好的设备,并不是说要购买几百万一台的超级设备,至少设备本身不应该经常性的出问题(时不时磁盘坏了,内存异常,频繁关机等)。日常需要加强相关的监控和告警,异常率高的iaas设备应该及时淘汰,淘汰糟糕的iaas设备,至少能够规避90%以上的故障(有条件的情况下,更倾向于疑罪从有策略

6.4 更完善的监控和告警

  • 核心系统全链路监控和告警
    需要包括核心链路的监控大盘和告警,特别是核心链路建议增加核心链路环节的全链路告警。
    在告警的建设上要抓大放小,把重要的精力都放在重点问题的建设上,抓重点,多建设全链路监控

  • 组件监控+iaas监控

  • 深入业务逻辑, 构建业务监控大盘

7. 参考文档

Raft常见选主逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/637301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

32 登录页组件

效果演示 实现了一个登录页面的样式,包括一个容器、左侧和右侧部分。左侧部分是一个背景图片,右侧部分是一个表单,包括输入框、复选框、按钮和忘记密码链接。整个页面的背景色为白色,容器为一个圆角矩形,表单为一个半透…

linux C语言socket函数send

在Linux中,使用C语言进行网络编程时,send函数是用于发送数据到已连接的套接字的重要函数之一。它通常用于TCP连接,但也可以用于UDP(尽管对于UDP,通常更推荐使用sendto,因为它允许你指定目标地址和端口&…

【linux驱动】用户空间程序与内核模块交互-- IOCTL和Netlink

创建自定义的IOCTL(输入/输出控制)或Netlink命令以便用户空间程序与内核模块交互涉及几个步骤。这里将分别介绍这两种方法。 一、IOCTL 方法 1. 定义IOCTL命令 在内核模块中,需要使用宏定义你的IOCTL命令。通常情况下,IOCTL命令…

Rancher部署k8s集群测试安装nginx(节点重新初始化方法,亲测)

目录 一、安装前准备工作计算机升级linux内核时间同步Hostname设置hosts设置关闭防火墙,selinux关闭swap安装docker 二、安装rancher部署rancher 三、安装k8s安装k8s集群易错点,重新初始化 四、安装kutectl五、测试安装nginx工作负载 一、安装前准备工作…

SD-WAN企业组网场景深度解析

在当前快速发展的企业网络环境中,SD-WAN技术不仅仅是实现企业站点之间网络互通的关键,更是满足不同站点对因特网、SaaS云应用、公有云等多种企业应用和业务访问的理想选择。从企业的WAN业务需求出发,我们可以对SD-WAN的组网场景进行深度解析&…

VIM工程的编译 / VI的快捷键记录

文章目录 VIM工程的编译 / VI的快捷键记录概述笔记工程的编译工程的编译 - 命令行vim工程的编译 - GUI版vim备注VIM的帮助文件位置VIM官方教程vim 常用快捷键启动vi时, 指定要编辑哪个文件正常模式光标的移动退出不保存 退出保存只保存不退出另存到指定文件移动到行首移动到行尾…

替代堆叠的新技术M-lag

M-lag:跨设备链路聚合组,是一种实现跨设备链路聚合的机制。将一台设备与另外两台设备进行跨设备链路聚合,从而把链路的可靠性从单板级提升到设备级,组成双活系统。 基本概念: peer-link链路:是一条聚合链…

[C#]winform部署官方yolov8-rtdetr目标检测的onnx模型

【官方框架地址】 https://github.com/ultralytics/ultralytics 【算法介绍】 RTDETR,全称“Real-Time Detection with Transformer for Object Tracking and Detection”,是一种基于Transformer结构的实时目标检测和跟踪算法。它在目标检测和跟踪领域…

力扣刷MySQL-第五弹(详细讲解)

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:力扣刷题讲解-MySQL 🍹文章作者技术和水平很有限,如果文中出…

Java 面向对象02 封装 (黑马)

人画圆:画圆这个方法应该定义在园这个类里面。 人关门:是人给了门一个作用力,然后门自己关上了门,所以关门的方法是在门的类里面 封装对象的好处: 调用Java自带的方法举例实现: 在测试类中,对其…

电脑pdf如何转换成word格式?用它实现pdf文件一键转换

pdf转word格式可以用于提取和重用pdf文档中的内容,有时候,我们可能需要引用或引用pdf文档中的一些段落、表格或数据,通过将pdf转换为可编辑的Word文档,可以轻松地复制和粘贴所需内容,节省我们的时间,那么如…

Element-UI 多个el-upload组件自定义上传,不用上传url,并且携带自定义传参(文件序号)

1. 需求: 有多个(不确定具体数量)的upload组件,每个都需要单独上传获取文件(JS File类型),不需要action上传到指定url,自定义上传动作和http操作。而且因为不确定组件数量&#xff0…

Oracle 经典练习题 50 题

文章目录 一 CreateTable二 练习题1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数2 查询"01"课程比"02"课程成绩低的学生的信息及课程分数3 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩4 查询平均成绩小于…

力扣精选算法100题——串联所有单词的字串(滑动窗口专题)

本题链接——串联所有单词的字串 本题和找到字符串中所有字母异位词题目非常相似,思路都是一样。通过自己的大脑能发现其中的相似之处。 第一步:了解题意 就按实例来分析吧,这样更通俗易懂。 words["ab","cd","ef…

Pycharm Terminal 无法激活conda环境

1.问题 Failed to activate conda environment. Please open Anaconda prompt, and run conda init powershell there. 这导致我们无法在Pycharm中使用conda命令 2.解决办法 修改为第二个,然后重启Terminal 再打开时发现已经是当前的conda环境

大数据安全 | 期末复习(上)| 补档

文章目录 📚概述⭐️🐇大数据的定义、来源、特点🐇大数据安全的含义🐇大数据安全威胁🐇保障大数据安全🐇采集、存储、挖掘环节的安全技术🐇大数据用于安全🐇隐私的定义、属性、分类、…

免费三款备受推崇的爬虫软件

在信息爆炸的时代,爬虫软件成为了数据采集、信息挖掘的得力工具。为了解决用户对优秀爬虫软件的需求,本文将专心分享三款备受推崇的爬虫软件,其中特别突出推荐147采集软件,为您开启爬虫软件的奇妙世界。 一、爬虫软件的重要性 爬…

使用OpenCV绘制图形

使用OpenCV绘制图形 绘制黄色的线: # 绘制一个黑色的背景画布 canvas np.zeros((300, 300, 3), np.uint8) # 在画布上,绘制一条起点坐标为(150, 50)、终点坐标为(150, 250),黄色的,线条宽度为20的线段 canvas cv2.line(canvas,…

迭代器模式介绍

目录 一、迭代器模式介绍 1.1 迭代器模式定义 1.2 迭代器模式原理 1.2.1 迭代器模式类图 1.2.2 模式角色说明 1.2.3 示例代码 二、迭代模式的应用 2.1 需求说明 2.2 需求实现 2.2.1 抽象迭代类 2.2.2 抽象集合类 2.2.3 主题类 2.2.4 具体迭代类 2.2.5 具体集合类 …

tcp/ip协议2实现的插图,数据结构7 (27 - 章)

(166) 166 二七1 TCP的函数 函tcp_drain,tcp_drop (167) (168)