您的位置:首页 > 其它

几种分布式消息系统比较(old)

2016-03-24 09:56 211 查看
0 引言

         随着互联网行业的发展和IT技术在行业内的广泛应用,许多互联网企业的服务器每天产生海量的日志。如天翼阅读平台每天产生的PV日志有上亿条;淘宝网每天的用户行为日志达数TB大小。如何高效地收集日志,并根据不同的时延要求向下游系统转发,是一个巨大的挑战。

         传统日志收集技术使用大容量高吞吐的日志服务器收集集群中每台机器的本地日志,再向下游系统转发。这种架构有以下缺陷:

n  业务服务器需要先将内存数据持久化到硬盘,写文件操作耗时,且每台主机均保存大量(数以万计甚至更多)个日志文件,扫描一遍即耗时很久。

n  日志服务器采集上游日志通常使用Pull方式。当上游业务服务器集群台数较多时,由于文件句柄、网络带宽等诸多限制,日志服务器只能间隔一定时间(如30分钟)扫描一次,无法保证实时性。

n  采集链路的负载均衡是人肉实现的,一旦上游服务器集群配置发生变化,需要大量人工配置以重新实现负载均衡。

n  日志服务器为保证效率,通常使用小型机挂载集中式存储的模式,扩容困难且成本高昂。

为解决这些问题,近年来多家业界巨头开发了自己的分布式消息采集系统,其中有多个均已开源。这些系统的典型特征有:

n  将业务服务器和下游分析服务器解耦,为两者提供数据传递的桥梁。

n  较高的可靠性和扩展性,当采集的消息规模扩张时,可通过增加集群节点数量进行扩容。

n  能提供达毫秒级的转发延迟,支持Storm这样的实时计算框架和Hadoop这样的离线计算框架。

本文试比较以下几种系统的特性和优劣,希望能起到抛砖引玉的作用。

 

1 Kafka

         Kafka是Linkedin于2010年12月开源的项目,使用scala语言编写。(为避免学习scala这种较冷门又较古怪的语言,可参考Kafka的Java语言克隆物:Jafka)为实现高实时性和可扩展性,Kafka使用了多种效率优化方案,整体架构比较新颖。

         主要特性:

n  使用zero-copy技术,数据在磁盘上存取代价为O(1)

n  高吞吐率,笔者的团队测试,在千兆网下,单个broker每秒可处理数万条1KB消息,吞吐率高于30MB/s,即单点3万TPS

n  显式分布式,即所有的producer、broker和consumer都会有多个,均为分布式的

n  支持将数据并行的加载到Hadoop中

系统主要部件:


Producer:向Kafka的主题(topic)发送消息,即上游服务器向Kafka的broker
push消息的进程。Producer负责选择某条消息发送给哪个topic的哪个partition。为实现负载均衡,用户可使用简单的round
robin算法或其他切片方法,亦或使用Kafka提供的高级接口中的Partitioner实现。比较遗憾的是,当前版本的Kafka并未提供producer和broker间的负载均衡机制,下文架构图上将各台broker连接到zookeeper,只是为了实现broker的自动识别。Producer可通过zookeeper获取可用的broker列表,也可在zookeeper中注册listener,当增加broker服务器数量或broker挂掉时,均可以通知到producer,并采取相应的措施。


Broker:Kafka集群中的每台服务器即为一个broker,其采取了多种策略提高数据处理效率,包括zero-copy和sendfile调用等技术。


Consumer:向一个或多个topic注册,以接收发送到这些topic的消息,即消费消息的进程或服务器。Kafka提供了两种consumer接口:simple接口使用无状态连接从broker
pull数据,每次均需告诉broker偏移量;high level接口则隐藏了broker的细节,使用流方式从broker
pull数据。另外,broker和consumer间使用zookeeper进行负载均衡。

图表1 Kafka整体架构

         笔者的团队使用6台PC
Server作为broker测试Kafka性能,每台4个CPU+32G内存。在启动1个broker时,数据吞吐量约为30MB/s,陆续增加broker数量,当达到4个broker时,吞吐量约为130MB/s,达到千兆网络带宽上限。说明Kafka有很好的横向扩展能力,当增加节点数量时,吞吐量基本呈线性增长,见图表2。

图表2 broker数量和发送速率

 

2 Flume

         Flume是Cloudera于2009年7月开源的项目,使用Java编写。它内置组件齐全,使用简单,并且和Cloudera自己的Hadoop版本有很好的结合。Flume的历史版本(1.0前,现称为FlumeOG)采用agent,collector,storage的三层架构。为解决FlumeOG代码过于复杂、核心组件生命周期管理等问题,在1.0版本后(现称为FlumeNG)架构有了较大的更新,下文均以FlumeNG为准。

         主要特性:

n  高可靠性。Flume提供了end to end的数据可靠性机制,每次传输数据agent均将事件记录到channel中,随后将事件发送给数据流中下一跳的agent或数据的最终存储者,仅当下一跳的agent或数据的最终存储者确认接收成功后,当前agent删除消息,如未确认或校验失败则重新发送。Flume还使用了事务机制来保证事件传递的可靠性。

n  易于扩展。Agent为分布式架构,可水平扩展。

n  易于恢复。Channel中保存了于数据源有关的事件,用于失败时的恢复。Flume支持基于本地文件系统的文件channel。同时也支持基于内存队列的内存channel,比文件channel更快速,但当agent线程失败时内存channel中尚未处理的事件无法用于恢复。

n  功能丰富。Flume内置了多种组件,包括不同数据源(file, syslog,
queue)使用的agent,各种存储方式(Linux FS, HDFS等)。

系统主要部件:


Agent:一个agent包含source、channel、sink和其他的组件。Flume就是一个或多个agent构成的。


Source:数据源。简单的说就是agent获取数据的入口。


Channel:管道,数据流通和存储的通道。一个source必须至少和一个channel关联。


Sink:用来接收channel传输的数据并将之传送到指定的地方。传送成功后数据从channel中删除。

图表3 Flume整体架构

         笔者的团队尝试用Flume采集服务器上的文件日志,并传递给下游Kafka系统。通过编写KafkaSink,Flume可将channel中的数据向Kafka传递,作为Kafka的producer输入,效果很好。

 

3
10904
Chukwa

         Chukwa是2009年11月开源的一个Apache项目,使用Java编写,属于hadoop系列组件中的一员,因此也引用了其他许多hadoop组件,如HDFS和MapReduce等。

         主要特性:

n  灵活性,动态可控的数据源

n  高性能,存储系统具备高扩展性

n  提供了对收集到的大规模数据进行分析的框架

系统主要部件:


Adaptor:用于封装数据源,目前支持多种数据源,如hadoop logs,file,linux命令行,linux系统参数数据等。


Agent:给adaptor提供各种服务,包括启动和关闭adaptor,将数据传递给collector,记录adaptor状态用于失败恢复等。


Collector:可对多个数据源发送来的数据进行合并,然后加载到HDFS中。鉴于HDFS适合处理少量大文件和低并发的高速写入,而日志系统往往需要处理大量小文件和高并发的低速写入,为处理这对矛盾,Chukwa让collector对小文件进行合并后再写入集群。同时Chukwa允许设置多个collector,agent负责处理collector的单点故障或繁忙情况(但还不是负载均衡)。以上三者是Chukwa的3个主要角色。


HDFS:Chukwa使用HDFS作为文件系统。Collector上合并机制的存在使得使用HDFS存储海量日志成为可能。


Demux和archive:Chukwa使用MapReduce分析集群上的日志文件,为此提供了demux和archive两种作业类型,demux作业负责对数据的分类、排序和去重;archive作业则负责把同类数据文件进行合并。


HICC:负责数据的展示。

图表4 Chukwa整体架构

 

4 Scribe

         Scribe是Facebook于2008年10月开源的消息收集系统,在Facebook公司内部大量应用,使用C/C++编写。它为日志的分布式收集、统一处理提供了一个可扩展的、高容错的方案。

         主要特性:

n  高可靠性。当后端的存储系统crash时,scribe会将数据写到本地磁盘上,当存储系统恢复正常后,scribe将日志重新加载到存储系统中。

n  数据源须通过thrift传输数据,thrift客户端可使用各种主流语言编写。

n  支持多种存储模式,包括file,thrift file,bucket(多个store),network(另一个scribe服务器)等。

系统主要部件:


Scribe agent:scribe agent实际上是一个thrift client。scribe内部定义了一个thrift接口,用户使用该接口将数据发送给server。


Scribe:scribe接收到thrift client发送过来的数据,根据配置文件,将不同topic的数据发送给不同的对象。


Store:即后端存储系统,scribe支持多种模式的存储,包括file,thrift
file,bucket(多个storage),network(另一个scribe服务器)等

图表5 Scribe整体架构

 

5 MetaQ

         MetaQ(全名为Metamorphosis)是一个淘宝开源的分布式的消息中间件,纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。它总体设计和Kafka完全一致,但又针对淘宝业务特性做了很多优化改进。

         主要特性(与Kafka相比独特之处):

n  文本协议设计,非常透明,支持类似memcached stats的协议来监控broker

n  纯Java实现,从通讯到存储,从client到server都是重新实现

n  提供事务支持,包括本地事务和XA分布式事务

n  支持HA复制,包括异步复制和同步复制,保证消息的可靠性

n  支持异步发送消息

n  消费消息失败,支持本地恢复

n  多种offset存储支持,数据库、磁盘、zookeeper,可自定义实现

n  支持groupcommit,提升数据可靠性和吞吐量

n  支持消息广播模式

n  一系列配套项目:python客户端、twitterstorm的spout、tail4j等

系统主要部件和架构同Kafka基本一致。

         该系统在阿里系公司内部广泛应用,在淘宝每日支撑十亿级条数据,在支付宝每日支撑百亿级条数据。笔者的团队也借鉴了MetaQ的部分亮点对Kafka做了一些优化,还为下游storm平台开发了spout作为消息输入。

 

6 总结

         以下是几种分布式消息系统的对比总结。可以看到,几种系统在高可靠性、高扩展性方面大同小异,而消息传递机制、持久化机制等方面又各具特色。同行们如需采用,可根据自身业务服务器特点选择最合适的系统,或选择一个社区最活跃的系统以获得可靠的技术支持。

 

项目

Kafka

Flume

Chukwa

Scribe

MetaQ

公司

Linkedin

Cloudera

Apache

Facebook

淘宝

源码语言

Scala

Java

Java

C/C++

Java

消息传递

Push/pull

Push/push

Push/push

Push/push

Push/pull

扩展性











容错性

Producer和broker,broker和consumer间均有容错机制

Agent和store间有容错机制,agent内部事件传递时也有容错

Agent和collector间有容错机制

Scribe和store间有容错机制,Scribe
agent和Scribe间的容错需自己实现

Producer和broker,broker和consumer间均有容错机制

负载均衡

zookeeper

zookeeper





zookeeper

持久化方式

多,支持HDFS

中,支持HDFS

中,支持HDFS

多,支持HDFS

多,支持HDFS

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MQ Kafka Flume Scribe