APP下载

一种分布式消息队列研究与测试

2016-12-02于金良朱志祥李聪颖

物联网技术 2016年8期
关键词:主题分布式

于金良 朱志祥 李聪颖

摘 要:为了解决实时流式数据的采集问题,研究了一种分布式消息队列Kafka,它可以实时采集流式数据,处理数据时先从它订阅,就可以以流数据的形式处理数据。该队列具有部署简单、易于管理、吞吐量高、高容错性等优点。经测试,该队列可以满足实际生产中对吞吐量的需求。

关键词:分布式;消息队列;主题;流数据

中图分类号:TP274.2 文献标识码:A 文章编号:2095-1302(2016)08-00-03

0 引 言

当前大数据处理的数据形式主要分为两种。一种是固定的批量数据,这种数据是一个文件或者一个数据库,其数据量是固定的,我们只需一次读取,然后进行计算;另外一种是活跃的流式数据,这种数据是一个数据流,是实时生成、可传输的,如一个网站的流量page views、用户搜索的内容等,这些数据是实时的,且数据量很大,其采集比较困难,传统的消息队列很难应用到此种场景中。要想处理这些数据就需要先采集这些数据,本文介绍了一种可以实时采集这些数据的分布式消息队列Kafka。

1 简介

Kafka是LinkedIn于2010年12月份开源的消息系统,它主要用于处理活跃的流式数据。活跃的流式数据在Web网站的应用中十分常见,包括网站的pv、用户访问的内容、搜索的内容等。这些数据通常以日志的形式记录下来,然后每隔一段时间进行一次统计处理。

传统的日志分析系统提供了一种离线处理日志信息的可扩展方案,但若要进行实时处理,通常会有较大延迟。而现有的消息(队列)系统能够很好地处理实时或者近似实时的应用,但未处理的数据通常不会写到磁盘上,这对于Hadoop之类(一小时或者一天只处理一部分数据)的离线应用而言,可能会存在些许问题。Kafka正是为了解决以上问题而设计的,它能够很好地提供离线和在线应用。

Kafka对消息按topic进行归类保存,消息的发布者称为生产者(Producer),消息的接收者称为消费者(Consumer)。Kafka是分布式,它的集群由多个Kafka实例组成,每个实例是一个Broker。Kafka集群的信息及生产者与消费者的元数据都由Zookeeper保存,它本身无需保存这些数据。

2 设计原理

Kafka的设计初衷是希望作为一个统一的数据收集平台,能够实时收集数据、支撑大数据,并具备良好的容错能力。

2.1 存储

Kafka不会在消息被消费后直接删除,而是将消息持久化在磁盘中,使用文件存储消息,而文件系统的优化几乎是不可能的,为了提高性能,采用了缓存/直接内存映射的方法。为了减少对磁盘的访问次数,Broker将数据暂时缓存起来,当消息的数量达到一定值时,再flush到磁盘中,减少了在磁盘I/O上消耗的时间。

2.2 高吞吐量

为了提高Kafka的吞吐量,它采用了批量传输发送的方法,即生产者发布消息时,先将消息缓存,当达到一定量时,批量发送到Broker;对于消费者也一样,Broker会批量发送多条消息。考虑到网络I/O,Kafka将在网络上传输的数据进行压缩,它支持的压缩方式有gzip/snappy等。而在创建主题时,可以分为多个分区,进一步提高读写的吞吐量。

2.3 负载均衡

生产者根据用户指定的算法,将消息发送到指定的分区;存在多个分区,每个分区都有自己的副本,每个副本分布在不同的Broker节点上;多个分区需要选取出主分区,主分区负责读写,并由Zookeeper负责故障恢复;通过Zookeeper管理Broker与消费者的动态加入与离开。

2.4 自动扩容

由于在大数据行业中数据量的大小难以估计,Kafka支持集群的横向扩展,当需要增加Broker结点时,新增的Broker、生产者、消费者会向Zookeeper注册,并及时作出调整。

3 技术架构

Kafka是使用scala语言开发的,同时支持多种编程语言的客户端(c++、java、python、go等),其总体架构如图1所示。

Kafka的消息分为以下几个层次:

(1)主题(Topic):一类消息,例如页面浏览日志,用户搜索日志等都可以以主题的形式存在,Kafka集群能够同时负责一个或多个主题的分发。

(2)分区(Partition):是在主题物理上的分组,一个主题可以分为多个分区,每个分区是一个有序的队列。分区中的每条消息都会被分配一个有序的id(offset)。

(3) 消息(Message):最小订阅单元。

具体流程如下所示:

(1)生产者根据指定的分区方法(round-robin、hash等),将消息发布到指定主题的分区中;

(2)Kafka集群接收到生产者发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被消费;

(3)消费者从Kafka集群拉数据,并控制获取消息的offset。

4 主题与分区

一个topic是对一组消息的归纳。Kafka对每个主题的日志进行了分区,如图2所示。

每个分区都由一系列有序的、不可变的消息组成,这些消息被连续追加到分区中。分区中的每个消息都有一个连续的序列号叫做offset,用来在分区中唯一的标识这个消息。

在一个可配置的时间段内,Kafka集群保留所有发布的消息,不管这些消息有没有被消费。比如将消息的保存策略设置为2天,那么在一个消息发布到Kafka的两天时间内,它都可以被消费。之后它将被丢弃以释放空间。Kafka的性能是和数据量无关的常量级,所以保留太多的数据并不是问题。

实际上每个消费者唯一需要维护的是已消费消息在消息队列中的位置,即offset。一般情况下随着消费者不断的读取消息,offset的值随之不断增加,其实消费者可以以任意的顺序读取消息,比如它可以将offset设置成一个旧值来重读之前的消息。

结合以上特点可以发现,Kafka消费者是轻量级的,它们可以在不对集群和其他消费者造成影响的情况下读取消息。

将日志分区可以达到以下目的:首先这使得每个日志的数量不会太大,可以在单个服务上保存。另外每个分区可以单独发布和消费,为并发操作主题提供了一种可能。

4.1 分布式

每个分区在Kafka集群的若干服务中都有副本,这些持有副本的服务可以共同处理数据和请求,副本数量可以配置。副本使Kafka具备了容错能力。

每个分区都由一个服务器作为主服务,零或若干服务器作为从服务,主服务负责处理消息的读和写,从服务则复制主服务,若主服务宕机了,从服务中的一台则会自动成为主服务。集群中的每个服务都会同时扮演两个角色:作为它所持有的一部分分区的主,同时作为其他分区的从,这样集群就会有较好的负载均衡。

4.2 生产者

生产者(Producer)将消息发布到它指定的主题中,并决定发布到哪个分区中。一般是由负载均衡机制随机选择一个分区,也可通过特定的分区函数来选择分区。使用更多的是第二种。

4.3 消费者

发布消息通常有两种模式:队列模式(queuing)和发布-订阅模式(publish-subscribe)。队列模式中,消费者(Consumers)可以同时从服务端读取消息,每个消息只被其中一个消费者读到;发布-订阅模式中消息被广播到所有的消费者中。多个消费者可以加入到一个消费者组中,共同竞争一个主题,主题中的消息将被分发到组中的一个成员中。同一组中的消费者可以在不同的程序中、不同的机器上。如果所有的消费者都在一个组中,这就成为了传统的队列模式,在消费者组中实现负载均衡。

5 性能测试

通过一台4核、8 G内存的台式机,向一个拥有5台Broker的Kafka集群发布、订阅消息。消息的平均大小为100个字节。测试结果如下:

生产者:每秒可发布30万条消息,且可通过调整request.required.acks参数来保证数据的可靠性。

消费者:每秒可消费5万条数据。通过使用java语言编写Kafka生产者与消费者对Kafka性能进行测试。

6 结 语

分布式消息队列Kafka具有部署简单、易于管理、高吞吐量、高容错性等优点,经测试,可以满足实际生产中对吞吐量的需求。

参考文献

[1]孙韩林.一种基于云计算的网络流量分析系统结构[J].西安邮电大学学报,2013,18(4):75-79.

[2]金澈清,钱卫宁,周傲英.流数据分析与管理综述[J].软件学报,2004,15(8):1172-1181.

[3]曹婧华,冉彦中,许志军.分布式消息队列的设计与实现[J].河南科技大学学报(自然科学版),2010,31(4):35-38,109.

[4]王博,陈莉君.Hadoop远程过程调用机制的分析和应用[J].西安邮电学院学报,2012,17(6):74-77.

[5]卢本捷.分布式消息队列的理论、实现与应用[D].武汉:华中科技大学,2004.

[6]崔小燕.Linux集群系统分析[J].西安邮电学院学报,2006,11(5):103-106.

[7]于自强.海量流数据挖掘相关问题研究[D].济南:山东大学,2015.

[8]谢晓燕,张静雯.一种基于Linux集群技术的负载均衡方法[J].西安邮电大学学报,2014,19(3):64-68.

[9]陆庆,周世杰,秦志光,等.消息队列中间件系统中消息队列与消息分发技术研究[J].计算机应用研究,2003(8):51-53.

猜你喜欢

主题分布式
基于预处理MUSIC算法的分布式阵列DOA估计
农村幼儿园“幼小衔接”的“五步走”
西门子 分布式I/O Simatic ET 200AL
家庭分布式储能的发展前景