Apache BookKeeper 简介

原作者:Sijie Guo
翻译:StreamNative-Sijia

Apache BookKeeper 是企业级存储系统,旨在保证高持久性、一致性与低延迟。Pulsar 由雅虎研究院(Yahoo! Research)开发,旨在实现 Hadoop 分布式文件系统(HDFS)NameNode 的高可用,在此之前,NameNode 不具备高可用特性,存在单点故障的问题。自 2011 年起,BookKeeper 开始在 Apache ZooKeeper 下作为子项目孵化,并于 2015 年 1 月作为顶级项目成功问世。在这四年间,Twitter、Yahoo、Salesforce 等公司使用 BookKeeper 存储和服务重要数据,并支撑了许多不同场景。本文将简要介绍 BookKeeper 的概念和相关术语。

背景介绍

BookKeeper 的开发者(Benjamin Reed、Flavio Junqueira、Ivan Kelly)凭借搭建 ZooKeeper 的经验设计了一个灵活的系统,能够支持多种工作负载。最初,BookKeeper 是分布式系统的预写式日志(WAL)机制。现在 BookKeeper 已经发展成为支持多个企业级系统的基础构建模块,如:Twitter 的 EventBus、雅虎的 Apache Pulsar 等。

BookKeeper 是什么?

BookKeeper 是一种优化实时工作负载的存储服务,具有可扩展、高容错、低延迟的特点。根据我们多年的工作经验,企业级的实时存储平台应符合以下几项要求:

  • 以极低的延迟(小于 5 毫秒)读写 entry 流
  • 能够持久、一致、容错地存储数据
  • 在写数据时,能够进行流式传输或追尾传输
  • 有效地存储、访问历史数据与实时数据

BookKeeper 的设计完全符合以上要求,并广泛用于多种用例,例如为分布式系统提供高可用性或多副本(如 HDFS NameNode 节点、Twitter 的 Manhattan key-value 存储);在单个集群中或多个集群间(多个数据中心)提供跨机器复制;为发布/订阅(pub-sub)消息系统(如 Twitter 的 EventBus、Apache Pulsar)提供存储服务;为流工作存储不可变对象(例如:检查点数据的快照)等。

BookKeeper 的概念及术语

BookKeeper 复制并持久存储日志流。日志流是形成良好序列的记录流。

记录

数据以不可分割记录的序列,而不是单个字节写入 Apache BookKeeper 的日志。记录是 BookKeeper 中最小的 I/O 单元,也被称作地址单元。单条记录中包含与该记录相关或分配给该记录的序列号(例如递增的长数)。客户端总是从特定记录开始读取,或者追尾序列。也就是说,客户端通过监听序列来寻找下一条要添加到日志中的记录。客户端可以单次接收单条记录,也可以接收包含多条记录的数据块。序列号也可以用于随机检索记录。

日志

BookKeeper 中提供了两个表示日志存储的名词:一个是 ledger(又称日志段);另一个是 stream(又称日志流)。

Ledger 用于记录或存储一系列数据记录(日志)。当客户端主动关闭或者当充当 writer 的客户端宕机时,正在写入此 ledger 的记录会丢失,而之前存储在 ledger 中的数据不会丢失。Ledger 一旦被关闭就不可变,也就是说,不允许向已关闭的ledger 中添加数据记录(日志)。

image

图1 BookKeeper ledger:有界数据 entries 序列

Stream(又称日志流)是无界、无限的数据记录序列。默认情况下,stream 永远不会丢失。stream 和 ledger 有所不同。在追加记录时,ledger 只能运行一次,而 stream 可以运行多次。一个 stream 由多个 ledger 组成;每个 ledger 根据基于时间或空间的滚动策略循环。在 stream 被删除之前,stream 有可能存在相对较长的时间(几天、几个月,甚至几年)。Stream 的主要数据保留机制是截断,包括根据基于时间或空间的保留策略删除最早的 ledger。

image

图2 BookKeeper stream:无界数据记录 stream

Ledger 和 stream 为历史数据和实时数据提供统一的存储抽象。在写入数据时,日志流流式传输或追尾传输实时数据记录。存储在 ledger 的实时数据成为历史数据。累积在 stream 中的数据不受单机容量的限制。

命名空间

通常情况下,用户在命名空间分类、管理日志流。命名空间是租户用来创建 stream 的一种机制,也是一个部署或管理单元。用户可以配置命名空间级别的数据放置策略。同一命名空间的所有 stream 都拥有相同的命名空间的设置,并将记录存放在根据数据放置策略配置的存储节点中。这为同时管理多个 stream 的机制提供了强有力的支持。

Bookies

Bookies 即存储服务器。一个 bookie 是一个单独的 BookKeeper 存储服务器,用于存储数据记录。BookKeeper 跨 bookies 复制并存储数据 entries。出于性能考虑,单个 bookie 上存储 ledger 段,而不是整个 ledger。因此,bookie 就像是整个集成的一部分。对于任意给定 ledger L,集成指存储 L 中 entries 的一组 bookies。将 entries 写入 ledger 时,entries 就会跨集成分段(写入 bookies 的一个分组而不是所有的 bookies)。

元数据

BookKeeper 需要元数据存储服务,用来存储 ledger 与可用 bookie 的相关信息。目前,BookKeeper 利用ZooKeeper 来完成这项工作(除了数据存储服务外,还包括一些协调、配置管理任务等)。

与 BookKeeper 交互

与 bookie 交互时,BookKeeper 应用程序有两个主要作用:一个是创建 ledger 或 stream 以便写入数据;另一个是打开 ledger 或 stream 以便读取数据。为了与 BookKeeper 中两个不同的存储原语交互,BookKeeper 提供了两个 API。

API 说明
Ledger API 较低级别的 API,允许用户直接与 ledger 交互,极具灵活性,用户可根据需要与 bookie 交互。
Stream API 较高级别、面向流的 API,通过 Apache DistributedLog 实现。用户无需管理与 ledger 交互的复杂性,就可以与 stream 交互。

选择使用哪个 API 取决于用户对 ledger 语义设定的的粒度控制程度。 用户也可以在单个应用程序中同时使用这两个 API。

放在一起看

下图即为 BookKeeper 的典型安装示例。

典型的 BookKeeper 安装(通过多个 API 连接的应用程序)

上图中的几个注意事项:

  • 典型的 BookKeeper 安装包括元数据存储区(如 ZooKeeper)、bookie 集群,以及通过提供的客户端库与 bookie 交互的多个客户端。
  • 为便于客户端的识别,bookie 会将自己广播到元数据存储区。
  • Bookie 会与元数据存储区交互,作为回收站收集已删除数据。
  • 应用程序通过提供的客户端库与 BookKeeper 交互(使用 ledger API 或 DistributedLog Stream API)
    • 应用程序 1 需要对 ledger 进行粒度控制,以便直接使用 ledger API。
    • 应用程序 2 不需要较低级别 ledger 控制,因此使用更加简化的日志流 API。

总结

本文对 BookKeeper 进行了技术层面的概述,首先介绍了 entry、ledger、stream、命名空间、bookie 的概念,然后介绍了典型的 BookKeeper 部署,以及如何处理数据等。

如果你对 BookKeeper 或 DistributedLog 感兴趣,可以通过以下方式加入我们的社区:

  • BookKeeper Slack channel。你可以在 https://apachebookkeeper.herokuapp.com/ 注册。
  • BookKeeper email list。

想要了解更多关于 Apache BookKeeper 项目的信息,请访问官方网站:http://bookkeeper.apache.org,或在 Twitter 上关注 @asfbookkeeper。

想要随时掌握 Pulsar 的研发进展、用户案例和热点话题吗?快来关注 Apache Pulsar 和 StreamNative 微信公众号,我们第一时间在这里分享与 Pulsar 有关的一切。

原文链接:https://www.splunk.com/en_us/blog/it/introduction-to-apache-bookkeeper.html

你可能感兴趣的:(Apache BookKeeper 简介)