DistributedLog介绍及与Kafka比较

来源:互联网 发布:aes算法原理 编辑:程序博客网 时间:2024/06/10 23:27

一、背景介绍

DistributedTwitter 20165月份开源的一个分布式日志系统。在Twitter内部已经使用2年多。

主页:http://distributedlog.io/

代码:https://github.com/twitter/distributedlog

介绍:

1、Building DistributedLog: Twitter’s high-performance replicated log service

  https://blog.twitter.com/2015/building-distributedlog-twitter-s-high-performance-replicated-log-service

2、【年度案例】Twitter高性能分布式日志系统架构解析

 

二、架构介绍

2.1 数据存储

 

数据模型


Log Segment:应用程序看到的Log 流是连续的,但物理存储是一个个的Log Segment

1、  同一个Log Segment上的Replica Configuration是一样的

2、  Log Segment可以设置按时间或者按大小,创建新的。

3、  Log Segment 分布式的存储在 Log Segment Store中。

4、  系统中的Log Segments最终会分散在各个节点上,数据读取就不会产生热点节点。

5、  Log Segment也是数据保留单元。即可以按照超时时间配置TTL,也可手动truncate

 

Log Sequence Number

 日志记录(Log Record)被顺序的写入Log Stream中,并且被分配一个DLSNDistributeLog Sequence Number)。Writer自动分配的。

DLSN = LSSN + EID + SID

LSSNLog Segment Sequence Number    -- 属于哪个Log Segment 

EIDEntry ID                         -- 在这个Log Segment中的ID

SIDSlot ID                          --  Entry 中的ID

 

日志记录可以根据DLSN排序。

 

除了DLSN,应用程序还可以分配一个 Transaction ID(递增的64位正整数)。比如一个常见的场景是,应用把记录生成时的timestamp作为记录的Transaction ID。在继续数据分析时,应用可以根据这个Transaction Id倒回到指定的时刻的日志。

 

命名空间(Name Space)

   属于相同的应用下的日志流(Log Streams)被归类到同一个命名空间(namespace)下。

应用根据命名空间定位日志流。应用能够在命名空间下创建和删除日志流,或者指定日志流ID,切除(truncate)日志流。

 

2.2读写过程


持久化存储

   DL的存储层(Storage Layer),提供持久化、可用性和一致性等核心功能。存储层的主要组件有日志段存储(Log Segment Store)、冷数据存储(Cold Storage)、元数据存储(Metadata Store)。

 

日志段存储(Log Segment Store

  使用BookKeeper做日志段的存储。BookKeeper提供从写入到读取的E2E的低时延、多副本的存储能力,并且通过fencing机制,在多份写时,能够提供强一致性。

 

冷数据存储(Cold Storage

 在日志段中存储的数据最终都会移动到冷数据存储中。应用在故障恢复或者调试时,可能需要旧的数据,可以从冷数据存储中读取。冷数据是使用HDFS存储。

 

元数据(Metadata Store

Metadata存储在zookeeper上。Metadata包含日志流(log streams)与日志段(log segment)的映射关系,以及日志段(log segment)的元数据。日志段的元数据包含:log segment ID, startend transaction IDscompletion time status

元数据服务器需要具有如下功能:一致性读写,故障时严格保序、通知机制。

 

DistributedLog 核心(DistributedLog Core

 DL的核心是构建在Log segment storebookkeeper)和元数据存储(zookeeper)之上的。它提供日志流、命名空间和提供single-writer-multiple-reader的数据访问模型。DL核心包含

Writer  Reader两个组件。

 

Writer

Writer会将数据写入到它们所选择的Log中。所有的记录都会按照顺序添加到Log之中。序列号(DLSN)是由Writer所负责的,这就意味着对于某个Log,在给定的时间点上,只能有一个激活的Writer。当出现网络分区(network partition),导致两个Writer试图往同一个Log进行写入的时候,DL会保证其正确性,这是通过Log分段存储的屏障(fencing)来实现的。

Writer由名为Write Proxy的服务层来提供和管理,Write Proxy用来接受大量客户端的fan-in写入。

Reader

Reader会从它们所选择的Log中读取记录,这会在一个给定的位置开始。这个给定的位置可以是DLSN,也可以是TransactionIDReader将会严格按照Log的顺序读取记录,并且保证每个消息指读取一次。在同一个Log中,不同的Reader可以在不同的起始位置读取记录。

与其他的订阅/发布系统不同,DistributedLog并不会记录/管理Reader的位置,它将跟踪的任务留给了应用程序本身,因为不同的应用在跟踪和协调位置上可能会有不同的需求,很难用一种方式就将这些需求全部解决。在应用程序层面,借助各种存储(如ZooKeeperFileSystemKey/Value存储)能够很容易地跟踪Reader的位置。

Log记录可以缓存在名为Read Proxy的服务层中,从而应对大量Reader的读取。

无状态的服务器层(Stateless Serving

无状态服务层构建在DistributedLog Core之上,支持大量的WriterReader。服务层包含Write ProxyRead ProxyOwnership TrackerRouting ServiceWrite Proxy管理LogWriter,并且在机器宕机时,能够对它们进行故障恢复。它能够从众多来源聚集写请求。Read Proxy通过将记录放到缓存中,优化了Reader的读取路径,以应对成百上千的Reader读取同一个Log流的状况。Fan out,一个日志流,多个读Read Client

Log Stream所有者跟踪(Ownership Tracker

Log Stream的所有者跟踪管理活着的Writer Proxy。并且在故障时,切换到健康的Writer Proxies上。跟踪记录通过在zk上建立临时节点管理的。Writer节点。

 

路由服务(Routing Service

因为Reader只能读取已经提交(committed)的数据,所以Reader proxy不需要跟踪log streamReader Proxy的关系。DL使用一致性哈希作为把Reader路由到Reader Proxies上的路由机制。

应用既可以使用瘦客户端(thin client)连接DL的服务层,当需要严格严格保序时也可以通过嵌入了core lib的方式直接访问存储层。应用根据自身需求去选择分区策略并跟踪读取的位置,DL本身不做分区策略,不存储已读取的位置。

 

消息生命循环(Lifecycle of records


Write过程:

Step1:应用(WC)创建日志消息并发起一个写请求。

Step2:写请求发往WPWrite Proxy),Master WP将在本地缓存该记录,缓冲区的消息会批量的发往Log Segment StoreBookies),应用可以在时延和吞吐率上做出权衡,选择低时延,则立即发送;选择高吞吐则周期发送或者当缓冲区超过最大字节数时发送。

Step3:批量的记录并行的发往多个bookiesbookkeeper的节点)。Bookies持久化该消息后,回应WP

Step4WP接收到多数(quorum)个的回应时,则回应ack消息给WC,写入成功。

Step5:尽管WriterWP选择的)写入成功(多副本、持久化)。但是各个bookies并不知道这些。所以WP需要再发送一个commit消息给bookies,该消息记录才对所有Reader可见(可读取)。Commit消息可以随下一次的批量记录一起发送,如果在SLA时间内,没有新消息需要发送,WP会单独发生一个control log record通知给所有bookies

Step6Reader使用Long Polling(常轮询)方式读取最新提交的消息记录。

Step7Speculative常轮询读从其它副本读取数据,可以预先降低99.9%的时延。

Step8:读取的数据将被缓存在RP上,以提升扇出(多读)效率。

Step9RC也是使用 Long Poll读机制从RP上读取数据。

 

2.3 备份

日志流(Log Stream)可以配置副本数。

 

2.4 多租户

Namespace支持多租户。

 

2.5  安全

传输安全,没看到。

存储安全,bookkeeper 也没看到。

 

2.6  rack-aware  region-aware

支持。

 

三、应用场景介绍

目前只有Twitter内部使用,下面场景都是其内部使用场景。

1Manhattan 数据库

2EventBus (Twitter自服务的 pubsub system,用于取代 Kafka

3、跨数据中心的数据库复制

4Twitter 搜索的 ingestion pipeline

5、持久化的 Deferred RPC 系统

6、用于存储系统的 Sharding Service

                                          

 

四、与Kafka比较

 

Kafka

DistributedLog

开发语言

Scala/java

Java

元数据/协调

Zookeeper

Zookeeper

JMSMQTT等协议

不支持

不支持

持久化

支持

支持

数据自动删除

支持/可配置

支持/可配置、可手动删除truncate

备份/多副本

支持

支持,bookkeeper多副本

多租户

不支持

支持

Rack/DC感知部署

只支持Rack0.10版本)

支持

开源协议

Apache 2.0

Apache 2.0

主要支持公司

LinkIn/Conflunce.io

Twitter

分区能力

支持

不支持(上层应用实现)

消息回溯

支持offset回溯

支持DSLN和用户自定义的Transaction Id 两种方式。

读取零拷贝

支持

不支持。消息需要读取到Reader Proxy缓存区。由于各种读取策略,不一定会延时大。

实时消费

通过Long Polling机制。没有额外的watch机制。

支持,有watch机制。一旦有新数据写入,立即触发读取。

海量Topic

一个partition多个文件。有瓶颈

bookie上,所有记录都是混合在一起,写入文件entry log file。一个entry log file达到了设置的大小,将生成新的文件。且有compact机制。

多客户端写入同一日志(Fan-in

Topic的每个分区一个leader。受限于Broker数目。

每个Log Stream只有一个Writer,多副本也是需要LeaderWriter/Writer Proxy虽然无状态,还是受限于Bookkeeperbookies数目。

多客户端读取同一日志(Fan-out

受限制,不灵活。扩充Broker需要相应的调节topic分区,且需要调整分区分布。

扩展无状态的reader proxy 支持fan-outRP可以缓存读。可以从副本读取数据。

读取位置管理(offset

支持

不支持(上层应用实现)

消费组(Sub/PUB)概念

支持

不支持(上层应用实现)

故障恢复(读写)

支持 / 故障恢复。Leader balance能力。

支持读写故障恢复。写 fencing特性。

Reader Proxy路由切换。

故障恢复(数据)备份安全

不支持故障的replica自动复制到其它broker。提供了工具。

bookkeeper不支持自动,提供了工具支持。

消息大小

通过配置文件可以限制。

不支持。

限流/限速

支持粗粒度,每个客户端在每个Broker上限制。不能全局限速,且是bpsbyte per second)。

支持粗细粒度。

粗粒度:proxy限速。

细粒度:每个stream 限速。

支持bpstps两种模型。

 

总结:

1  1、Kafka可以归类为消息系统(MQ),而DistributedLog不能,只是一个分布式日志系统。很多消息系统的特性,不支持。

2、  2、DL的分层架构,可以参考。存储有状态与服务无状态,使得存储节点与服务节点(CPU/内存)可以独立扩展。

3、  3、KafkaDL都依赖zookeeper存储元数据。Kafkazookeeper比较明显,比如消费者不需要连接zkDL消费者也不需要经过zk。在多节点时(Brokers),若有瓶颈,都是一样的。


1 0
原创粉丝点击