【存储架构】云上坚不可摧的存储Apache Bookkeeper
关键点
- 使存储系统具有云感知的传统方法是提升和转移方法。虽然它是有效的,但根据我们的经验,投资重构架构,使其更能感知云,可以产生更好的结果。
- 在跨区域环境中部署Apache BookKeeper的当前解决方案需要将BookKeeper存储节点手动映射到特定的区域/可用性区域,但这并不能在区域中断期间提供相同的持久性和可用性保证。
- Salesforce使Apache BookKeeper具有云感知的独特方法包括为BookKeeper存储节点提供智能,以便它们在基于云的部署中有效运行,同时保持BookKeeper保证的持久性和可用性。
- 这些新增功能使集群更容易打补丁、升级和重新启动,对使用服务的影响最小。
在Salesforce,我们需要一个可以处理两种流的存储系统,一种是写前日志(write-ahead logs WAL)流,另一种是数据流。但是我们有来自两个流的竞争需求。预写日志流应该是写的低延迟和读的高吞吐量。数据流应该具有高的写吞吐量,但具有低的随机读延迟。作为云计算的先驱,我们也要求我们的存储系统能够感知云,因为对可用性和持久性的要求越来越高。我们的部署模型被设计为不可变的,以便能够扩展到大规模的级别并在普通硬件上运行。
开源替代
我们对这种存储系统的最初研究遇到了构建还是购买的问题。
考虑到我们所有的期望和需求都取决于上市时间、资源、成本等主要业务驱动因素,我们决定采用开源存储系统。
在研究了开源所能提供的服务之后,我们确定了两种最终的选择:Ceph和Apache BookKeeper。随着系统对我们的客户可用的需求,规模到大规模的水平,也作为一致的事实来源,我们需要确保系统可以满足我们用例的CAP定理的方面。让我们鸟瞰一下BookKeeper和Ceph在CAP定理(一致性、可用性和分区容忍度)和我们独特的要求方面的立场。
Ceph提供了一致性和分区容忍,而读路径可以提供不可靠读取的可用性和分区容忍。要让写路径提供可用性和分区容忍度,还有很多工作需要做。我们还必须记住部署的不可变数据需求。
我们决定Apache BookKeeper是我们用例的明确选择。它接近于我们所需要的CAP系统,因为它的数据存储设计是只附加/不可变的,并且是高度复制的分布式日志。其他主要特点:
- 一旦一个写入被确认,它总是可读的。
- 一旦一个条目被读取,它总是可读的。
- 没有中央主服务器,厚客户机,使用Apache Zookeeper来达成共识和元数据。
- 没有复杂的散列/计算的数据放置。
此外,Salesforce一直鼓励开源,Apache BookKeeper社区是一个活跃且充满活力的社区。
Apache BookKeeper -几乎完美,但需要更多的工作
虽然Apache BookKeeper已经为我们的需求检查了大多数框,但仍然有差距。在我们进入差距之前,让我们了解一下Apache BookKeeper提供了什么。
- 每个存储节点都被称为赌徒(bookie)。“Ensemble”是一组赌徒。
- “条目”(Entry)是你能写的最小单位。它也是不可变的。
- 一个“分类账”(Ledger)是由一系列的条目组成的,这些条目也遵循了一个不可变的只添加的模型。
- “写入仲裁”(write quorum)是指将数据写入或复制到该条目的最大复制数。
- “ack quorum”是在确认写入之前确认数据的赌徒数量——条目的最小复制。
从耐久性的角度来看,账本被复制到一个赌徒的集合中,账本内的条目也贯穿于整个集合中。
Ensemble Size: 5 Write Quorum Size: 3 Ack Quorum Size: 2
写入是基于可配置的写入和确认仲裁进行确认的。这提供了较低的写延迟和扩展能力。
然而,事实证明,在云中的商用硬件上运行BookKeeper具有挑战性。
数据放置策略不是原生云感知的,也没有考虑到底层的公共云提供商(云底层)。一些用户目前部署它的方式是手动识别不同可用性区域中的节点,将它们逻辑地分组在一起,并在这些节点组上改进现有的放置策略。虽然这是一种解决方案,但它不提供对区域故障的任何支持,也不提供维护和升级大规模集群时的易用性。
众所周知,所有的云底层都经常出现跨可用性区域的宕机,一般的理解是应用程序应该针对这些故障进行设计。一个很好的例子是Netflix在2012年圣诞节期间受到了亚马逊网络服务可用区中断的影响。Netflix的服务一直以有限的容量运行,即使它所依赖的底层公共云基础设施宕机了。
公共云中的问题
互联网——从网站到应用程序,甚至企业软件——大多运行在公共云提供商提供的基础设施上。这是因为公共云基础设施易于扩展,并且在一定程度上使用和维护成本更低。然而,它也有其缺陷,其中之一就是节点、区域或区域级别的不可用性。如果底层基础设施不可用,那么用户实际上什么也做不了。这可能是由于某些机器、区域或区域的停机。它甚至可能是由于硬件故障导致的网络延迟增加。因此,最终,作为在这个公共云基础设施上运行的应用程序,我们——开发人员——在设计时要考虑到它的缺点。
Apache BookKeeper没有针对这种可能性的内置答案,因此我们需要设计一个修复程序。
Salesforce 的重新架构
现在我们对问题有了大致的了解,我们开始思考如何修复它们,以便使Apache BookKeeper具有云感知并符合我们的需求。我们将这些差距归纳如下:
- Bookies 需要在公共云中的集群中提供一个身份。
- 为了提供更好的可用性、更容易的维护和更平滑的部署,需要将数据放置策略设计为根据可用性区域分布的集成。
- 现有的博彩功能(如读、写和数据复制)需要更改,以便利用多区域布局,并考虑跨这些区域传输数据的成本。
- 所有这些都应该是云底物不可知的。
让我们看看我们是如何解决这些差距的。
用于云感知的cookie和Kubernetes
现有的BookKeeper架构为每个赌徒提供了在其首次启动时分配的唯一标识。这个标识持久化在元数据存储中(Zookeeper),其他赌徒或客户可以访问它。
让Apache BookKeeper具有云感知的第一步是让每个赌徒知道他们在Kubernetes中部署的集群中的位置。我们认为这些饼干是最好的信息来源。
我们在cookie中添加了一个名为“networkLocation”的字段,该字段由两个可以定位赌徒的主要组件组成——可用性区域和升级域。使用Kubernetes允许我们不考虑底层,所以我们使用Kubernetes api来查询底层可用性区域信息。我们还根据一个涉及主机名序号索引的公式生成' upgradeDomain '。upgradeDomain可以用于滚动升级,而不影响集群的可用性。
所有这些信息都是在启动时生成的,并持久化到元数据存储中以供访问。
现在可以在生成集合、向集合指定赌徒以及决定从哪个赌徒复制或复制到哪个赌徒时使用这些信息。
公共云放置策略
现在我们在客户端中有了智能,这样它就可以与特定区域的赌徒通信,我们需要确保我们有一个利用这些信息的数据放置策略。我们的一个独特的发展是ZoneAwareEnsemblePlacementPolicy (ZEPP)。它是专为基于云的部署而设计的两级分层放置策略。ZEPP知道可用分区(AZ)和升级域(UD)。
AZ是区域内逻辑隔离的数据中心。UD是AZ内的一组节点,可以一起关闭,对服务没有影响。它还提供了理解区域何时停止和何时恢复的启发式方法。
下面是ZEPP可以使用的一个可视化部署。此部署考虑来自cookie的AZ和UD信息来对赌徒节点进行分组,如图所示。
可用性、延迟和成本
通过这些改变,我们已经能够使Apache BookKeeper真正具有云意识。然而,在设计此架构时考虑成本也很重要。大多数云基质对其服务之外的单向数据传输收费,跨可用性区域时收费是不同的。对于BookKeeper客户端来说,这是需要考虑的一个重要因素,因为它目前从集合中任意选择一个赌徒来满足读取。
如果赌徒是来自另一个可用区域比客户,这将导致不必要的收费。数据复制现在将在分布在可用性区域的赌徒之间进行,在可用性区域下降的情况下将导致更多的成本。
让我们看看如何处理这些特定的场景。
重新排序读取
目前,簿记员(BookKeeper )客户端从一个集合中任意选择一个赌徒来满足阅读。
通过我们的重新排序读取功能,客户端现在选择了一个赌徒,这样可以最小化读取延迟,同时降低成本。
重新排序读取功能开启后,客户端按以下顺序选择赌徒:
- 从本地区域按能满足请求和有更少未决请求的赌徒顺序排序。
- 从一个远端区域按能满足请求和有较少待处理请求的赌徒顺序。
- 下一个来自本地区域的赌徒,其失败次数最少或未挂起的请求超过配置的阈值
- 下一个来自远程区域的赌徒,其失败次数最少或未挂起的请求超过配置的阈值
按照这个顺序,我们在一个运行了很长时间并经历过故障的系统中进行了适当的权衡,以满足延迟和成本需求。
处理区域故障
在区域下降的情况下,现在来自不同集合的所有赌徒将开始复制他们的数据到当前可用区域的赌徒,以满足集合的规模约束和法定人数要求,造成一个“雷鸣群体问题”。
我们处理这个问题的方法是,首先决定一个区域什么时候实际上是下降的。故障可能是短暂的信号;我们不希望仅仅因为一个网络信号导致一个区域不可用而开始复制tb级的数据。与此同时,我们想要为真正的失败做好准备。
我们的解决方案有两个阶段:
- 识别一个区域什么时候真正下降,什么时候是暂时的波动。
- 将整个区域的大规模自动复制移动到手动操作中。
下面的图表显示了我们在声明区域关闭和区域恢复时考虑的启发式。
HighWaterMark和LowWaterMark是两个值,它们是根据一个区域中可用的赌徒数量与该区域中总赌徒数量计算的。这两个值的阈值是可配置的,因此用户可以根据他们认为的故障来决定故障的灵敏度。
当一个区域被标记为down时,我们还禁用自动复制,以避免跨区域自动复制tb级的数据。我们在其位置上添加了警报,以提醒用户可能出现的区域故障。我们相信,运营专家能够区分噪音和真正的故障,并决定是否启动整个区域的自动复制。
我们还提供了启动已禁用的自动复制的赌徒shell命令。
我们学到了什么
Apache BookKeeper是一个非常活跃的开源项目,并拥有一个令人惊讶的支持社区,社区中对该系统面临的所有挑战进行了充满活力的讨论。由于它是许多用户的真实来源,它需要成为云感知。
然而,这样的架构更改在每个级别上都有权衡和决定因素——可用性、延迟、成本、部署和维护的便利性。上述考虑和改变已经在Salesforce进行了战斗测试,现在我们可以使用Apache BookKeeper支持AZ和AZ+1故障。我们已经合并了一些更改,并将在未来的版本中继续为社区做出更多贡献。这些添加的目的是使集群更容易打补丁、升级和重新启动,同时对使用服务的影响最小。
关于作者
Anup Ghatage是旧金山的一位软件开发人员。
他喜欢在维护和开发高度可伸缩的系统中挑战问题。他目前是Salesforce的技术人员领导成员,在那里他致力于云基础设施和数据工程。他也是Apache Bookkeeper的提交者和积极贡献者。他曾任职于SAP和思科系统公司,拥有浦那大学计算机科学学士学位和卡内基梅隆大学硕士学位。你可以在推特@ghatageanup上联系到Anup。
原文:https://www.infoq.com/articles/storage-cloud-apache-bookkeeper/
本文:http://jiagoushi.pro/node/1505
讨论:请加入知识星球【首席架构师圈】或者小号【cea_csa_cto】或者QQ【2808908662】
- 125 次浏览