导语 本文介绍如何用Raft协议做有状态服务的高可用,以及提升性能。

  高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间,解决单点故障问题。本文以Ozone举例,如何用Raft协议做有状态服务的高可用,以及提升性能。

  1. Ozone背景介绍

  1.1 为什么做Ozone

  Ozone是继HDFS的下一代对象、文件混合存储系统。做Ozone目的是,第一,解决HDFS扩展性问题,HDFS因为中心节点NameNode的性能瓶颈,导致集群达到万台时无法再扩展。业界已有的方案有两种,但成本都很高:字节跳动将Java的NameNode用C++重写,而京东有专门的JVM团队优化Java的内存垃圾回收;第二,大数据生态缺失对象存储。HDFS社区为了解决这两个问题,孵化出了Ozone项目。

  1.2 Ozone架构

  Ozone架构如图所示,Ozone有三部分构成,Datanode、SCM和OM,Datanode负责存数据,数据以128 MB Block为单位存储;SCM和OM都是中心节点,SCM管理Datanode,以及Block到Datanode的映射。OM管理Key或者文件到Block的映射。

  1.3 解决HDFS扩展性问题

  Ozone的架构可解决HDFS扩展性问题。HDFS因为中心节点NameNode的单点瓶颈,导致HDFS集群达到万台时无法再扩展。首先在内存上,NameNode的所有元数据均存在内存,内存和GC压力大,而Ozone将元数据存在RocksDB,并部分Cache在内存里,大大减轻内存压力。其次,NameNode包含所有元数据,而Ozone将NameNode拆分为两个服务OM、SCM,并将元数据分三级,OM、SCM、Datanode各存部分元数据,进一步减轻中心节点压力。最后HDFS的Datanode需要将所有128MB的Block向NameNode汇报,造成汇报风暴;而Ozone的Datanode只需要将所有5GB的Container向SCM汇报。

  

  2. OM高可用架构演化

  2.1 OM为什么做高可用

  Ozone诞生是为了替换HDFS,而最大的HDFS集群有上万个节点,同时跑的任务4K多。OM提供Key或文件到Block的映射,如果OM进程发生故障,4K多任务全部失败,如果机器故障,万台节点的元数据都会丢失。因此需要做OM的高可用。

  2.2 主从式高可用

  高可用有两种方式:多活和主从。多活采用Load Balance方式,多个节点同时提供服务,适用于无状态服务,或者服务之间状态天然隔离,无需相互可见,多用于REST服务。但对于Ozone这种存储系统,状态多、状态更新频繁、且需相互可见,只能采用主从式高可用。

  2.3 已有主从架构

  目前已有的主从方案,有HDFS的NameNode,借用ZooKeeper、JournalNode、ZKFC实现,ZooKeeper简称ZK,JournalNode简称JN。如果OM借鉴NameNode,则有两个OM,分别处于active、standby状态,active OM对外服务,standby OM作为备份。3个JN组成一致性存储系统, active OM将操作log写到JN集群,standby OM从JN集群同步操作log并执行,以便于跟上active OM状态。3个ZK和2个zkfc用于选主,zkfc检测到active OM发生故障时,借助zk选主,将standby OM切换为active OM,对外提供服务。这套架构至少10个进程,维护困难,逻辑复杂,如何简化?

  2.4 简化主从架构

  首先3个ZK可以和3个JN合并,因为JN用一致性协议paxos写操作Log,而ZK用一致性协议zab选主,可将两套一致性协议合并为一套,合并后剩下7个进程:3个JN、2个ZKFC、2个OM。3个JN里会选出一个主,2个om也会选出来一个主,可以将两个主合并成一个,这样就可将JN做到om里面,产生只有3个进程的om ha。

  2.5 选择分布式一致性协议

  3个OM的HA仍然依赖一致性协议实现写一致性和选主,目前主流分布式强一致性协议有Paxos、Zab、Raft。Paxos论文细节少,实现困难,虽然Paxos支持乱序提交log,而Zab、Raft只能顺序提交log, paxos写性能优于zab、raft,但multi-zab、multi-raft性能也可达到paxos的水平。而ZAB协议,和Raft非常相似,差异仅在于选主等细节,但论文细节少。而Raft协议有258页论文,细节充足,理论完备,且开源项目众多,如Etcd、TiKv、Ratis、SofaJraft等,从语言、开放性、活跃度和易用性考虑,选择Ratis。OM HA的架构是三个OM,接下来看下三个OM如何保证一致性和可用性。

  

  2.6 写一致性

  OM HA需要起若干个OM节点,只有一个主节点,也叫leader节点,其他都是从节点,也叫follower节点。

  首先看下3个OM的HA如何保证写一致性,假设初始三个OM的DB里变量a的值都是1,客户端发送a+2的请求给leader OM1,OM1首先将这个请求写到wal log,也就是raft log,然后将这个请求发给OM2、OM3,OM2、OM3也将这个请求写到raft log里,如果3个节点里的2个节点成功将a+2写raft log,OM1就执行a+2请求,将DB里a的值改为3,并回复客户端成功。这里OM1没有等OM2和OM3执行完a+2再返回客户端,因为OM2和OM3已将请求a+2记在raft log里,可以后续从raft log里读出请求并执行。

  

  2.7 读一致性

  可以看出,写数据是通过leader向follower同步,所以leader有最新状态,所以读数据时从leader即可读到最新数据,不需要像multi-paxos要从大多数节点读。

  3. 提升可用性

  为了提高可用性,首先分析进程的生命周期,进程的状态分为死和活,死又有宕机和升级两种情况,宕机分为主节点宕机、主从节点全宕机。针对每种case都有相应的方法提高可用性。首先只有主节点宕机时,可通过自动主从切换,选出新leader对外服务。如果主从节点全宕机,通过listener的备份数据,恢复服务。而在升级时,通过滚动升级,不中断服务。在进程活着的时候,则通过稳定主节点,避免主从频繁切换,导致切换期间服务不可用。

  

  3.1 解决主节点宕机

  首先看主节点宕机的解决办法,宕机分两种情况,如果OM进程宕机,则无法提供服务;如果机器宕机,且不可恢复,会造成数据丢失,因此HA需要保证进程或机器宕机时,服务正常,数据不丢。OM HA允许少数节点故障,假设leader OM1发生故障,OM2会当选为新leader,对外服务,保证服务正常。因为OM HA写数据时,大多数写成功才算成功,所以少数节点宕机时,剩下的节点一定有最新的状态,最新状态的节点会当选为新leader,保证不丢数据。但现在只有两个节点,不能再有节点挂掉,为了恢复集群的容灾能力,需要添加新节点OM4。但刚添加的OM4,没有最新的DB状态,提供不了容灾能力,已有的做法,leader会将raft log一条条发给OM4,OM4再执行,速度很慢,因此为了让OM4快速跟上Leader的状态,Leader会将自己DB做个snapshot发给OM4,OM4利用snapshot快速跟上leader状态,并提供容灾能力。

  

  3.2 解决主从节点全宕机

  如果3个主从OM全挂了,且数据不可恢复怎么办?第一种方案是添加节点OM4、OM5,3个OM变为5个OM,允许更多节点挂掉,但吞吐量下降9%左右,原因有两个:第一,leader负载更重,需要向四个follower同步log;第二,5个节点后,需要3个节点都提交成功才算成功。第二种做法是增量备份DB,但如果备份太频繁,备份时需要锁表,影响吞吐量,如果备份不频繁,会丢很多数据。那如何既能既能提高容灾能力,又不影响集群吞吐量?考虑到raft log本身就是DB的增量备份,因此直接利用已有的log同步机制,增量同步log即可,而增量同步raft log机制是已有的,直接利用即可。做法是在follower后添加2个listener, 增量同步follower已提交的log ,为了不影响集群性能,listener不参与提交log、选举。因为listener不参与提交log,因此可将listener部署在更远的位置,提高容灾能力。但listener也有个缺陷,因为它不参与提交log,所以它的log可能落后于leader,在leader和follower全挂的情况下,listener可能会丢几分钟的数据,对于非交易类等大部分场景是可接受的。

  

  3.3 滚动升级

  最后一个进程停止的情况就是升级,现在三个OM,如果将三个OM停机升级,那就无法做到不中断服务,因此需要滚动升级。做法是先将follower OM2停机升级,此时OM1作为leader仍然对外提供服务。然后将leader角色从OM1切换到OM2,此时OM2作为leader对外提供服务,如果OM2能稳定服务,再将OM1、OM3逐一升级。但如果OM2无法正常服务,需要回滚,此时再将leader从OM2切回OM1,然后回滚OM2即可。在此流程中,只有将leader从OM1切换到OM2过程中,无法提供服务,而该时间间隔为2秒左右,客户端自动重试,用户无感知。

  该流程难点是如何将Leader快速从OM1切换到OM2,图里OM2的log比OM1的log旧,根据之前介绍的选举机制,只有log最新才能当选为leader,因此OM2不具备当leader的条件。所以leader OM1需要将最新log a+2发给OM2。另外如果客户端一直向leader OM1发送写请求, OM1会一直有新log产生,OM2的log可能一直落后于 OM1,无法成为leader。所以在切换leader过程中,leader OM1阻塞客户端写请求。

  到现在解决的都是进程停止运行时,如何提高可用性,但进程一直运行时,也有不可用的问题,比如leader频繁切换,切换期间服务也是不可用状态,所以需要稳定leader。

  3.4 稳定leader

  首先看下leader如何选举产生的,follower在2s后收不到leader心跳,因为超时向其他节点发送选举请求,收到大多数赞成票才能当选为leader,而其他节点收到选举请求后,会依据对方RaftLog是否最新来决定是否给对方投赞成票。

  上述方案有两个问题,第一,没办法指定leader的位置,OM和SCM都采用主从方案,如果OM和SCM leader距离远,比如在不同数据中心,OM、SCM通信延时高。第二,每月因为选主,不可用时间38min,51次超时选主,每次选主耗时45秒。

  针对无法指定leader位置的问题,我采用优先级方案,高优先级的节点更容易成为leader,这样可以让OM、SCM leader分布的更近,经测试若OM、SCM leader在同一台机器,比在不同机器,吞吐量提升14%。

  针对每月38min的不可用问题,采用减少选举次数、缩短选举时间。为了减少选举次数,在我收到对方投票请求后,我检查自己近期是否收到leader心跳,如果收到,就拒绝给对方投票,这是为了防止对方网络抖动,导致整个集群频繁切换leader,加入这项优化后每月51次选举降低为2次。为了缩短选举时间,让更可能成为leader的高优先级节点率先发起选举,可将选举时间从45秒降为1.5秒。

  4. 性能优化

  接下来看HA的性能优化,对于存储系统,关注读、写性能;优化指标有两个,延时和吞吐。

  首先看下读,Raftis实现的HA,只需从leader读,所以HA对读性能没有影响。再看下写,首先在延时上,使用HA之前,只需要写一个节点,且只需要写DB。开启HA后,至少写两个节点,且要写Raft Log和DB,因此写延时增加,优化方向是利用落盘的raft log降低写延时。那是否有必要优化写吞吐?对于大数据场景,读写比例9比1,写的比例很小,因此暂时没有优化的必要,但也可以优化,可以采用分表的方式,多个raft group同时写不同的表,提高并行度。

  

  优化性能首先要定位性能瓶颈,定位性能瓶颈一般采用如下方法,如果CPU高,则采用Perf查看CPU热点。如果延时高,首先用tcpdump粗略排查,tcpdump可查看每个请求的执行时间。但tcpdump无法深入到进程内部排查。如果需要深入进程内部排查每个阶段执行时间,则有两种方式:metric和opentracing。Metric适用于统计多个请求每个阶段执行时间的分布。而opentracing则适用于分析单个请求每个阶段的执行耗时。

  

  4.1 写性能优化

  首先看下写延时的问题,启用HA后,写延时由48ms增加到107ms,通过使用上文定位性能瓶颈的方法,定位到因为刷盘导致写延时高,一次写数据有两次刷盘,raft log和DB。但只要raft log及时刷盘即可,即使DB因为未及时刷盘而丢数据,也可以从Raft log恢复数据,所以OM1写完cache立即返回客户端。

  那如果在Cache数据落盘前,OM1 Crash了如何恢复数据?可以在DB里记录已落盘数据对应的Raft log的Index。现在有两条raft log, a + 1的index是0,a + 2的index是1。DB里的值是1,对应的raft log是a + 1,所以DB里记录index 0,OM1重启后,检查DB,查index是0,知道log a + 1对应的数据落盘了,而log a + 2对应数据未落盘,所以OM1重新执行a + 2再写到cache里。优化后写延时从107ms降低到71ms。

  

解决单点故障 - 有状态服务的高可用相关推荐

  1. 【秒杀购物商城业务服务】「分布式架构服务」盘点中间件服务的高可用模式及集群技术的方案分析

    秒杀购物商城业务服务-分布式架构介绍 基于MySQL数据库集群技术实现服务的高可用 基于Tomcat的集群负载机制实现Tomcat服务器的高可用 基于Nginx负载均衡机制实现负载均衡(介绍和配置) ...

  2. Centos7+Nginx+Keepalived实现Apache服务的高可用负载均衡

    Centos7+Nginx+Keepalived实现Apache服务的高可用&负载均衡 今天是2017年的第一天,昨天也就是2016年的最后一天,我尝试部署了Centos7+Nginx+Kee ...

  3. 04 | 负载均衡:Ribbon 如何保证微服务的高可用

    上一讲我们对 Nacos 的集群环境与实现原理进行了讲解,我们已经可以轻松将单个微服务接入到 Nacos 进行注册,但是微服务本不是孤岛,如何实现有效的服务间稳定通信是本文即将介绍的主要内容,本次我们 ...

  4. java 主备切换_keepalived 实现 Java 服务的高可用(主备切换)

    前言 本文要说的是基于 keepalived 实现两台服务器之间的主备切换,从而实现 Java 服务的高可用.keepalived 的原理不多做介绍,自行搜索了解,keepalived 的安装部署请参 ...

  5. 云原生时代微服务的高可用架构设计

    简介: 在8月20日"阿里巴巴技术质量精品课"上,来自蚂蚁的经国分享了对云原生时代微服务的高可用架构设计的全面解析,为大家介绍了应用架构演进路径.云原生时代的技术福利.高可用架构的 ...

  6. 如何保证 HBase 服务的高可用?看看这份 HBase 可用性分析与高可用实践吧!

    来源 | 阿丸笔记 责编 | Carol 头图 | CSDN 下载自视觉中国 HBase作为一个分布式存储的数据库,它是如何保证可用性的呢?对于分布式系统的CAP问题,它是如何权衡的呢? 最重要的是, ...

  7. 蚂蚁金服资深技术专家经国:云原生时代微服务的高可用架构设计

    经国 蚂蚁金服数字金融线担任技术风险架构师 读完需要 15 分钟 速读仅需 5 分钟 经国,蚂蚁金服资深技术专家,毕业于浙江大学. 2014 年加入蚂蚁金服,先后负责过支付宝的单元化.弹性.去 ORA ...

  8. 微服务治理 高可用 HA (High Availability) 的一些理解

    文章目录 微服务治理 高可用 HA (High Availability) 的一些理解 1.简介 2.Nginx 高可用 3.站点层的高可用 4.服务层 Service 的高可用 5.缓存层的高可用 ...

  9. 爱奇艺会员服务在高可用架构的实战探索

    点击"开发者技术前线",选择"星标????" 13:21 在看|星标|留言,  真爱 ▌概述 很多互联网公司在发展过程中大多出现过多次机房网络故障的情形,如果发 ...

最新文章

  1. 学习谭浩强老师的《C程序设计》,必配《C程序设计伴侣》!
  2. UGUI的优点新UI系统四 开源
  3. sql server 数据库 ' ' 附近有语法错误
  4. QTreeWidget
  5. Paper:《Spatial Transformer Networks》的翻译与解读
  6. Hibernate SqlQuery
  7. Atitit 爬虫发展历史 在互联网发展初期,网站相对较少,信息查找比较容易。然而伴随互联网爆炸性的发展,普通网络用户想找到所需的资料简直如同大海捞针,这时为满足大众信息检索需求的专业搜索网站便应运
  8. impala日期格式转换
  9. 电阻用计算机怎么算,电阻分压计算器
  10. 纯Vue实现网页日常任务清单小功能(数据存储在浏览器)
  11. 缓存算法篇其一-----FIFO(先入先出)
  12. MIPS/RISC-V ALU设计
  13. 《D o C P》学习笔记(3 - 0)Regular Expressions, other languages and interpreters - 简介
  14. Android桌面图标布局,android安装运行launcher并修改桌面图标
  15. 格里高历日历判断闰年
  16. [渝粤教育] 西南科技大学 法律文书写作 在线考试复习资料(1)
  17. 【通俗易懂】limit的使用方法
  18. Vue 图片压缩并上传至服务器
  19. UE4 如何将材质Material保存为本地图片Png
  20. 英语口语测试对话软件,英语口语人机对话软件

热门文章

  1. VUE项目引入微信JSSDK 实现微信自定义分享
  2. 机械设备行业专题研究:各家电池片技术路线差异几何?
  3. 【报错】arXiv上传文章出现XXX.sty not found
  4. 1.5 Illustrator视图的放大与缩小
  5. 2020平安科技校招内推
  6. 梯度下降算法和正规方程组学习笔记
  7. 精神分析学的创始人弗洛伊德先生关于梦的理论
  8. 生成好看的海底地形图
  9. BLEMotion-Kit 支持蓝牙运动传感评估套件
  10. 两种方式读取Json文件 数据