分享嘉宾:翟佳 StreamNative 联合创始人

编辑整理:张晓伟 美团点评

出品平台:DataFunTalk


导读:多数读者们了解BookKeeper是通过Pulsar,实际上BookKeeper在数据库和存储场景都有着非常广泛的应用。BookKeeper是Pulsar的底层存储,Pulsar有着广泛数据入口,Pulsar跟Kafka及各类MQ(RabbitMQ、ACTIVEMQ)的较大区别是Pulsar是统一的云原生消息流平台,不但是分布式系统,而且做了存算分离,可以让用户在云的环境下,体验到云原生的优势,例如随意扩缩容、数据灵活迁移复制等。希望通过本文,让大家对Pulsar底层的BookKeeper有更深入的了解。

今天的介绍会围绕下面四点展开:

  • BookKeeper的简介
  • BookKeeper的特性
  • BookKeeper存储介质的演进
  • BookKeeper的社区资源

--

01 BookKeeper的简介

1. 业务场景需求的统一

Pulsar里有很重要的概念是“统一”,这个统一的特性是由BookKeeper支持实现的。这里的统一是指需求的统一,在消息场景下,用户场景分两类:

第一类是线上业务场景,例如1984年诞生的IBM MQ到现在的各类开源MQ解决的是线上业务场景,这些MQ的服务质量会对业务服务质量有着直接的影响,所以这类需求对数据质量,例如对数据持久性、数据延迟、消费模型的灵活性有较强的要求。

第二类是大数据场景,例如2010年左右随着实时计算的广泛使用,Kafka的这种高带宽和高吞吐使用需求。

由于面向场景不同、技术栈不同,这两种场景在业务上又同时存在,给业务带来不同的基础设施API、不同的使用方式、不同系统的运维成本等问题。所以Pulsar针对这些问题,做了两层API的统一:既兼容MQ的并发消费模型,提供比较好的服务质量,同时通过底层存储层抽象,可以提供很高的吞吐和带宽,这就是我们要介绍的Apache BookKeeper项目。

2. Apache BookKeeper简介

很多服务里都有日志,例如MySQL的binlog和HDFS的namenode的editlog,都是对日志的一个抽象,而BookKeeper就是把这个抽象变成了一个分布式的服务,摆脱了对单机容量瓶颈的限制,把日志变成了可无限扩展的服务。BookKeeper使用packet source协议和ZooKeeper的zap协议,通过log append only的方式实现了低延迟和高吞吐。在APCP里选择CP,而availability是通过多副本并发的方式提供高可用,BookKeeper有着低延迟、高吞吐、持久化、数据的强一致性、服务的高可用、单节点可以存储很多日志、IO隔离等优势,针对这些特性在后文会展开介绍。

3. BookKeeper的诞生

BookKeeper也是Apache的一个项目,同样是由雅虎捐献诞生,原本是为了应对雅虎开源HDFS里元数据存储的需求。

下图是字节跳动技术文章的一个图,主要是呈现在字节跳动如何用BookKeeper支撑元数据服务,支撑起EB级别的HDFS集群。这个集群DN有好几万台,需要很多NameNode,就需要一个可以保障active/standby/observer NameNode之间强一致性的日志服务,单机容量瓶颈下很难支撑这么大的体量时,引入了一个分布式的日志服务,这就是BookKeeper诞生的场景。随着HDFS大规模的问题开始出现之后,BookKeeper成为了HDFS在HA上的刚需需求,例如在EMC内部的HDFS集群,也是用的BookKeeper来做NameNode的editlog服务。BookKeeper是一种分布式场景下很常见的复制状态机的实现(通过复制log,保持各个节点状态机的同步,A节点持久化log后,把log同步到B节点,在B节点进行log的一个重放,让B节点达到跟A节点一样的一个状态)。由于在HDFS场景中,保存的只是NN的变更日志,所以算是元数据的元数据,对数据一致性、对吞吐、对时延的要求自然极高。

4. BookKeeper使用案例

BookKeeper也有局限性,是append only的一个抽象变成了分布式服务,相对而言比较底层。所以用户多是一些比较大的互联网公司或其他有大数据量的需求的用户,这些用户会在BookKeeper之上做一些二次开发,例如Pulsar在BookKeeper之上做了一层broker服务,对BookKeeper的每个分片做一些管理然后将其作为数据的存储服务。

类似的还有Twitter和Salesforce。Twitter的技术栈是构建在实时计算上的,在Twitter内部,BookKeeper是作为很重要的基础设施,不但有类似Pulsar的服务eventbus,还有其他使用场景例如搜索、广告、Stream computing, 以及作为类似KV存储的Manhattan Database的元数据服务,这些场景都用到了BookKeeper。在规模上,Twitter BookKeeper有两个集群,每个集群约有1500个节点,每天有17PB的数据,每秒1.5万亿的records。而在Salesforce的使用背景,是Salesforce想去掉对Oracle的依赖,所以自研了类似Amazon Aurora的NewSQL Database,其内部很多跟元数据相关或有一致性要求的服务都是通过BookKeeper来满足的,并且也有部分后端场景将BookKeeper作为存储服务去用。

--

02 BookKeeper的特性

1. BookKeeper基本概念

  • Ledger

可以理解为BookKeeper是会计,Ledger是账本,每个账本是记录信息的一个单元,写完之后转为closed状态(只读),最新的账本是打开状态(openLedger),以append only的方式持续存储数据。

  • Fragment

可以理解为BookKeeper内部维护的一个以append only的方式添加的数据组。

Fragment之下就是用户以append only的方式追加的一条条数据。

2. BookKeeper的节点对等架构

openLedger时有3个参数:Ensemble选择几个节点存储这个账本,Write Quorum控制数据写几个副本(并发写,不同于Kafka或HDFS,BookKeeper没有数据节点之间主从同步的关系,把数据同步的协调者从服务端移到了客户端),Ack Quorum控制等几个副本返回ack。

以下图为例openLedger(5,3,2),在保存这个账本时,选择了5个节点,但是只写3个副本,等2个副本来返回ack。第一个参数一般可用于调整并发度,因为写3个副本是通过轮转的方式写入,例如第1个record是写1-3节点,第2个record写2-4节点,第3个record写3-5节点,第4个record写4-5和1节点这样轮转。这种方式即便3个副本,也可以把5个节点都用起来。

这几个参数便捷的特性可让用户通过机架感知、机房感知、resource感知等各种方式进行灵活设置。当选好节点后节点之间的排序就已完成,每个record会带个index,index和节点已有绑定关系,例如index为1的,都放在123上,为2的都放在234上。通过这种方式可以让我们知道每个节点存了哪些消息,当某个节点宕机,根据这个节点的位置信息,把对应record还在哪些节点上有副本的信息找出来进行多对多的恢复。这么做的另一个好处是不用再维护元数据信息,只需要有每个节点记录index信息,在openLedger时记录好每个节点的顺序即可。

openLedger(5,3,2)数据存储结构就是下图中右边的结构,如果选择Ensemble=3,Write Quorum=3,数据存储结构就是下图左边的结构:

综上,用户可以通过Ensemble来调整读写带宽,通过Write Quorum调整强一致性的控制,通过Ack Quorum权衡在有较多副本时也可以有较低的长尾时延(但一致性就可能有一定的损失)。

3. BookKeeper可用性

  • 读的高可用

读的访问是对等的,任意一个节点返回就算读成功。这个特性可以把延迟固定在一个阈值内,当遇到网络抖动或坏节点,通过延迟的参数避障。例如读的延迟时间2ms,读节点3超过2ms,就会并发地读节点4,任意一个节点返回就算读成功,如下图Reader部分。

  • 写的高可用

在openLedger时会记录每个节点的顺序,假如写到5节点宕机,会做一次元数据的变更,从这个时间开始,先进行数据恢复,同时新的index中会把5节点变为6节点,如下图x节点替换5节点:

4. BookKeeper一致性

BookKeeper底层节点对等设计让写入数据的Writer成为了协调者,Writer来保存数据是否存储成功的状态,例如节点是否出现问题、副本够不够、切换Fragment时要不要做数据恢复、在写入过程中出现宕机时,通过fencing的方式防止脑裂等。所以,Writer维护了2个index:LastAddPushed和LastAddConfirmed。

LastAddPushed会随消息ID递增,LastAddConfirmed则记录最后一个连续的消息成功写入了(例如Ack Quorum为2,有2个成功返回了即为成功),但因为返回顺序不一定与消息顺序一致,例如123个消息,3的消息先返回了,2的还未返回,按连续的规则就是2不是3。

5. BookKeeper与Raft的对比

在底层原理上,Raft与BookKeeper有很多类似的地方,Raft每个数据写入的组织形式是term,跟BookKeeper的segment类似,每个term也会选择一组节点存储数据,然后不断往后追加数据,通过数据节点之间的协同保证数据一致性。

在数据结构上,Raft在保存数据时有Entry,Entry除了带本身的index还会带上last committed index,与BookKeeper中的LastAddConfirmed较为类似,只是BK是通过Writer来协调数据在不同节点的一致性,Raft有leader来协调数据在不同节点的一致性。



6. BookKeeper的IO读写分离

下图是每个数据节点的数据流转过程,数据写入时,Writer通过append only方式写入到Journal,Journal在把数据写到内存的同时会按一定频率(默认1ms或500 byte)把数据持久化到Journal Device里,写完后会告诉Writer这个节点写入成功了(持久化到磁盘是默认配置)。

Journal在数据写入时有写到内存中,接下来在内存中做排序(用于解决如果按写的顺序读会导致分区随机性强的问题),然后把数据刷到数据盘中。读的时候,如果读最新的数据,可以直接从内存里返回,如果读历史数据,也只去读数据盘,不会对Journal Device写入有影响。这样针对有读瓶颈或写瓶颈的用户,可以把Journal Disk或Ledger Disk换成SSD盘,提升性能,并且防止读写的互相干扰。

--

03 BookKeeper的存储介质演变

1. BookKeeper的Disk演进

在演进过程中,因为顺序读的情况比较多,所以读的部分变化不大,但在写的这部分经历了HDD到SSD再到NVMe SSD,再到现在部分用户换成了Intel的PMem的过程(如下图所示)。在换到NVMe SSD时,部分用户通过多目录的方式可以把SSD的IO带宽打的很满。

2. PMEM在BookKeeper上的应用

PMem的特性非常匹配Journal Disk,单块PMem可以达到3-4GB的带宽,不但能提供高带宽吞吐而且可持久化。PMem容量相比SSD比较小、相比内存又比较大,在刚推出时单条128GB,有着GB级别的吞吐和ns级别的延迟。

高吞吐低容量的PMem非常适合Journal持久话刷盘的需求,例如宕机后,需要对没刷到磁盘的这部分数据做恢复,需要Journal做replay log重放,由于只是增量日志而非全量数据,所以并不需要很大的容量,正好和PMem容量不大相匹配。而且,PMem的寿命会比SSD的寿命长一些,例如在每天同样写入量下SSD可能只能用1年而PMem预计可以使用4-5年。

雅虎(现在是Verizon Media)有实际通过PMEem优化BookKeeper的案例,在只增加5%的单机成本情况下提升了5倍的带宽吞吐和低于5ms的时延保障(BookKeeper社区与Intel正在合作做性能测试,预计未来会产出白皮书说明)。

在雅虎案例中用10台Pulsar(底层是用PMem做Journal Disk的BookKeeper)替换了33台Kafka,比原Kafka方案成本降低了一半,产出的对比结果如下:

--

04 社区资源

  • 团队构成

由Apache Pulsar核心研发团队创立,同时有Apache Pulsar和Apache BookKeeper项目管理委员会(PMC)主席,有6名Apache Pulsar PMC成员和3名Apache BookKeeper PMC成员,有约20名 Apache Committer。

  • 里程碑

公司成立于2019年,2020年发布商业化产品StreamNative Cloud,目前有50+付费客户,覆盖金融、IoT、互联网、制造多个行业。

  • 优势

是社区和代码的构建维护者,有全球最专业的Pulsar设计开发、运维、管理团队的7*24小时服务,提供开箱即用的云服务和咨询培训服务。




今天的分享就到这里,谢谢大家。


分享嘉宾:



本文首发于微信公众号“DataFunTalk”。

翟佳:高可用、强一致、低延迟——BookKeeper的存储实现的更多相关文章

  1. 理解 OpenStack 高可用(HA) (6): MySQL HA

    本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...

  2. 人人都可以开发高可用高伸缩应用——论Azure Service Fabric的意义

    今天推荐的文章其实是微软的一篇官方公告,宣布其即将发布的一个支撑高可用高伸缩云服务的框架--Azure Service Fabric. 前两天,微软Azure平台的CTO Mark Russinovi ...

  3. 数据库高可用架构(MySQL、Oracle、MongoDB、Redis)

    一.MySQL MySQL小型高可用架构 方案:MySQL双主.主从 + Keepalived主从自动切换   服务器资源:两台PC Server 优点:架构简单,节省资源 缺点:无法线性扩展,主从失 ...

  4. [转]数据库高可用架构(MySQL、Oracle、MongoDB、Redis)

    一.MySQL   MySQL小型高可用架构 方案:MySQL双主.主从 + Keepalived主从自动切换 服务器资源:两台PC Server 优点:架构简单,节省资源 缺点:无法线性扩展,主从失 ...

  5. MySQL高可用之MHA (转)

    MySQL高可用之MHA MHA简介 MHA是由日本人yoshinorim(原就职于DeNA现就职于FaceBook)开发的比较成熟的MySQL高可用方案.MHA能够在30秒内实现故障切换,并能在故障 ...

  6. activitmq+keepalived+nfs 非zk的高可用集群构建

    nfs 192.168.10.32 maast 192.168.10.4 savel 192.168.10.31 应对这个需求既要高可用又要消息延迟,只能使用变态方式实现 nfs部署 #yum ins ...

  7. MongoDB高可用集群配置的方案

    >>高可用集群的解决方案 高可用性即HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性. ...

  8. zookeeper + LevelDB + ActiveMQ实现消息队列高可用

    通过集群实现消息队列高可用. 消息队列在项目中存储订单.邮件通知.数据分发等重要信息,故对消息队列稳定可用性有高要求. 现在通过zookeeper选取activemq leader的形式实现当某个ac ...

  9. 从零开始学spring cloud(八) -------- Eureka 高可用机制

    一.Eureka高可用机制介绍 Eureka服务器没有后端存储,但注册表中的服务实例都必须发送心跳以使其注册保持最新(因此可以在内存中完成). 客户端还有一个Eureka注册的内存缓存(因此,他们不必 ...

随机推荐

  1. 老生常谈系列之Aop--Spring Aop原理浅析

    老生常谈系列之Aop--Spring Aop原理浅析 概述 上一篇介绍了AspectJ的编译时织入(Complier Time Weaver),其实AspectJ也支持Load Time Weaver ...

  2. springboot处理blog字段

    springboot处理blog字段 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章https://www.javaman.cn/ 1.数据库表结构 其中content为long ...

  3. 国产开源优秀新一代MPP数据库StarRocks入门之旅-数仓新利器(上)

    概述 背景 Apache Doris官方地址 https://doris.apache.org/ Apache Doris GitHub源码地址 https://github.com/apache/i ...

  4. 1903021121—刘明伟—Java第三周作业—学习在eclipse上创建并运行java程序

    项目 内容 课程班级博客链接 19信计班(本) 作业要求链接 第三周作业 作业要求 每道题要有题目,代码,截图 扩展阅读 eclipse如何创建java程序 java语言基础(上) 扩展阅读心得: 想 ...

  5. form表单与css选择器

    目录 form表单 action属性 input标签 lable标签 select标签 textarea标签 补充 网络请求方式 CSS简介 CSS基本选择器 组合选择器 属性选择器 分组与嵌套 伪类 ...

  6. Fail2ban 安装Fail2ban到Ubuntu

    系统版本:Ubuntu 16.04.5 LTS 软件版本:fail2ban-0.9.3 硬件要求:无 1.安装Fail2ban root@local:~# apt-get update root@lo ...

  7. 【SSM框架】Spring笔记 --- 事务详解

    1.Spring的事务管理: 事务原本是数据库中的概念,在实际项目的开发中,进行事务的处理一般是在业务逻辑层, 即 Service 层.这样做是为了能够使用事务的特性来管理关联操作的业务. 在 Spr ...

  8. 一些有趣的B+树优化实验

    作为目前数据库引擎的两种主要数据结构,LSM-tree和B+-tree在业界已经有非常广泛的研究.相比B+-tree,LSM-tree牺牲一定的读性能以换取更小的写放大以及更低的存储成本,但这必须建立 ...

  9. 使用FileSystemWatcher监听文件状态

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 一.FileSystemWatcher类型介绍 在.NET中使用 FileSystemWatcher 类型可以进行监视指定 ...

  10. VueX的热更替你知道多少?

    前言 我们在使用Vuex的时候,会时不时的更改Vuex内的数据,但是页面不会随之更新,如果数据量大,一个数据依赖另一个数据的话,这样我们要是再刷新页面的话会把以前依赖的数据清空,效率特别低.所以,今天 ...