总之:kafka是用于构建实时的数据管道和流应用程序。具备横向扩展,容错等优点。
consumerGroup组员之间不能重复消费。
partition的目录中有多个segment组合(index,log)一个Topic对应多个partition[0,1,2,3],一个partition对应多个segment组合。一个segment有默认的大小是1G,消息都在segment上面存储。
kafka吞吐量大的原因: 1.kafka针对一个partition,不是通过对多个consumer thread加悲观锁来防止重复消费,而是一个partition只能同时被一个consumer thread消费,如果消息数量太大觉得效率不高要增大吞吐量,直接横向扩展partition数量,同时增加一个consumer group下的consumer thread数量即可。这样没有锁竞争,充分发挥了横向的扩展性,吞吐量极高。2.kafka分布式并发的读和写都非常快,写的性能体现在以o(1)的时间复杂度进行顺序写入。读的性能体现在以o(1)的时间复杂度进行顺序读取, 对topic进行partition分区,consume group中的consume线程可以以很高能性能进行顺序读。
kafka消息是顺序读取,必须维护上一次读到哪里的offset信息。 维护offset有两套机制,high level API的offset存于Zookeeper中;low level API的offset由自己维护。
因为消息的读取进度由offset提供,offset可以由消费者自己维护也可以维护在zookeeper里,但是当消息消费后consumer挂掉, offset没有即时写回,就有可能发生重复读的情况,这种情况同样可以通过调整commit offset周期、阈值缓解,甚至消费者自己把消费和commit offset做成一个事务解决, 但是如果你的应用不在乎重复消费,那就干脆不要解决,以换取最大的性能。
Kafka提供了两套consumer api,分为high-level api和sample-api。
在kafka中,当前读到哪条消息的offset值是由consumer来维护的,因此,consumer可以自己决定如何读取kafka中的数据 。比如,consumer可以通过重设offset值来重新消费已消费过的数据。不管有没有被消费,kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期时间,kafka才会删除这些数据.
High level api是consumer读的partition的offsite是存在zookeeper上。High level api 会启动另外一个线程去每隔一段时间,offsite自动同步到zookeeper上。 换句话说,如果使用了High level api, 每个message只能被读一次,一旦读了这条message之后,无论我consumer的处理是否ok。 High level api的另外一个线程会自动的把offiste+1同步到zookeeper上。如果consumer读取数据出了问题,offsite也会在zookeeper上同步。 因此,如果consumer处理失败了,会继续执行下一条。因此,Best Practice是一旦consumer处理失败,直接让整个conusmer group抛Exception终止 ,但是最后读的这一条数据是丢失了,因为在zookeeper里面的offsite已经+1了。 等再次启动conusmer group的时候,已经从下一条开始读取处理了。
consumer读的partition的offsite在consumer自己的程序中维护。不会同步到zookeeper上。 但是为了kafka manager能够方便的监控,一般也会手动的同步到zookeeper上。
ack机制:broker表示发来的数据已确认接收无误,表示数据已经保存到磁盘。
摘录了一下大神的博客,如下:
kafka_log.png