《Kafka权威指南》重点第3,4,5,6章
《Kafka技术内幕》
《Kafka入门与实践》
Kafka数据单元被称为消息,类似数据库的一行;消息由字节数组组成,消息里的数据没有特别的格式或含义;
Kafka消息通过主题进行分类,主题好比数据库的表;主题被分为若干分区,一个分区就是一个提交日志;
消息以追加的方式写入分区,以先入先出的顺序读取;
由于一个主题一般包含几个分区,因此无法在整个主题范围内保证消息的顺序,但可以保证消息在单个分区内的顺序;
分区可以分布在不同的服务器上,一个主题可以横跨多个服务器;
(主题类似spark的RDD?主题和RDD都有分区,分布在集群中)
生产者默认情况下把消息均衡分布到主题的所有分区,而并不关心特定消息会被写到哪个分区;
(在某些情况下,生产者会把消息直接写到指定的分区。这通常是通过消息键和分区器来实现的)
消费者把每个分区最后读取的消息偏移量保存在Zookeeper或Kafka上,如果消费者关闭或重启,它的读取状态不会丢失;
消费者是消费者群组的一部分;会有一个或多个消费者共同读取一个主题;
群组保证每个分区只能被一个消费者使用;
(但一个消费者可以读取多个分区;)
如果一个消费者失效,群组里的其他消费者可以接管失效消费者的工作;
注意:如果一个customer消费到100位置 换成同一分组的另一个customer消费offset是从100开始消费;
但对不同分组的customer,可以从头消费;(前提auto.offset.reset 从latest改为earliest)
也就是说,偏移量是针对‘消费组’的!
http://www.cnblogs.com/yunxizhujing/articles/9463776.html
(在Kafka0.9版本之前消费者保存的偏移量是在zookeeper中/consumers/GROUP.ID/offsets/TOPIC.NAME/PARTITION.ID)
(到了0.9.0.0版本,Kafka引入了新的消费者接口,允许broker直接维护这些信息)
(建议使用最新版本的Kafka,让消费者把偏移量提交到 Kafka服务器上,消除对zk的依赖;)
一个独立的Kafka服务器被称为broker;单个broker可以轻松处理数千个分区以及每秒百万级的消息量;
每个集群都有一个broker同时充当了集群控制器的角色;
(自动从集群的活跃成员中选举出来)
控制器负责管理工作,包括将分区分配给broker和监控broker;
在集群中,一个分区从属于一个broker, 该broker被称为分区的首领;
一个分区可以分配给多个broker,这个时候会发生分区复制;
这种复制机制为分区提供了消息冗余,如果有一个broker失效,其他broker可以接管领导权;
(相关的消费者和生产者都要重新连接到新的首领;)
broker和分区到底啥关系??
每个分区都有副本?
Kafka broker消息保留策略是,要么保留一段时间(如7天),要么达到一定字节数(如1GB);
主题也可以设置自己的保留策略,如保留到不再使用为止;(如几天、几个小时)
最好在创建主题的时候就把分区规划好,永远不要增加新分区;
分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为再均衡;
再均衡非常重要,它为消费者群组带来了高可用性和伸缩性(我们可以放心地添加或移除消费者);
不过在正常情况下,我们并不希望发生这样的行为;
在再均衡期间,消费者无法读取消息,造成整个群组一小段时间的不可用;
消费者通过向broker发送心跳,来维持和群组的从属关系,以及对分区的所有权关系;
当长期没有收到消费者心跳,broker会认为它死亡,并触发一次再均衡;
(在0.10.1版本里,Kafka社区引入了一个独立的心跳线程;这样,发送心跳的频率和消息轮询的频率就是独立的)
一个消费者是一个线程还是进程?线程
一个消费者组的消费者可以在不同机器上吗?
如果想从分区的起始位置,或直接跳到分区的末尾开始读取消息,可以使用seekToBeginning和seekToEnd方法;
kafka偏移量可以保存在数据库,而不是zk吗?可以,然后使用consumer.seek()从特定偏移量开始处理记录;
意思是,在同一个事务里把记录和偏移量都写到数据库;《Kafka权威指南》P65
broker负载不均衡问题如何解决?
kafka丢失数据情况总结:
分为生产者发送消息给broker出错、broker出错、消费者读取消息出错三种情况;
生产者发送给broker出错情况:
(生产者有3种确认模式,acks=0速度快但不可靠;acks=1仍然有可能丢失数据,比如消息已经成功写入首领,但在被复制到跟随者副本之前首领发生奔溃;
acks=all首领在返回确认或错误响应之前,会等待所有同步副本都收到消息,生产者会一直重试直到消息被成功提交;根据可靠性需求配置恰当acks值;)
broker出错情况:
(replication.factor=3,代表每个分区会被3个不同的broker共复制3次;更高的复制系数会带来更高的可用性、可靠性和更少的故障;但会占用更多磁盘空间;
同时建议把broker分布在多个不同的机架上!)
(如果我们允许不同步的副本成为首领,就要承担丢失数据和出现数据不一致的风险;如果不允许它们成为首领,那么就要接受较低的可用性,因为我们必须等待原先首领恢复到可用状态;
看需求,如对于银行系统,设置unclean.leader.election.enable为false,即禁止不完全的首领选举;)
消费者读取消息出错情况:
(注意:只有那些被提交到Kafka的数据,也就是已经被写入所有同步副本的数据,对消费者是可用的,这意味着消费者得到的消息已经具备了一致性;
消费者唯一要做的是跟踪哪些消息已经读取过,哪些还没有读取过;这是在读取消息时不丢失消息的关键;)
(当消费者交接时,比如发生再均衡,如果消费者提交了偏移量却未能处理完消息,那么就有可能造成消息丢失,这也是消费者丢失消息的主要原因;
在处理完消息后再提交偏移量很关键,另外要避免消费者发生再均衡;------主要解决偏移量和消息的同步问题!)
(自动提交偏移量,可能会在消息还没有处理完毕就提交偏移量,可以改为显式提交偏移量;)
(显式提交偏移量,有8条建议;其中最后一条如何实现exactly-once如下)
Kafka消费者实现exactly-once方法:
尽管Kafka现在还不能完全支持exactly-once语义,消费者还是有一些办法可以保证Kafka里的每个消息只被写到外部系统一次
(但不会处理向 Kafka 写入数据时可能出现的重复数据;)《Kafka权威指南》P97
(实现仅一次处理最简单且最常用的办法是把结果写到一个支持唯一键的系统里,比如键值存储引擎、关系型数据库、ES或其他数据存储引擎;)
(数据存储引擎会覆盖已经存在的键值对,就像没有出现过重复数据一样,这个模式被叫作幂等性写入;)
(如果写入消息的系统支持事务,如关系型数据库,可以把消息和偏移量放在同一个事务里,这样它们就能保持同步;)
Kafka没有提供事务支持?0.11版本有exactly-once了
Kafka现在还不能完全支持exactly-once语义?0.11版本开始支持exactly-once
http://www.jasongj.com/kafka/transaction/ !!!
以下哪个说法正确:(CDE)
A. kafka消息丢失不可能是kafka自身的bug
B. kafka消息丢失一定能通过正确的代码和配置避免
C. kafka消息丢失可能是broker存储故障
D. kafka消息丢失可能是生产者漏发
E. kafka消息丢失可能是消费者偏移量管理出错
F. kafka消息丢失是因为没有事务支持
可以验证kafka系统可靠性,有3个方法:(这块只是说用什么方法观察、测试,是辅助手段,不是消息丢失根本原因和解决方法)
配置验证、应用程序验证以及生产环境的应用程序监控;
Kafka 提供了两个重要的工具用于验证配置: org.apache.kafka.tools包里的VerifiableProducer和VerifiableConsumer这两个类
应用程序是自己写的,最好包含集成测试;
生产环境监控使用JMX,最重要的两个可靠性指标是消息的error-rate 和 retry-rate(聚合过的);对于消费者来说,最重要的指标是consumer-lag
kafka源码(scala+java)
https://github.com/apache/kafka
kafka streams和spark streaming差不多?
(最近两年,Kafka将重心逐步转向 Streaming,通过内置流计算算子的形式提供一种轻量级的流计算解决方案)
https://github.com/apache/kafka/tree/trunk/streams
https://www.cnblogs.com/devos/p/5616086.html