文章目录

  • 前言
  • OzoneManager HA的目标
  • OM HA的Raft方式实现
  • Ozone的读写请求的区别处理
  • OM服务的定期Snapshot、Checkpoint行为
  • 附:DoubleBuffer+Table Cache的请求处理
  • 引用

前言


在分布式系统中,为了避免中心服务节点存在单点问题,我们往往会有HA(High Availability)的防御措施。比如一个简单的HA部署方案,额外在另一个机器上部署一个完全一样的服务。当当前的这个服务出现问题时,能够快速切换到这个用来做HA的服务。HA服务切换本身并不是重点,这里的重点是如何保持HA服务间的状态同步。这点在分布式系统的HA设计实现中尤其之关键。本文笔者来聊聊Ozone对象存储系统中核心服务OzoneManager的HA的设计实现原理。

OzoneManager HA的目标


在之前Ozone的alpha版本中,OM服务都是以单点服务部署的方式来处理外部请求的。显然这种缺乏HA的运行模式在运用到实际生产环境中将会存在风险。于是Ozone社区在JIRA[HDDS-505: OzoneManager HA]下设计实现了OM HA的特性。同样是作为分布式存储系统的HA实现,OzoneManager的HA实现和HDFS NameNode HA实现有许多异同之处。

在官方社区的OM HA的设计文档中,列出了以下几点目标实现要点:

  • 底层使用Raft协议来实现OM服务的HA特性。换句话说,这里将不是只有1个Active,另1个Standby服务这样的模式。而是2N+1的模式,1个OM Leader服务,2N个OM Follower服务。OM Follwer间通过投票选举出Leader服务。中间投票选举的过程遵从的就是Raft协议。这点即OM HA服务实现基于的一大核心要点。
  • 有了OM Leader,OM Follower服务之后,另外一个要点是Leader/Follower间的状态同步控制,以此保证服务在角色切换后,还能保证完全一致的服务状态,就是我们所说的Strong Consistency。
  • OM HA服务对于用户的透明性。用户理应对于OM HA完全透明,它在配置了给定的多OM服务地址后,就可以进行服务的请求了了。不管背后的服务处于什么角色状态,客户端用户都无须做任何调整。换言之,客户端始终能找到正确的OM服务,进行请求的发送,而不是单一定向的定点服务发送。

OM HA的Raft方式实现


OM HA中使用了Raft做HA的底层实现,那么它是如何工作的呢?以及它是如何做服务状态的同步的呢?

OM HA在这里使用了Raft的Java实现库Apache Ratis,里面实现了基于Raft协议的Leader选举以及Leader/Follower的状态一致性的控制。不过今天笔者并不准备展开篇幅阐述Raft中一致性同步控制的具体机理,我们还是着重谈谈OM HA本身。

因为有了Raft库Ratis的底层一致性的实现保证后,在上层OM中,它需要做的事情就变得清晰,明了了。在Apache Ratis中,是通过定义StateMachine状态机的方式来表示一个服务的当前状态。外界的每次请求就是此StateMachine即将要apply的一个新的State,每次apply完这个State后,整个状态机就会变为下一个State。因此,多个服务初始拥有相同初始State的StateMachine,在经历了若干次顺序一致的状态改变后,StateMachine的最终状态必然是一致的。这就是基于StateMachine的保证状态同步的核心原理。

这里我们将StateMachine的抽象概念定义转化为更为具体化的概念定义:

  • 每次外界而来的待apply的State即为外界的request请求。
  • 服务的StateMachine为OM服务的metadata信息,包括volume, bucket,key信息等各种表信息。

在Leader/Follower的HA模式下,请求状态的处理流程如下:
1)客户端发送请求给Leader处理
2)Leader接收到客户端请求,然后将请求复制分发到其它Follower上
3)Leader服务获取到超过半数以上Follower收到请求信息的ack回复之后,apply用户请求到内部状态机。
4)Leader会通知其它Follower去apply它们接收到的请求。

上述请求我们可以理解为是Transaction,从StateMachine的角度来看,概念叫做log entry。Leader复制请求到其它Follower的过程为log的write过程, 如果log被其它Follower成功接收到了,则意为此log为committed的log。

因此在这里StateMachine的实现异常关键,Ozone在这里实现了其内部使用的状态机类OzoneManagerStateMachine,对应的2个核心方法,log entry的写入,和log entry的状态apply方法:

  /*** Validate/pre-process the incoming update request in the state machine.* @return the content to be written to the log entry. Null means the request* should be rejected.* @throws IOException thrown by the state machine while validating*/@Overridepublic TransactionContext startTransaction(RaftClientRequest raftClientRequest) throws IOException {ByteString messageContent = raftClientRequest.getMessage().getContent();OMRequest omRequest = OMRatisHelper.convertByteStringToOMRequest(messageContent);Preconditions.checkArgument(raftClientRequest.getRaftGroupId().equals(raftGroupId));try {handler.validateRequest(omRequest);} catch (IOException ioe) {TransactionContext ctxt = TransactionContext.newBuilder().setClientRequest(raftClientRequest).setStateMachine(this).setServerRole(RaftProtos.RaftPeerRole.LEADER).build();ctxt.setException(ioe);return ctxt;}return handleStartTransactionRequests(raftClientRequest, omRequest);}
  /** Apply a committed log entry to the state machine.*/@Overridepublic CompletableFuture<Message> applyTransaction(TransactionContext trx) {try {OMRequest request = OMRatisHelper.convertByteStringToOMRequest(trx.getStateMachineLogEntry().getLogData());long trxLogIndex = trx.getLogEntry().getIndex();CompletableFuture<Message> ratisFuture =new CompletableFuture<>();applyTransactionMap.put(trxLogIndex, trx.getLogEntry().getTerm());CompletableFuture<OMResponse> future = CompletableFuture.supplyAsync(() -> runCommand(request, trxLogIndex), executorService);future.thenApply(omResponse -> {if(!omResponse.getSuccess()) {if (omResponse.getStatus() == INTERNAL_ERROR) {terminate(omResponse, OMException.ResultCodes.INTERNAL_ERROR);} else if (omResponse.getStatus() == METADATA_ERROR) {terminate(omResponse, OMException.ResultCodes.METADATA_ERROR);}}// For successful response and for all other errors which are not// critical, we can complete future normally.ratisFuture.complete(OMRatisHelper.convertResponseToMessage(omResponse));return ratisFuture;});return ratisFuture;} catch (Exception e) {return completeExceptionally(e);}}

从上述方法我们可以看到,只有在apply State操作的时候,才是真正请求处理执行的阶段。

Ozone的读写请求的区别处理


Ozone为了保证请求状态处理的一致,引入了StateMachine的方式来做一致性的处理。但并不是所有的请求都需要以这样的方式被处理,比如那些不会影响服务内部状态的请求,即READ类型的请求,其实可以直接被服务处理返回。

简单来说,Client甚至可以直接请求到其中任何一个服务,然后被服务处理得到返回结果。但是为了保证服务内部持有最新的状态数据,Ozone目前只允许Leader服务接受READ读请求,客户端发送到Follower的请求会被failover到当前的Leader服务中去。然后直接被Leader服务的RPC Server处理逻辑所处理。

WRITE类型的请求同样会被failover到Leader服务,但是它会有上述提到的replicate request的额外过程,会有上述startTransaction(log entry written),applyTransaction(app transaction log)的过程来保证状态一致性的处理。

对于请求客户端而言,它在发起请求前并不知道哪些服务是Leader服务,因此在Client层面需要实现一个FailOverProxy类,做自动的重定向处理,Ozone这边专门实现了这样的类,叫做OMFailoverProxyProvider。

这个FailoverProxy在处理返回得到Follower服务返回的OMNotLeaderException后,会提取里面的Leader ID信息,进行请求的重试,并failover当前指向的OM为建议的Leader OM服务。

相关代码逻辑如下,

if (exception instanceof ServiceException) {OMNotLeaderException notLeaderException =getNotLeaderException(exception);if (notLeaderException != null &&notLeaderException.getSuggestedLeaderNodeId() != null) {// We need to failover manually to the suggested Leader OM Node.// OMFailoverProxyProvider#performFailover() is a dummy call and// does not perform any failover.omFailoverProxyProvider.performFailoverIfRequired(notLeaderException.getSuggestedLeaderNodeId());return getRetryAction(RetryAction.FAILOVER_AND_RETRY, failovers);}

OM服务的定期Snapshot、Checkpoint行为


和HDFS的FSImage Checkpoint行为类似,Ozone为了OM服务避免长时间做log entry的状态重建,也做了定期生成Snapshot的行为处理。由于Follower定期做Checkpoint,然后Leader定期向Follower上download最新的Snapshot到其本地。新加入的OM服务也可以快速从Leader 服务中bootstrap相关Snapshot文件和log数据,进行状态的快速同步。

综合上述几方面的模块描述,OM HA的实现整体架构如下图所示:

附:DoubleBuffer+Table Cache的请求处理


Ozone社区在实现OM HA模式下的请求处理时,额外设计实现了基于双缓冲+Table Cache的高效请求处理方式,大致原理如下:

  • OM的StateMachine在处理transaction请求时,先将请求执行到Table Cache中,然后返回一个OMClientResponse对象。OMClientResponse定义了执行写入db具体操作逻辑。
  • OM将OMClientResponse加入到OM DoubleBuffer中。
  • OM DoubleBuffer内部线程定期同步OMClientResponse的transaction到db中,然后清理掉对应过期的Table Cache的entry项。

核心处理方法如下,这个处理逻辑同样适用于非HA模式,

  @Overridepublic OMClientResponse handleWriteRequest(OMRequest omRequest,long transactionLogIndex) {OMClientRequest omClientRequest =OzoneManagerRatisUtils.createClientRequest(omRequest);OMClientResponse omClientResponse =omClientRequest.validateAndUpdateCache(getOzoneManager(),transactionLogIndex, ozoneManagerDoubleBuffer::add);return omClientResponse;}

引用


[1]. https://issues.apache.org/jira/browse/HDDS-505 . OzoneManager HA

Ozone OM服务HA原理分析相关推荐

  1. Ozone OM服务的HA配置搭建

    文章目录 前言 OM HA的配置初始化 OM HA模式下的服务启动 OM HA下的CLI命令使用 附:OM HA的样例配置 前言 在上文中,笔者阐述了Ozone OM服务HA的内部机理,但是没有介绍其 ...

  2. Flink JobManager的HA原理分析

    文章目录 前言 JobManager的HA切换通知 利用Zookeeper的领导选举与消息通知 引用 前言 在中心式管理的系统里,主节点如果只是单独服务部署的话,或多或少都会存在单点瓶颈(SPOF)问 ...

  3. 鸿蒙OS原子化服务卡片原理和架构分析

    引言 2021年6月2日晚间,华为在HarmonyOS 2系统及全场景新品发布会上正式推出了服务卡片,颠覆了人们对APP信息展示的认知,引起了行业内的极大关注,本文是对HarmonyOS服务卡片的原理 ...

  4. 借助nat123软件快速发布网站做网站服务,解决80端口被屏蔽被封,nat123软件原理分析

    概述 nat123软件主要是为没有公网IP或80端口被屏蔽被封的做网站用户而开放自由的平台软件. 使用nat123,可以在内网一步发布网站,做网站服务: 使用nat123,可以解决80端口被屏蔽被封的 ...

  5. 基于原理分析Nmap——活跃主机发现、端口扫描、服务探测、伪装技术、NSE脚本

    参考书籍<诸神之眼--Nmap网络安全审计技术揭秘> 李华峰 著 清华大学出版社 基于原理分析Nmap 1. 活跃主机发现技术 1.1 基于ARP协议 1.2 基于ICMP协议 1.2.1 ...

  6. Kubernetes Kubeadm init 与 join 原理分析

    一.kubeadm概述 kubeadm是社区维护的Kubernetes集群一键部署利器,使用两条命令即可完成k8s集群中master节点以及node节点的部署,其底层原理是利用了k8s TLS boo ...

  7. HDFS Multiple Standby原理分析

    文章目录 前言 HDFS Multiple Standby的实现要素 Multiple Standby实现分析 Bootstrap行为 Standby NN的checkpoint upload行为 A ...

  8. Keepalived与HaProxy的协调合作原理分析

    Keepalived与HaProxy的协调合作原理分析 keepalived与haproxy合作场景 更好的理解方式 协调合作中考虑的问题 一.Keepalived 以TCP/IP模型角度来分析: 二 ...

  9. 一次 SQL 查询优化原理分析(900W+ 数据,从 17s 到 300ms)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:Muscleape jianshu.com/p/0768eb ...

最新文章

  1. Flask上下文管理源码分析
  2. python2x与3x下使用urlretrieve下载文件
  3. java读取项目资源文件的方法
  4. php-redis 下载地址
  5. 任务记录:OEA 框架中的多类型树控件
  6. 开滦二中2021高考成绩查询,2021年唐山查询中考成绩
  7. JAVA:泛型通配符T,E,K,V区别,T以及Class,Class的区别
  8. Unity Invoke 函数调用
  9. 国内外最顶级的十大敏捷项目管理软件【2022】
  10. flash for linux安装教程,Flash Player 9 FOR Linux 的安装
  11. MATLAB数字图像小系统
  12. 巴比特 | 元宇宙每日必读:企业需要具备哪些资质才能开展NFT相关业务?
  13. 【三】仿射变换、投影变换的矩阵形式和特点归纳
  14. 学PS平面设计前,你需要先了解这些
  15. java中StringTokenizer使用
  16. select SCM type and URL 用m2e插件从svn导出maven项目
  17. 1077 Kuchiguse
  18. 从底层结构开始学习FPGA----Xilinx 7 系列 FPGA 的逻辑优势
  19. 盆盆的11年Microsoft MVP心路历程
  20. 电脑端必用思维导图软件,选一款就够了

热门文章

  1. 没有了三星谁来为苹果制造处理器?
  2. 体育对计算机专业的作用,计算机在体育教学中的应用
  3. QQ小游戏 RewardedVideoAd 创建激励视频广告组件 API
  4. scikit-learn 机器学习工具
  5. Windows 2003 64位正式版抢先体验(转)
  6. 将8051单片机长数组存储在Flash中
  7. 前端资源汇集(个人觉得不错的学习资源收集)
  8. 注册表启动项的具体位置
  9. 自定义TextView实现渐变色边框,渐变色文字并绘制drawable
  10. Linux 僵死进程 文件操作