https://bbs.huaweicloud.com/blogs/112956

版权归PUMA项目组所有,转载请声明,多谢。

kakfa大规模集群能力在前面已给大家分享过,kafka作为消息总线,在支撑云千万tps上千节点的集群能力非常出色,本文继续对业界关于单机多topic的性能瓶颈点问题(比如:https://yq.aliyun.com/articles/62832?spm=5176.100239.blogcont25379.8.KMUH1L),国内某云使用RocketMQ,性能对比唱衰kafka 64分区时出现性能拐点,为此我们表示不服,从理论到实测数据,一步步揭开所谓单机性能拐点的秘密及解决之道。

1     简介

本文分析了Kafka分区数量的支持情况,通过一系列的测试和分析需要确认分区的数目是否受到限制,并找到解决方案。

本文读者包含分布式消息总线系统的开发者、测试者,以及应用该系统的客户产品

硬件约束:2285服务器2台

软件约束:无

2     需求背景

为什么要扩展Kafka分区数量呢?主要有以下几点:

  1. 分区的数目关系消息队列的并行度,消息发送是往分区里发送的,每个消费者都只能对每个分区启动1个线程获取数据。所以分区是消息队列并行度的最大保证。
  2. 消息总线需要多业务接入,每个业务都要创建自己的Topic和分区,必然对队列数目有需求(队列数目包含Topic和分区)
  3. 终端有个IM的需求,是做一个类似一个微信和旺旺一样的聊天工具。如果用消息总线来做,那么要求消息队列为每个用户分配一个队列,这样至少要支持几亿的消息队列,这个在目前的消息队列中完全没办法支持。
  4. 当消息队列作为公有云的服务提供的时候,我们分析每个用户会独占一个队列(分区或Topic),同样会对分区数量带来要求。

正是这些需求和原因导致我们将分区个数作为了MQ的一个度量指标。同时从网上的一些分析,Kafka最多支持64个分区性能就下降得很厉害,为了验证和解决分区数量限制的问题,我们就有本文档的分析。

3     分析

3.1   原理分析

3.1.1    基本概念

3.1.1.1 分区

分区是Kafka中的最重要的概念之一,消息发送和接收都是按照分区为单位来处理的。

分区的几个主要作用如下:

1、 Producer(消息发送者)的往消息Server的写入并发数与分区数成正比。

2、 Consumer(消息消费者)消费某个Topic的并行度与分区数保持一致,假设分区数是20,那么Consumer的消费并行度最大为20。

3、 每个Topic由固定数量的分区数组成,分区数的多少决定了单台Broker能支持的Topic数量,Topic数量又决定了支持的业务数量。

简单的说,有多少分区,就有多少对应的文件读写,Kafka的每个分区对应一个文件:

每条消息都被append到该Partition中,属于顺序写磁盘,因此效率非常高,经验证,顺序写磁盘效率比随机写内存还要高,这是Kafka高吞吐率的一个很重要的保证。

3.1.1.2 磁盘

在对消息存储和缓存时,Kafka使用了文件系统。

Kafka的设计基于一种非常简单的指导思想:不是要在内存中保存尽可能多的数据,在需要时将这些数据刷新(flush)到文件系统,而是要做完全相反的事情。所有数据都要立即写入文件系统中持久化的日志中,但不进行刷新数据的任何调用。实际中这样做意味着,数据被传输到OS内核的页面缓存中了,OS随后会将这些数据刷新到磁盘。

大家普遍为“磁盘很慢”,因而人们都对持久化(persistent structure)结构能够提供说得过去的性能抱有怀疑态度。实际上,同人们的期望值相比,磁盘可以说是既很慢又很快,这取决决于磁盘的使用方式。设计的很好的磁盘结构可以和网络一样快。在一个由6个7200rpm的SATA硬盘组成的RAID-5磁盘阵列上,线性写入(linear write)的速度大约是600MB/秒,但随机写入却只有100k/秒,其中的差距接近6000倍。

Kafka并没有在内存中创建缓冲区,然后再向磁盘write的方法,而是直接使用了PageCache。

OS在文件系统的读写上已经做了太多的优化,PageCache就是其中最重要的一种方法,详细的说明请看3.1.2章节。

直接使用PageCache有如下几个好处:

1)减少内存开销: Java对象的内存开销(overhead)非常大,往往是对象中存储的数据所占内存的两倍以上。

2)避免GC问题:Java中的内存垃圾回收会随着堆内数据不断增长而变得越来越不明确,回收所花费的代价也会越来越大。

3)简单可靠:OS会调用所有的空闲内存作为PageCache,并在其上做了大量的优化:预读,后写,flush管理等,这些都不用应用层操心,而是由OS自动完成。

由于这些因素,使用文件系统并依赖于PageCache页面缓存要优于自己在内存中维护一个缓存或者什么其他别的结构。

3.1.2    文件读写分析

Kafka借力于Linux内核的Page Cache,不(显式)用内存,胜用内存,完全没有别家那样要同时维护内存中数据、持久化数据的烦恼——只要内存足够,生产者与消费者的速度也没有差上太多,读写便都发生在Page Cache中,完全没有同步的磁盘访问。

3.1.2.1 读写空中接力

Linux总会把系统中还没被应用使用的内存挪来给Page Cache,在命令行输入free,或者cat /proc/meminfo,"Cached"的部分就是Page Cache。

Page Cache中每个文件是一棵Radix树(基树),节点由4k大小的Page组成,可以通过文件的偏移量快速定位Page。

当写操作发生时,它只是将数据写入Page Cache中,并将该页置上dirty标志。

当读操作发生时,它会首先在Page Cache中查找内容,如果有就直接返回了,没有的话就会从磁盘读取文件再写回Page Cache。

可见,只要生产者与消费者的速度相差不大,消费者会直接读取之前生产者写入Page Cache的数据,大家在内存里完成接力,根本没有磁盘访问。

而比起在内存中维护一份消息数据的传统做法,这既不会重复浪费一倍的内存,Page Cache又不需要GC(可以放心使用大把内存了),而且即使Kafka重启了,Page Cache还依然在。

3.1.2.2 后台异步flush的策略

这是大家最需要关心的,因为不能及时flush的话,OS crash(不是应用crash) 可能引起数据丢失,Page Cache瞬间从朋友变魔鬼。

当然,Kafka不怕丢,因为它的持久性是靠replicate保证,重启后会从原来的replicate follower中拉缺失的数据。

内核线程pdflush负责将有dirty标记的页面,发送给IO调度层。内核会为每个磁盘起一条pdflush线程,每5秒(/proc/sys/vm/dirty_writeback_centisecs)唤醒一次,根据下面三个参数来决定行为:

  1. /proc/sys/vm/dirty_expire_centiseconds:如果page dirty的时间超过了30秒(单位是10ms),就

会被刷到磁盘,所以crash时最多丢30秒左右的数据。

  1. /proc/sys/vm/dirty_background_ratio:如果dirty page的总大小已经超过了10%的可用内存(cat

/proc/meminfo里 MemFree+ Cached - Mapped),则会在后台启动pdflush 线程写盘,但不影响

当前的write(2)操作。增减这个值是最主要的flush策略里调优手段。

  1. /proc/sys/vm/dirty_ratio:如果wrte(2)的速度太快,比pdflush还快,dirty page 迅速涨到 10%

的总内存(cat /proc/meminfo里的MemTotal),则此时所有应用的写操作都会被block,各自在自

己的时间片里去执行flush,因为操作系统认为现在已经来不及写盘了,如果crash会丢太多数据,

要让大家都冷静点。这个代价有点大,要尽量避免。在Redis2.8以前,Rewrite AOF就经常导致

这个大面积阻塞,现在已经改为Redis每32Mb先主动flush()一下了。

详细的文章可以看:http://www.westnet.com/~gsmith/content/linux-pdflush.htm

3.1.2.3 主动flush的方式

对于重要数据,应用需要自己触发flush保证写盘。

  1. 调用fsync() 和 fdatasync()

fsync(fd)将属于该文件描述符的所有dirty page的写入请求发送给IO调度层。

fsync()总是同时flush文件内容与文件元数据, 而fdatasync()只flush文件内容与后续操作必须

的文件元数据。元数据含时间戳,大小等,大小可能是后续操作必须,而时间戳就不是必须的。

因为文件的元数据保存在另一个地方,所以fsync()总是触发两次IO,性能要差一点。

  1. 打开文件时设置O_SYNC,O_DSYNC标志或O_DIRECT标志

O_SYNC、O_DSYNC标志表示每次write后要等到flush完成才返回,效果等同于write()后紧接一个fsync()或fdatasync(),不过按APUE里的测试,因为OS做了优化,性能会比自己调write() + fsync()好一点,但与只是write相比就慢很多了。O_DIRECT标志表示直接IO,完全跳过Page Cache。不过这也放弃了读文件时的Cache,必须每次读取磁盘文件。而且要求所有IO请求长度,偏移都必须是底层扇区大小的整数倍。所以使用直接IO的时候一定要在应用层做好Cache。

Kafka的默认机制中,fsync的间隔时间和消息个数都是最大值,所以基本上都是依赖OS层面的flush。

3.1.2.4 Page Cache的清理策略

当内存满了,就需要清理Page Cache,或把应用占的内存swap到文件去。有一个swappiness的参数(/proc/sys/vm/swappiness)决定是swap还是清理page cache,值在0到100之间,设为0表示尽量不要用swap,这也是很多优化指南让你做的事情,因为默认值居然是60,Linux认为Page Cache更重要。

Page Cache的清理策略是LRU的升级版。如果简单用LRU,一些新读出来的但可能只用一次的数据会占满了LRU的头端。因此将原来一条LRU队列拆成了两条,一条放新的Page,一条放已经访问过好几次的Page。Page刚访问时放在新LRU队列里,访问几轮了才升级到旧LRU队列(想想JVM Heap的新生代老生代)。清理时就从新LRU队列的尾端开始清理,直到清理出足够的内存。

Linux 提供了这样一个参数min_free_kbytes,用来确定系统开始回收内存的阀值,控制系统的空闲内存。值越高,内核越早开始回收内存,空闲内存越高。

3.1.2.5 预读策略

根据清理策略,Apache Kafka里如果消费者太慢,堆积了几十G的内容,Cache还是会被清理掉的。这时消费者就需要读盘了。

内核这里又有个动态自适应的预读策略,每次读请求会尝试预读更多的内容(反正都是一次读操作)。内核如果发现一个进程一直使用预读数据,就会增加预读窗口的大小,否则会关掉预读窗口。连续读的文件,明显适合预读。

3.1.2.6 调度层优化

IO调度层主要做两个事情,合并和排序。

合并是将相同和相邻扇区(每个512字节)的操作合并成一个,比如现在要读扇区1,2,3,那可以合并成一个读扇区1-3的操作。

排序就是将所有操作按扇区方向排成一个队列,让磁盘的磁头可以按顺序移动,有效减少了机械硬盘寻址这个最慢最慢的操作。

排序看上去很美,但可能造成严重的不公平,比如某个应用在相邻扇区狂写盘,其他应用就都干等在那了,pdflush还好等等没所谓,读请求都是同步的,耗在那会很惨。所有又有多种算法来解决这个问题,其中内核2.6的默认算法是CFQ(完全公正排队)。

3.1.3    原理分析结论

1、Kafka使用文件系统来交换消息,性能是否比使用内存来交换消息的系统要低很多?

在Apache Kafka里,消息的读写都发生在内存中(Pagecache),真正写盘的就是那条pdflush内核线程,根本不在Kafka的主流程中,读操作大多数会命中Pagecache,同时由于预读机制存在,所以性能非常好,从原理上有保证的。

2、 每个分区一个文件,那么多个分区会有多个文件同时读写,是否会极大的降低性能?

1)        首先,由于Kafka读写流程是发生在PageCache中,后台的flush不在主流程中触发,所以正常情况下理论上是没有影响的,除非PageCache占用内存过大,或是释放导致读写消耗Kafka进程的CPU时间。

2)        再次,文件都是顺序读写,OS层面有预读和后写机制,即使一台服务器上有多个Partition文件,经过合并和排序后都能获得很好的性能,不会出现文件多了变成随机读写的情况,但是当达到相当多的数量之后,也会存在一定的影响。

3)        当PageCache过大,大量触发磁盘I/O的时候,超过了/proc/sys/vm/dirty_ratio,Flush会占用各个应用自己的CPU时间,会对主流程产生影响,让主流程变慢。

3.2   性能测试

3.2.1    测试环境

同时启动消息发送和消费。

指标说明:

TPS

在客户端侧由代码统计的每秒发送和接收到的消息个数。

wai

系统因为io导致的进程wait。再深一点讲就是:这时候系统在做io,导致没有进程在干活,cpu在执行idle进程空转,所以说iowait的产生要满足两个条件,一是进程在等io,二是等io时没有进程可运行。

%util

使用iostat测试得到。Percentage of CPU time during which I/O requests   were issued to the device (bandwidth utilization for the device). Device   saturation occurs when this value is close to 100%。一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间   I/O 队列是非空的。如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。

IOPS

该设备每秒的传输次数(Indicate the number of   transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。IOPS=reads+writes

reads

在用例运行过程中,每秒读io的个数均值

writes

在用例运行过程中,每秒写io的个数均值

从流程来看,影响性能的几个主要点为:客户端,网络,服务器端CPU,内存,文件系统(磁盘)。

3.2.2    单硬盘测试

当系统只有一个硬盘的时候,所有的分区文件集中在一个磁盘上,测试数据如下:

从数据来看,cpu,内存,网络问题都不大。

随着分区数目的增加,吞吐量会下降。从图上来看,2000的分区下,生产者和消费者TPS下降幅度已经较大了。1000左右的分区TPS浮动不大。

备注:Consumer的TPS下降的原因,根据JProfile分析,主要是客户端问题,后面章节有专门分析。

从磁盘的IOPS来看,超过1000之后,会急剧上升,3000之后因为TPS的下降,反而有所下降。

特别注意的是:读操作一直为0,证明基本上所有的Consumer消息都是从PageCache中获取的。

接下来,看一下util和wai,超过1000之后,util会急剧上升,到了3000左右,基本满负荷了。

这个和TPS是能对上的。

根据以上的测试数据,我们可以得到一个初步的结论:

1、 当分区超过了2000之后,util急剧上升,磁盘性能会成为瓶颈,导致Producer TPS下降。

2、 由于Read操作一直为0,证明磁盘对Consumer的影响不大。Consumer的TPS下降是客户端原因。(后面的章节给出证据)

建议:单台服务器单硬盘下,分区数量不超过2000,推荐值在1000以下。

3.2.3    多硬盘测试

启动8个磁盘,1个磁盘跑zookeeper和OS,其他7个磁盘分担所有的分区文件。

Util和IOPS是7个硬盘加起来的值,实际上每个硬盘的负荷是平均分担的。

1、可以看到,3000分区下,Producer的TPS很平稳,实际上还要超过单硬盘下单分区的TPS。

证明追加硬盘的方法可以明显的提高TPS。

2、Consumer TPS,在多硬盘下其实和单硬盘是一致的,超过2000分区之后,一直都是18w左右。证明硬盘并不是Consumer的瓶颈。

磁盘的IOPS和Util是随分区增加而增加的,但是实际上被7个硬盘平均分担,每个硬盘的负荷除以7之后很小了。

当分区达到5000之后,TPS会下降,但是磁盘负荷还远没有达到瓶颈。

CPU,网络,内存也同样没有问题。

3.2.4    客户端分析

3.2.4.1 Consumer客户端

Consumer客户端,使用的是Scala的客户端。

多硬盘,单分区下,JProfile如下:

400分区如下:

3000分区如下:

3000分区的时候,可以看到,97.8的cpu时间被用来执行了parseFull这个函数,这个函数是创建Streams的时候,对从zk获取的json文件进行解析,每次只执行一次。

但是由于分区越多,这个文件越大越复杂,导致执行时间非常长,影响了Consumer的TPS。

由于这个函数只执行一次,不会大量被执行,所以当Consumer运行时间越长,那么影响会越小。

3.2.4.2 Producer Scala客户端

最开始使用Scala客户端的测试,发现多分区下,大量的时间被消耗在日志打印参数的format函数上:

25分区:

这里的代码,会在分个消息发送的时候,对分区的MAP循环执行如下的函数,这个代码里面会多次拼接字符串很耗时。

通过屏蔽日志打印函数,避免执行format,可以大大提升TPS:

partitionMetadata.map { m =>

m.leader match {

case Some(leader) =>

//debug("Partition [%s,%d] has leader %d".format(topic, m.partitionId, leader.id))

new PartitionAndLeader(topic, m.partitionId, Some(leader.id))

case None =>

//debug("Partition [%s,%d] does not have a leader yet".format(topic, m.partitionId))

new PartitionAndLeader(topic, m.partitionId, None)

}

}.sortWith((s, t) => s.partitionId < t.partitionId)

那两句debug信息打印注释掉,能大大的提升TPS。

估计还有其他的瓶颈点,之后我们将测试客户端切换到了java客户端。

3.2.4.3 Producer Java客户端

多硬盘一分区下,客户端的情况(ACK=1):

多硬盘5000分区下,Producer客户端(ACK=1):

多硬盘5000分区下,Producer客户端(ACK=0)

我们可以看到,分区数量越大,send函数耗时越长,5000分区下,耗时大半。

ACK=0的时候,客户端是不需要等待server的响应的,可以说基本上客户端的TPS和服务器端没有关系,但是,TPS照样降低,send照样消耗大量的时间。

所以,我们判断,多硬盘下,当分区达到5000以上的时候,瓶颈在客户端代码上,可以通过优化客户端代码来提升性能。

4     分析结论

4.1   结论

一、单Broker的分区,主要受以下几个方面的瓶颈限制:

1、 OS限制:Kafka代码中没有对分区做限制,但是分区数量受到OS的文件句柄的数量限制。可以用ulimit –a查看。需要调整该数目到一个较大的值。

2、 文件系统(磁盘刷盘):单硬盘下,磁盘IO和util会随着分区数目增大而增大,导致Kafka的性能会下降。

主要原因:

刷盘是一个很昂贵的操作,虽然OS提供了Group Commit和排序等优化机制,但是当分区数量太多之后,无法完全消除影响。每个分区写入是磁盘顺序写,但是多个分区同时顺序写入在操作系统层面变为了随机写入。

另外,当Pagecache的dirty数据达到一定限制之后,刷盘操作会阻塞应用的write操作,也会带来影响。

3、 客户端瓶颈:

通过追加硬盘可以解决单硬盘下的文件系统瓶颈。但是当达到5000以上,客户端会成为瓶颈。

这个是由于发送消息的时候需要获取Topic下的分区信息而产生的。

实际生产中,这个限制的影响应该不大,因为不会在1个Topic下划分太多的分区,而是会有多个Topic,每个Topic下有一些分区。测试的时候为了测试方便,采取了一种比较极端的测试方法(单个Topic下挂上数千的分区)。

当有需要的时候,也可以考虑优化。

建议分区数量:

1、单台服务器单硬盘下,推荐值1000,最好不超过2000。

2、单台服务器多硬盘下(7个),推荐值3000,最好不要超过5000。(当分区被分散到多个Topic的时候,这个值会更高,预计至少可以达到7000以上)。

二、集群(多节点)的分区限制:

理论上是随着节点增加而线性增加。但是实际还是受到Zookeeper的影响。节点最大支持数量估计在1w(zookeeper的限制)左右,那么整个集群分区的支持估计在百万左右(但是实际上受网络速度的影响,分区越大,存放在zookeeper的数据量越多等各种因素影响肯定会有个折扣)。

预计10w左右的分区支持问题不大。

1)        参考LinkedIn的Kafka集群部署规模:

http://www.slideshare.net/miguno/apache-kafka-08-basic-training-verisign

2)   在这篇文章中,提到曾经在单broker上使用了上万的分区。

http://www.confluent.io/blog/how-to-choose-the-number-of-topicspartitions-in-a-kafka-cluster/

4.2   社区意见参考

这里,kafka的committer有很明确的答复,基本上和我们验证的结果一致:

http://www.quora.com/How-many-topics-can-be-created-in-Apache-Kafka

有几个主要观点:

1、 Kafka的分区数量两个因素的影响:文件系统和zookeeper。

2、 实际应用中,分区数量不应该成为一个问题。分区的数量在实际中应该随着消费者数量扩展,不应该根据Data的特征来扩展。

4.3  解决方案

针对目前的几个瓶颈的解决方案如下:

1、 OS限制:通过调整Server的支持文件数目的句柄来解决。

2、 文件系统(磁盘刷盘):通过追加硬盘或追加Broker Node的方式来解决。

单个硬盘支持的分区数量推荐1000。多个硬盘:N*1000。

3、 客户端:当一个Topic下有过多的分区的时候(>3000),客户端预计会成为瓶颈。

如果有这种需求,可以考虑优化客户端来解决这里的瓶颈。

5     备注

5.1   参考资料

5.1.1    Cloudera配置Kafka的建议

http://blog.cloudera.com/blog/2015/07/deploying-apache-kafka-a-practical-faq/

非常好的实际经验。

http://blog.cloudera.com/blog/category/kafka/

是否应当为Kafka Broker使用 固态硬盘 (SSD)

实际上使用SSD盘并不能显著地改善 Kafka 的性能,主要有两个原因:

  • Kafka写磁盘是异步的,不是同步的。就是说,除了启动、停止之外,Kafka的任何操作都不会去等待磁盘同步(sync)完成;而磁盘同步(syncs)总是在后台完成的。这就是为什么Kafka消息至少复制到三个副本是至关重要的,因为一旦单个副本崩溃,这个副本就会丢失数据无法同步写到磁盘。
  • 每一个Kafka Partition被存储为一个串行的WAL(Write Ahead Log)日志文件。因此,除了极少数的数据查询,Kafka中的磁盘读写都是串行的。现代的操作系统已经对串行读写做了大量的优化工作。

如何对Kafka Broker上持久化的数据进行加密

目前,Kafka不提供任何机制对Broker上持久化的数据进行加密。用户可以自己对写入到Kafka的数据进行加密,即是,生产者(Producers)在写Kafka之前加密数据,消费者(Consumers)能解密收到的消息。这就要求生产者(Producers)把加密协议(protocols)和密钥(keys)分享给消费者(Consumers)。

另外一种选择,就是使用软件提供的文件系统级别的加密,例如Cloudera Navigator Encrypt。Cloudera Navigator Encrypt是Cloudera企业版(Cloudera Enterprise)的一部分,在应用程序和文件系统之间提供了一个透明的加密层。

Apache Zookeeper正成为Kafka集群的一个痛点(pain point),真的吗?

Kafka高级消费者(high-level consumer)的早期版本(0.8.1或更早)使用Zookeeper来维护读的偏移量(offsets,主要是Topic的每个Partition的读偏移量)。如果有大量生产者(consumers)同时从Kafka中读数据,对Kafka的读写负载可能就会超出它的容量,Zookeeper就变成一个瓶颈(bottleneck)。当然,这仅仅出现在一些很极端的案例中(extreme cases),即有成百上千个消费者(consumers)在使用同一个Zookeeper集群来管理偏移量(offset)。

不过,这个问题已经在Kafka当前的版本(0.8.2)中解决。从版本0.8.2开始,高级消费者(high-level consumer)能够使用Kafka自己来管理偏移量(offsets)。本质上讲,它使用一个单独的Kafka Topic来管理最近的读偏移量(read offsets),因此偏移量管理(offset management)不再要求Zookeeper必须存在。然后,用户将不得不面临选择是用Kafka还是Zookeeper来管理偏移量(offsets),由消费者(consumer)配置参数 offsets.storage 决定。

Cloudera强烈推荐使用Kafka来存储偏移量。当然,为了保证向后兼容性,你可以继续选择使用Zookeeper存储偏移量。(例如,你可能有一个监控平台需要从Zookeeper中读取偏移量信息。) 假如你不得不使用Zookeeper进行偏移量(offset)管理,我们推荐你为Kafka集群使用一个专用的Zookeeper集群。假如一个专用的Zookeeper集群仍然有性能瓶颈,你依然可以通过在Zookeeper节点上使用固态硬盘(SSD)来解决问题。

Kafka是否支持跨数据中心的可用性

Kafka跨数据中心可用性的推荐解决方案是使用MirrorMaker。在你的每一个数据中心都搭建一个Kafka集群,在Kafka集群之间使用MirrorMaker来完成近实时的数据复制。

使用MirrorMaker的架构模式是为每一个”逻辑”的topic在每一个数据中心创建一个topic:例如,在逻辑上你有一个”clicks”的topic,那么你实际上有”DC1.clicks”和“DC2.clicks”两个topic(DC1和DC2指得是你的数据中心)。DC1向DC1.clicks中写数据,DC2向DC2.clicks中写数据。MirrorMaker将复制所有的DC1 topics到DC2,并且复制所有的DC2 topics到DC1。现在每个DC上的应用程序都能够访问写入到两个DC的事件。这个应用程序能够合并信息和处理相应的冲突。

另一种更复杂的模式是在每一个DC都搭建本地和聚合Kafka集群。这个模式已经被Linkedin使用,Linkedin Kafka运维团队已经在 这篇Blog 中有详细的描述(参见“Tiers and Aggregation”)。

5.1.2    大数据领域的架构图

http://www.blogbus.com/navigating-logs/272257444.html

5.1.3    源代码High level分析

http://ju.outofmemory.cn/entry/124628

5.1.4    Kafka的配置推荐

http://bbs.chinacloud.cn/archiver/showtopic-29836.aspx

http://liyonghui160com.iteye.com/blog/2163899

5.1.5    Zookeeper的讨论

http://bbs.chinacloud.cn/archiver/showtopic-29836.aspx

重要的记录:

5.1.6    Kafka跨集群同步方案

http://jingyan.baidu.com/article/8065f87fea4d3a233124989f.html

http://tangzhaohui.net/post/524

5.1.7    实践部署与使用apache kafka

http://blog.csdn.net/zhongwen7710/article/details/41252649

5.1.8    从Apache Kafka 重温文件高效读写

http://calvin1978.blogcn.com/articles/kafkaio.html

kafka 解密:破除单机topic数多性能下降魔咒的更多相关文章

  1. Kafka相关内容总结(存储和性能)

    Kafka消息的存储 Kafka的设计基于一种非常简单的指导思想:不是要在内存中保存尽可能多的数据,在需要时将这些数据刷新(flush)到文件系统,而是要做完全相反的事情.所有数据都要立即写入文件系统 ...

  2. Kafka vs RocketMQ——多Topic对性能稳定性的影响-转自阿里中间件

    引言 上期我们对比了RocketMQ和Kafka在多Topic场景下,收发消息的对比测试,RocketMQ表现稳定,而Kafka的TPS在64个Topic时可以保持13万,到了128个Topic就跌至 ...

  3. Kafka vs RocketMQ——多Topic对性能稳定性的影响

    引言 上期我们对比了RocketMQ和Kafka在多Topic场景下,收发消息的对比测试,RocketMQ表现稳定,而Kafka的TPS在64个Topic时可以保持13万,到了128个Topic就跌至 ...

  4. Kafka 概念、单机搭建与使用

    目录 Kafka 概念.单机搭建与使用 基本概念介绍 Topic Producer Consumer Kafka单机配置,一个Broker 环境: 配置zookeeper 配置Kafka 使用Kafk ...

  5. Apache Kafka(十一)Topic 的配置与组成

    Topic 的配置与组成 之前我们仅主要介绍了Kafka Producer与Kafka Consumer 的相关配置,而未详细介绍过有关topic的配置.Topic的配置在Kafka 使用中也至关重要 ...

  6. Kafka设计解析(十二)Kafka 如何读取offset topic内容 (__consumer_offsets)

    转载自 huxihx,原文链接 Kafka 如何读取offset topic内容 (__consumer_offsets) 众所周知,由于Zookeeper并不适合大批量的频繁写入操作,新版Kafka ...

  7. 8、RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较 RabbitMQ中,除了Simple Queue和Work Queue之外的所有生产者提交的消息都由Exc ...

  8. kafka 以windows服务的方式在windows下安装并自启动

    准备工作: 下载kafka http://apache.fayea.com/kafka/0.10.0.0/kafka_2.10-0.10.0.0.tgz 解压kafka至D:\bigdata\kafk ...

  9. Kafka vs RocketMQ——单机系统可靠性-转自阿里中间件

    引言 前几期的评测中,我们对比了Kafka和RocketMQ的吞吐量和稳定性,本期我们要引入一个新的评测标准--软件可靠性. 何为"可靠性"? 先看下面这种情况:有A,B两辆越野汽 ...

随机推荐

  1. bat脚本里面if else if的写法

    曾经困扰了很久的bat脚本,如果里面包含多种条件判断,就必须要试用if,else if,else的写法了.尝试了很久,终于找到规律: 第一种写法:最简单,就是写一行. @echo off rem 写一 ...

  2. Django forms 主要的标签介绍

    修改 forms.py from django import forms as DForms from django.forms import fields from django.forms imp ...

  3. django rest framework 过滤 lim分页

    一.过滤 1.首先引用diango 自带的过滤配置 2.导入模块 from django_filters.rest_framework import DjangoFilterBackend from ...

  4. pdfium 之二

    https://www.foxitsoftware.cn/products/premium-pdfium/feature.php 基于谷歌PDFium开源代码 谷歌采用福昕的PDF技术为其PDF开源项 ...

  5. 【买衣服】I'm looking for a jacket

    核心句型: I 'm looking for a jacket. 我想买一件夹克. 场景对话 A: Are you looking for anything? 您想买什么吗? B: Yes. I'm ...

  6. 201871010133-赵永军《面向对象程序设计(java)》第十四周学习总结

    201871010133-赵永军<面向对象程序设计(java)>第十四周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  7. pycharm 有汉字的地方就有阴影

    1.pycharm  有汉字的地方就有阴影 编码申明 阴影就会消失 # _*_ coding:UTF-8

  8. leetcode 561. 数组拆分 I

    为了理解这种方法,让我们从不同的角度来看待问题.我们需要形成数组元​​素的配对,使得这种配对中最小的总和最大.因此,我们可以查看选择配对中最小值的操作,比如 (a,b)(a,b) 可能会产生的最大损失 ...

  9. 了解html标签

    <title></title> 1.网页标题 2.当我们收藏网页时,默认标题就是网页标题 3.seo(搜索引擎优化) <h1></h1>~<h6& ...

  10. bcc 基于bpf 分析linux 系统性能的强大工具包

    bcc 是一个基于bpf 的强大linux io,网络监控分析工具集(当然也可以分析java,ruby,python...) 一张工具图 说明 bcc 好多工具是需要kernel 4.1 的,但是大部 ...