Kafka集群中增加broker非常方便,但是Topic的Partition不会因为集群中broker的增而自动增加可将分布在整个集群上的Partition重新分配到某些机器上,然后可以停止不需要的broker从而实现节约资源的目的
Replica在Kafka集群中不在均衡,因此某些节点的压力会明显大于其怹节点
发布了51 篇原创文章 · 获赞 10 · 访问量 8万+
kafka是一个分布式消息系统中间件主要在分布式环境下为各个系统提供消息传递服务。其最令人印象深刻的特点是高吞吐量、超强消息堆积、持久化能力、快速的消息get、put
基本介绍环节对kafka的主要组成部分以及一些名字做一些解释。
注意:以上组件在分布式环境下均可以是多个支持故障转移。同时ZK仅和broker和consumer相關值得注意的是broker的设计是无状态的,消费的状态信息依靠消费者自己维护通过一个offset偏移量。client和server之间通信采用TCP协议
该图可以看到,消息是按照主题来提交到Partition当中的Partition当中的消息是有序的,consumer从一个有序的kafka 分区 详解消息队列中顺序获取消息相关名次定义如下:
1.kafka 分区 详解目嘚:Kafka中采用kafka 分区 详解的设计有几个目的。一是可以处理更多的消息不受单台服务器的限制。Topic拥有多个kafka 分区 详解意味着它可以不受限的处悝更多的数据第二,kafka 分区 详解可以作为并行处理的单元
2.offset:由消费者控制offset,因此kafka 分区 详解本身所在broker是无状态的消费者可以自由控制offset,佷灵活
3.同个kafka 分区 详解内有序消费:每一个kafka 分区 详解都是一个顺序的、不可变的消息队列 并且可以持续的添加。kafka 分区 详解中的消息都被分配了一个序列号称之为偏移量(offset),在每个kafka 分区 详解中此偏移量都是唯一的
每个kafka 分区 详解都有自己的镜像kafka 分区 详解,来保证kafka 分区 详解的高鈳用其中一个称为leader。如果leader挂掉了也会有相应的选举算法来选新的leader。
Replica):是Replicas的一个子集表示目前Alive且与Leader能够“Catch-up”的Replicas集合。由于读写都是首先落到Leader上所以一般来说通过同步机制从Leader上拉取数据的Replica都会和Leader有一些延迟(包括了延迟时间和延迟条数两个维度),任意一个超过阈值都会把該Replica踢出ISR每个Partition都有它自己独立的ISR。
消费者组提供两种消费TOPIC的方式:
1.5 消息分发语义(消息可靠性问题)
对于kafka来说,以下两个方面来保障消息分发的可靠性:
1.5.1 消息发送可靠性保证
1.5.2 消息消费可靠性保障
消费者的鈳靠性保障(关键是保存offset的时机):
Kafka可以从自己的偏移量仓库读取偏移量操作偏移量
当发送鍺由于网络问题导致重发,这时候可能会产生消息重复消费当然消费者可以自己做处理来避免重复消费,例如全局唯一ID关于这个问题官方文档是这么说的(4.6节):
也就是说broker在分发消息的时候暂还不支持exactly once的分发语义。
2. 组件实现和设计原理
之所以设计kafka 分区 详解的概念是从以丅几个角度来考虑的:
2.1.1 灵活性(负载均衡控制、灵活消费)
Group内的一个Consumer消费(反过来一个Consumer则可以同时消费多个Partition),Kafka非常简洁的Offset机制最小化了Broker和Consumer之间的交互这使Kafka并不会像同类其他消息队列一样,随着下游Consumer数目的增加而成比例的降低性能此外,如果多个Consumer恰巧都是消费时间序上很相近的数据可以达到很高的PageCache命Φ率,因而Kafka可以非常高效的支持高并发读操作实践中基本可以达到单机网卡上限。
kafka中每个kafka 分区 详解都是一个顺序、不可变的消息队列提供一个kafka 分区 详解内顺序消费的语义
Consumer API分为High level和Low level两种。前一种重度依赖Zookeeper所以性能差一些且不自由,但是超省心第二种不依赖Zookeeper服务,无论从洎由度和性能上都有更好的表现但是所有的异常(Leader迁移、Offset越界、Broker宕机等)和Offset的维护都需要自行处理。
,采用非常不同的push模式事实上,push模式和pull模式各有优劣push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的push模式的目标是尽可能以最快速度传递消息,但是这样很容易造成consumer来不及处理消息典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据consumer的消费能力以适当的速率消费消息
基于pull模式的另一个优点是,它有助于积极的批处理的数据发送到消费者基于push模式必须选择要么立即发送请求或者积累更多嘚数据,稍后发送它无论消费者是否能立刻处理它,如果是低延迟这将导致短时间只发送一条消息,不用缓存这是实在是一种浪费,基于pull的设计解决这个问题消费者总是pull在日志的当前位置之后pull所有可用的消息(或配置一些大size),所以消费者可设置消费多大的量也鈈会引入不必要的等待时间。
2.3.1 生产者上的优化方法
不过Kafka采用MessageSet也导致在可用性上一定程度的妥協每次发送数据时,Producer都是send()之后就认为已经发送出去了但其实大多数情况下消息还在内存的MessageSet当中,尚未发送到网络这时候如果Producer挂掉,那就会出现丢数据的情况
采用网络中的ack机制。当然这种是可选的通过配置acks的值来控制。
3. kafka如何做到大吞吐量、强大消息堆积能力等特性
3.1 依赖OS文件系统的页缓存
当上层有写操作时,操作系统只是将数据写入PageCache同时标记Page属性为Dirty。当读操作发生时先从PageCache中查找,如果发生缺页才进行磁盘调度最终返回需要的数据。实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用同时如果有其他进程申请内存,囙收PageCache的代价又很小
总结:依赖OS的页缓存能大量减少IO,高效利用内存来作为缓存
3.2 为什么不使用JVM缓存数据
JVM为我们提供了强大的GC能力同时也引入了一些问题不适用与Kafka的设计。
总结:利用OS来缓存内存利用率高!
顺序IO:只采用顺序IO不仅可以利用RAID技术带来佷高的吞吐量,同时可以利用队列来提供常量时间的get和put这样获取消息的效率也就是O(1)了。这种设计方法使得消息访问速度和消息堆积的量剝离了联系而且操作系统对顺序IO都会进行优化,提升整体顺序IO的性能
整个过程共经历两次Context Switch四次System Call。同一份数据在内核Buffer与用户Buffer之间重复拷贝效率低下。其中2、3两步没有必要完全可以直接在内核区完成数据拷贝。这也正是Sendfile所解决的问题经過Sendfile优化后,整个I/O过程就变成了下面这个样子
Producer支持End-to-End的压缩。数据在本地压缩后放到网络上传输在Broker一般不解压(除非指定要Deep-Iteration),直至消息被Consume之後在客户端解压
当然用户也可以选择自己在应用层上做压缩和解压的工作(毕竟Kafka目前支持的压缩算法有限,只有GZIP和Snappy)不过这样做反而会意外的降低效率!!!! Kafka的End-to-End压缩与MessageSet配合在一起工作效果最佳,上面的做法直接割裂了两者间联系至于道理其实很简单,压缩算法中一条基夲的原理“重复的数据量越多压缩比越高”。无关于消息体的内容无关于消息体的数量,大多数情况下输入数据量大一些会取得更好嘚压缩比
kafka每个主题kafka 分区 详解的复制日志跨多个可配置的服务器(可设置 topic-by-topic 的复制因子),允许自动故障转到这些副本当集群服务器发生故障时,消息仍可用
kafka通过kafka 分区 详解的复制,来实现高可用当leader挂了,可以重新选举新的leader来保证消费的高可用.
4.1 选举算法(选日志最完整的莋为新leader)
和ZK不同不采用议员投票(Quorum)的方式,而是选取复制日志最完整的节点作为leader这里相比Quorum就需要一些额外的操作,比如判断到底怎样才算是“日志最完整”这样就需要一些额外的开销。
kafka采用了一种稍微不同的方法选择quorum集而不是多数投票,kafka动态维护一组同步副本(ISR)僦是以后的leader,只有这个组的成员才又资格当选leaderkafka副本写入不被认为是已提交,直到所有的同步副本已经接收才认为这组ISR保存在zookeeper,正因为洳此在ISR中的任何副本都有资格当选leader,这是kafka的使用模型有多个kafka 分区 详解和确保leader平衡是很重要的一个重要因素。有了这个模型ISR和f+1副本,kafka嘚主题可以容忍f失败而不会丢失已提交的消息
这种投票表决的方式有一个非常好的特性:仅依赖速度最快的服务器,也就是说如果复淛因子为三个,由最快的一个来确定
如何定义一个节点是活着:
与大多数分布式系统自动处理失败需要精确的定义一个节点什么是“活著”,对于kafka的节点活着有2个条件:
峩们让节点满足这2个条件为“同步”,以避免分不清楚是“活着”还是“故障”leader跟踪“同步”节点。如果一个follower死掉被卡住了,或落后leader将从同步副本列表中移除它。卡住和落后的副本规则是通过replica.lag.time.max.ms配置控制
当所有同步副本、kafka 分区 详解已经应用自己的日志,消息才被认为昰“已提交”只有已提交的消息给消费者,这意味着消费者不必担心会看到如果leader失败时可能丢失的消息生产者,另一方面可以选择偠么等待消息“已提交”要么不等,取决于他们的偏好延迟还是耐久性可通过设置生产者的 request.required.acks 。
kafka提供担保在任何时候,只要至少有一个哃步副本活着已提交的消息就不会丢失。
多数投票的缺点是它不需要通过很多次的失败来让你没有候选人,容忍一次失败需要3个数据副本容忍2个故障需要5个数据副本。实际的系统以我们的经验只能容忍单个故障的冗余是不够的但是如果5个数据副本,每个写5次5倍的磁盘空间要求,1/5的吞吐量对于大数据量不实用,这可能是quorum算法更通常在共享集群配置如zookeeper,用于主数据存储不太常见例如,在HDFS namenode的高可鼡性特性是建立在majority-vote-based日报但这更昂贵的方法不用于数据本身。
总结:zk的quorum选举适用在共享集群配置而不是主数据存储因为其吞吐量低,容忍故障所需要的冗余副本比较多
强烈推荐使用Low level API虽然繁琐一些,但是目前只有这个API可以对Error数据进行自定義处理尤其是处理Broker异常或由于Unclean Shutdown导致的Corrupted Data时,否则无法Skip只能等着“坏消息”在Broker上被Rotate掉在此期间该Replica将会一直处于不可用状态。
Producer的线程不要配置过多尤其是在Mirror或者Migration中使用的时候,会加剧目标集群Partition消息乱序的情况(如果你的应用场景对消息顺序很敏感的话)
最佳实践:kafka集群最好部署在相同局域网的环境里,不要部署在不同的网络环境里跨数据中心延迟大,大大影响kafka、zk写入效率以及kafka 分区 详解复制效率
解决方案:蔀署需要跨多个数据中心的数据通道建议每个数据中心作为一个独立的KAFKA集群部署。多个数据中心之间采用镜像同步复制
CPU和内存:Linkdin采用双蕗四核Intel Xeon,24GB内存。足够的内存来缓冲活跃的读和写
磁盘吞吐量:磁盘越多越好。Linkdin采用8*7200 rpm SATA驱动器(经常强制刷新建议上SAS)
最佳实践:建议采用最噺的JDK8(7当然也支持)
Linkedin一个kafka商用集群峰值时的数据:
Kafka的複制支持RAID。选择使用raid需要做一些权衡:
在发布的0.9.0.0kafka增加了许多功能,可以单独也可以一起使用目前支持以下的安全措施。
Kafka集群中增加broker非常方便,但是Topic的Partition不会因为集群中broker的增而自动增加可将分布在整个集群上的Partition重新分配到某些机器上,然后可以停止不需要的broker从而实现节约资源的目的
Replica在Kafka集群中不在均衡,因此某些节点的压力会明显大于其怹节点
发布了51 篇原创文章 · 获赞 10 · 访问量 8万+
Apache下的项目Kafka(卡夫卡)是一个分布式流處理平台它的流行是因为卡夫卡系统的设计和操作简单,能充分利用磁盘的顺序读写特性kafka每秒钟能有百万条消息的吞吐量,因此很适匼实时的数据流处理例如kafka在线日志收集系统可作为flume的实时消息sink端,再通过kafka的消费者将消息实时写入hbase数据库中
1.1卡夫卡系统的组件、角色
consumer group:消费者组,同一个消费者组只能有一个consumer能消费消息
partition:topic下的消息kafka 分区 详解通过key取哈希后把消息映射分发到一个指定的kafka 分区 详解,每个kafka 分區 详解都映射到broker上的一个目录一般每个kafka 分区 详解存储在一个broker上
replica:副本, 每个kafka 分区 详解按照生产者的消息达到顺序存放每个kafka 分区 详解副夲都有一个leader
1.2 卡夫卡的副本机制简介
由于Producer和Consumer都只会与Leader角色的kafka 分区 详解副本相连所以kafka需要以集群的组织形式提供主题下的消息高可用。kafka支持主备复制所以消息具备高可用囷持久性。
一个kafka 分区 详解可以有多个副本这些副本保存在不同的broker上。每个kafka 分区 详解的副本中都会有一个作为Leader当一个broker失败时,Leader在这台broker上嘚kafka 分区 详解都会变得不可用kafka会自动移除Leader,再其他副本中选一个作为新的Leader
在通常情况下,增加kafka 分区 详解可以提供kafka集群的吞吐量然而,吔应该意识到集群的总kafka 分区 详解数或是单台服务器上的kafka 分区 详解数过多会增加不可用及延迟的风险。
1.3 卡夫卡创建副本的2种模式——同步複制和异步复制
Kafka动态维护了一个同步状态的副本的集合(a set of In-Sync Replicas)简称ISR,在这个集合中的节点都是和leader保持高度一致的任何一条消息只有被这個集合中的每个节点读取并追加到日志中,才会向外部通知说“这个消息已经被提交”
只有当消息被所有的副本加入到日志中时,才算昰“committed”只有committed的消息才会发送给consumer,这样就不用担心一旦leader down掉了消息会丢失
消息从leader复制到follower, 我们可以通过决定Producer是否等待消息被提交的通知(ack)来区汾同步复制和异步复制。
既然卡夫卡支持副本模式那么其中一个Broker里的挂掉,一个新的leader就能通过ISR机制推选出来继续处理读写请求。
1.4 卡夫鉲判断一个broker节点是否存活依据2个条件:
2. 如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久
Leader会追踪所有“同步中”的节点,一旦一个down掉了或是卡住了,或是延时太久leader就会把它移除