标签:
http://www.jianshu.com/p/f78b773ddde5
Kafka是一种分布式的,基于发布/订阅的消息系统。主要设计目标如下:
kafka的架构和原理想必大家都已经在很多地方看过,今天暂时不讲,下次再开篇详谈,整个kafka的具体工作流和架构如下图:
如上图所示,一个典型的Kafka集群中包含若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。
在centos上安装kafka,我推荐安装confluent公司的kafka套装,我们可以选择自己想要的组件就行。
sudo rpm --import http://packages.confluent.io/rpm/2.0/archive.key
confluent.repo
[confluent-2.0]
name=Confluent repository for 2.0.x packages
baseurl=http://packages.confluent.io/rpm/2.0
gpgcheck=1
gpgkey=http://packages.confluent.io/rpm/2.0/archive.keyenabled=1
sudo yum install confluent-platform-2.11.7
安装即可,里面包含confluent-kafka-2.11.7
和confluent-schema-registry
等组件。安装完成后马上快速开始吧。
kafka工具安装后,会有很多自带的工具来测试kafka,下面就举几个例子
创建、改变、展示全部和描述topics, 例子:
[root@localhost ~]#/usr/bin/kafka-topics --zookeeper zk01.example.com:2181 --list
sink1
test
[root@localhost ~]#/usr/bin/kafka-topics --zookeeper zk01.example.com:2181 --create --topic
从kafka中读取数据,输出到控制台
[root@localhost ~]#kafka-console-consumer --zookeeper zk01.example.com:2181 --topic test
从标准输出读取数据然后写入到kafka队列中
[root@localhost ~]#/usr/bin/kafka-console-producer --broker-list kafka02.example.com:9092,kafka03.example.com:9092 --topic test2
检查读写的消息量
[root@localhost ~]#/usr/bin/kafka-consumer-offset-checker --group flume --topic test1 --zookeeper zk01.example.com:2181
利用开源项目KafkaOffsetMonitor或者kafka-manager将kafka情况直观的展示出来。
java -cp /root/kafka_web/KafkaOffsetMonitor-assembly-0.2.1.jar com.quantifind.kafka.offsetapp.OffsetGetterWeb --dbName kafka --zk zk-server1,zk-server2 --port 8080 --refresh 10.seconds --retain 2.days
[program:kafka_web]
command=java -cp /root/kafka_web/KafkaOffsetMonitor-assembly-0.2.1.jar com.quantifind.kafka.offsetapp.OffsetGetterWeb --dbName kafka -zk zk-server1,zk-server2 --port 8080 --refresh 10.seconds --retain 2.days
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true
运行kafka-manager需要sbt编译,但是编译起来太麻烦了,而且还不一定成功,所以我就直接用docker跑了一个。
/etc/sysconfig/docker
上增加daocloud的加速mirror, 修改docker运行参数:
other_args=" --registry-mirror=http://7919bcde.m.daocloud.io --insecure-registry=0.0.0.0:5000 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -api-enable-cors=true"
直接重启docker即可。 docker run -p 9000:9000 -e ZK_HOSTS="zk_host:2181" -e APPLICATION_SECRET=kafka-manager sheepkiller/kafka-manager
关于性能测试,找到了Kafka的创始人之一的Jay Kreps的bechmark。以下描述皆基于该benchmark。(该benchmark基于Kafka0.8.1)
该benchmark用到了六台机器,机器配置如下
Intel Xeon 2.5 GHz processor with six cores
Six 7200 RPM SATA drives
32GB of RAM
1Gb Ethernet
这6台机器其中3台用来搭建Kafka broker集群,另外3台用来安装Zookeeper及生成测试数据。6个drive都直接以非RAID方式挂载。实际上kafka对机器的需求与Hadoop的类似。
该项测试只测producer的吞吐率,也就是数据只被持久化,没有consumer读数据。
消息系统的一个潜在的危险是当数据能都存于内存时性能很好,但当数据量太大无法完全存于内存中时(然后很多消息系统都会删除已经被消费的数据,但当消费速度比生产速度慢时,仍会造成数据的堆积),数据会被转移到磁盘,从而使得吞吐率下降,这又反过来造成系统无法及时接收数据。这样就非常糟糕,而实际上很多情景下使用queue的目的就是解决数据消费速度和生产速度不一致的问题。
但Kafka不存在这一问题,因为Kafka始终以O(1)的时间复杂度将数据持久化到磁盘,所以其吞吐率不受磁盘上所存储的数据量的影响。为了验证这一特性,做了一个长时间的大数据量的测试。测试表明当磁盘数据量达到1TB时,吞吐率和磁盘数据只有几百MB时没有明显区别,这个variance是由Linux I/O管理造成的,它会把数据缓存起来再批量flush。
需要注意的是,replication factor并不会影响consumer的吞吐率测试,因为consumer只会从每个partition的leader读数据,而与replicaiton factor无关。同样,consumer吞吐率也与同步复制还是异步复制无关。
1个consumer
该测试从有6个partition,3个replication的topic消费50 million的消息。测试结果为89.7MB/second。可以看到,Kafka的consumer是非常高效的。它直接从broker的文件系统里读取文件块。Kafka使用sendfile API来直接通过操作系统直接传输,而不用把数据拷贝到用户空间。该项测试实际上从log的起始处开始读数据,所以它做了真实的I/O。在生产环境下,consumer可以直接读取producer刚刚写下的数据(它可能还在缓存中)。实际上,如果在生产环境下跑I/O stat,你可以看到基本上没有物理“读”。也就是说生产环境下consumer的吞吐率会比该项测试中的要高。
3个consumer
将上面的consumer复制到3台不同的机器上,并且并行运行它们(从同一个topic上消费数据)。测试结果为249.5MB/second,正如所预期的那样,consumer的吞吐率几乎线性增涨。
上面的测试只是把producer和consumer分开测试,而该项测试同时运行producer和consumer,这更接近使用场景。实际上目前的replication系统中follower就相当于consumer在工作。
该项测试,在具有6个partition和3个replica的topic上同时使用1个producer和1个consumer,并且使用异步复制。测试结果为75.8MB/second, 可以看到,该项测试结果与单独测试1个producer时的结果几乎一致。所以说consumer非常轻量级。
上面的所有测试都基于短消息(payload 100字节),而正如上文所说,短消息对Kafka来说是更难处理的使用方式,可以预期,随着消息长度的增大,records/second会减小,但MB/second会有所提高。正如我们所预期的那样,随着消息长度的增加,每秒钟所能发送的消息的数量逐渐减小。但是如果看每秒钟发送的消息的总大小,它会随着消息长度的增加而增加,当消息长度为10字节时,因为要频繁入队,花了太多时间获取锁,CPU成了瓶颈,并不能充分利用带宽。但从100字节开始,我们可以看到带宽的使用逐渐趋于饱和(虽然MB/second还是会随着消息长度的增加而增加,但增加的幅度也越来越小)。
上文中讨论了吞吐率,那消息传输的latency如何呢?也就是说消息从producer到consumer需要多少时间呢?该项测试创建1个producer和1个consumer并反复计时。结果是,2 ms (median), 3ms (99th percentile, 14ms (99.9th percentile),(这里并没有说明topic有多少个partition,也没有说明有多少个replica,replication是同步还是异步。实际上这会极大影响producer发送的消息被commit的latency,而只有committed的消息才能被consumer所消费,所以它会最终影响端到端的latency)
如果读者想要在自己的机器上重现本次benchmark测试,可以参考本次测试的配置和所使用的命令。
实际上Kafka Distribution提供了producer性能测试工具,可通过bin/kafka-producer-perf-test.sh
脚本来启动。
读者也可参考另外一份Kafka性能测试报告
标签:
原文地址:http://www.cnblogs.com/Leo_wl/p/5447910.html