RaftKeeper:构建跨机房高可用OLAP集群 演讲人:京东吴建超架构师 Contents 目录 项目简介功能和架构性能优化跨机房架构 01项目简介 项目背景 Zookeeper引起的问题RaftKeeper项目 Zookeeper在OLAP中的角色: 1.Meatdatastore:Tabledefinition、PartitionInfoetc. 2.OperationLog:Insertion、mutation、merge 3.Coordinator:ServiceDiscovery、TaskQueueetc. 项目研发的动机: 1.实际业务中问题越来越突出 2.社区计划研发keeper替代Zookeeper 项目的目标: Zookeeper瓶颈导致的问题:•完全兼容ZK的用户接口 •相对ZK更优的性能,支持更高(至少2倍)的请求吞吐量 1.TableReadOnly导致插入失败 2.分布式DDL操作超时或者失败 3.后台PartsMerge失败等 •降低ZK中的阻塞因素:JVMGCSTW、状态机Map扩容、mntr命令等 RaftKeeper项目已开源,详见:Github Raft分布式共识算法 Raft关键流程 1.Leader选举 1.采用majority的规则 2.新Leader通过强制Follower复制它的日志来处理日志的不一致 3.日志不全的服务器不会赢得选举,保证已经commit的请求不会回退 Raft共识算法简介 1.Raft用于解决分布式系统中副本间数据一致性的问题 2.Raft相对Paxos算法而言容易理解,工程实践简单 3.广泛用于数据相关工程中:Kudu、TiDB、Etcd等 2.LogReplication 1.基于Log,且log连续没有空洞 2.写操作只能由Leader发起 3.Log只能从Leader流向Follower WhyNuRaft 实现方面 1.第三方依赖少,良好的示例,代码优雅、接口抽象 的好 2.Pipeline机制和Batch处理机制,具有优秀的性能 算法方面 NuRaft在Raft算法的基础上做了一些有意义的补充: 1.Pre-vote机制:解决follower重连导致的重新选举的问题 2.Leadership过期机制:可以解决网络分区情况下的多个leader问题。 3.Leader指派机制:可以使某些节点不能或者较低的概率成为Leader 4.自定义commit&leaderelectionquorumsize,增加了集群在可用性和一致性间调节的灵活性 核心特性 1.完全兼容Zookeeper生态,客户端、监控管理工具等 2.高性能,写吞吐Zookeeper性能的2倍,见:Benchmark 3.查询平稳,TP99表现更稳定,见:Benchmark 4.Session内请求响应的顺序性保证 5.多路复用网络模型,支持30w长连接同时在线 02功能和架构 基础命令 CreateSync RemoveHeartbeat ExistsList GetCheck SetMulti GetACLAuth SetACLSetWatches 异常处理 #create/china"" Nodealreadyexists:/china #delete/not-exist-node Nodedoesnotexist:/not-exist-node #set/china""100 versionNoisnotvalid:/china … 基础功能 网络协议 1.Zookeeper握手协议格式 2.Zookeepercreate命令格式 高级功能 Watch机制 1.NodeWatch 支持节点的:创建、删除、更新事件 2.ParentNodeWatch 支持子节点的:创建、删除事件 特殊节点 1.Ephemeral节点:随着session过期,自动删除的节点 2.Sequential节点:子节点按照序号排列的节点 3.SequentialEphemeral节点 四字命令 1.用法:echomntr|nclocalhost5102 2.新增命令 Snap:统计snapshot情况,包括snapshot次数和执行时间 3.mntr命令优化 •mntr命令在ZK中统计approximate_data_size指标的时候会遍历整个状态机 •在2kwznode的ClickHouse集群中执行大概需要5-9s, 经常导致监控指标采集超时。 •RaftKeeper中的统计弃用了遍历数据的方式。 架构设计 Leader StateMachine IOModule Watches NodeMap 2.Readrequest 1.Userrequest EphemeralNodes Sessions RequestDispatcher dumpdata Snapshot 2.Writerequest 5.committostatemachine LeaderSelectionModule LogReplicationModule LogStore 131415aggreementHandleinsequence Needmajority3.logdisk 1234567 cache 8910111213 Requesttobecomeleader 4.Replication Followers 整体架构要点 1.状态机是核心模块实现了数据存储和watch等高级功能 2.只有写请求才走LogReplication流程,读请求直接访问状态机 3.数据持久化采用snapshot+binlog的方式 4.LogStore设置了cache,大幅度提升性能 一致性约束 1.同一个session内,保证响应按照请求的顺序执行 2.所有Session范围内,已经提交的事物按照顺序执行 架构设计–session内一致性 同一个session内,保证响应按照请求的顺序执行 1.写请求:同一个session内的请求只会在同一个PipeRunner内执行 2.读请求:同一个session的读写请求在Processor内按照xid的顺序执行 PipeRunner: thread,connection,taskqueue 架构设计–状态机 Writerequest 4567 StateMachine Readrequest dumpdata Logstore snapshot 状态机职责 1.功能实现,基础命令、watch、ephemeral节点等 2.接收logcommit请求并应用到状态机,接收用户查询请求 3.维护session信息,包括session过期机制 Sessions EphemeralNodes Nodes Watches watches sessioncloseortimeout 1.Deletewatches 4.deleterelatednode sessions 2.deleteephemeralnodes nodesmap node1node2node3 ... 3.Delete epode hemeraln ephemeralnodes Session机制 1.Session代表客户端和server端的一次会话 2.状态机中维护了会话的watches、Ephemeralnodes这样的易失性状态 01/eph_node1 02/eph_node2 03/eph_node3 00110s 00220s 00315s 01/watch_node1 02/watch_node2 03/watch_node3 架构设计–存储结构 1.Log存储格式: 2.Snapshot存储格式: 03性能优化 性能优化 假设需要从仓库运送100个包裹到一个小区,第一种方式是一个快递员一次运送一个包裹,那么总共需要花费100个小时。 性能优化-Batch 第一个优化方式是批量运送,假设一次运送10个包裹,只需要运送10趟,那么效率提升10倍,只需要10个小时就可以完成任务。 对应到RaftKeeper中,在请求最开始设置了一个专门攒批的组件,尽量将用户的写请求在处理最开始就按照批量的方式处理。 性能优化-pipeline 第二个优化方式是接力运送,比如在运送途中增加一名快递员,在运送过程中形成接力,那么时间可以从10个小时进一步降低到5个小时。 对应到RaftKeeper中我们将请求分解为:攒批、请求转发给leader、leader写本地日志并转发、follower写本地日志、leader提交请求、follower提交请求等一些环节,每个环节由一组线程完成,形成执行流水线,进而提升吞吐量。 延时优化–状态机Map 使用HashMap •主要思路是使用多个哈希表替换单一的哈希表,消除长 时间的阻塞和扩容时一次性空间消耗 将阻塞时间控制在1s以下 •根据实验数据,子哈希表的数据不能超过500w,如果支持 1亿的节点,小哈希表的数量设置在16-32个是比较合理的。 延时优化–异步Snapshot(WIP) 同步的snapshot •当日志数量达到一定阈值的时候,会创建snapshot,将数据全量dump到磁盘中,该操作在数据同步过程中处理,会引起读写请求阻塞。 存在的问题 •下表是存储OLAP数据的服务做snapshot的时间统计 •如果存储几千万级别的数据量,会造成100s的阻塞 异步的snapshot •异步snapshot消除了查询阻塞 •可能导致部分日志被apply两次。方案可行的关键点是,写 请求都是幂等的或者状态机对不同写请求适配冲突方案: 1.Create:ReturnNodeExistError 2.Delete:ReturnNodeNotExistError 3.Set:幂等的命令 4.… 优化小结 延时优化 1.状态机哈希表,采用TwolevelHashMap,减小阻塞时间 2.异步Snapshot,消除snapshot和compactlog阻塞的时间 3.C++没有JVMGC的阻塞 性能优化 1.Pipeline和Batch执行模型 2.添加环形队列,缓存最近的日志 3.请求处理采用多线程的线程模型,多个读请求可以并行处理 ……. 上线情况 2021年11月至今上线60+集群,经历3次大促考验 200 60 Zookeeper 1.OLAP集群规模提升2.解决导数失败问题 最大可以支持500节点 04跨机房架构 跨机房架构 LoadBalance Zone1 w/r r Zone2 CHProxy CHProxy CHProxy CHProxy S1R1 S1R2 S1R3 S1R4 S2R1 S2R2 S2R3 S2R4 Zone1 Zone2 Zone3 RK1 RK2 RK3 RK4 RK5 实施方案 •OLAP以副本为粒度跨2个机房部署 •RaftKeeper按照2:2:1的方式部署在3个机房 架构优势 •提供机房级别的业务高可用保障 •相比双集群导数,提供了更强的数据一致性保障 RaftKeepervsZookeeper •更优秀的性能和稳定性 •可以指定Leader所在的zone 开源社区 RaftKeeper项目已开源,地址见:Github,欢迎试用参与开发 OLAP社区 1.RaftKeeper项目源自OLAP社区,是其下游项目 2.贡献一些Feature:4lwcommand、手工snapshot、session超时协商、session重连(ignored) 3.发展思路不同,RK更倾向于替换Zookeeper,所以项目独立开发。 NuRaft社区 1.RK开发过程中NuRaft社区给予了很多帮助 2.同时也做了一些社区回馈,部分列举如下: 1.#293Inconsistentlogwhenl