您的位置:首页 > 其它

Kafka学习笔记01 - 设计理念

2014-08-12 00:00 260 查看
摘要: 阐述Kafka的设计理念,与普通的消息中间件不同,Kafka更关注性能。

Kafka是一个高性能,高可用,可持久化的,为分布式设计的消息中间件。与标准的,如ActiveMQ这样的消息中间件不同,Kafka对消息的“仅仅发送一次”并不关注。

Kafka的设计初衷是提供一个统一的处理实时数据的平台。和普通的消息中间件一样,Kafka也分为消息生产者,消息消费者和消息中介。



每一种消息的分类,叫主题(Topic)。一个消息中介可以包含多个不同的主题。为了分布式设计,每个主题又可以分成多个分区(Partition)。每个分区都是一个顺序写入,且不可变的文件。每个新的消息总是追加到文件尾部。每个消息都有一个编号(Offset),消费者可以通过这个编号选择消费消息。如下图:



由于主题都可以分成不同的分区,而每个分区可以分布在不同的机器上,所以实现了分布式功能。Kafka通过Zookeeper实现注册中心,会将消息生产者,消费者,消息中介的元数据存储到Zookeeper上。Kafka会自动将分区分配到不同的机器上。

对于将哪些消息发送到哪些分区,Kafka默认使用轮询调度的方式分配。但是也可以根据自己的业务场景,定制化实现消息分区逻辑。

每个分区的消费都是按照顺序的,但是跨分区的消息不保证顺序性。Kafka为消费者提供了GroupID的功能,同时只能有一个拥有同样GroupID的消费者,消费一个分区。这个有点像ActiveMQ里面的Exclusive Consumer功能。我们都知道,消息中间件分为Queue和Topic两种模式。如果每个消费者拥有同样的GroupID,那么这个主题就是被当做Queue方式消费,因为不会有消费者消费同样的消息;如果每个消费者拥有不同的GroupID,那么这个主题就是被当做Topic方式消费,因为每个消费者都会消费一遍这个消息。

消息生产者使用标准的推送(push)模型,将消息推送到消息中介。但是消息消费者不同,它使用拉取(pull)模型,主动的将消息从消息中介拉取到客户端。这样消息中介不需要维护消息的使用状态。消息推送的优势是,消息的实时性高,一旦消息中介接收到消息,可以马上推送给消费者。并且方便维护消息的消费状态。但是缺点也比较明显,不能得知消费者的状态,如果碰到消费者比发送者慢的情况,很容易造成消费者的消息堆积,最终压垮消费者。使用拉取模型,消费者可以根据自己的状态选择什么时间拉取多少消息,不会造成消费者的拥堵。并且为了提升吞吐量,可以一次批量拉取多条消息。

Kafka的消息中介不会存储消息消费的状态,而是把消息消费到哪里的偏移量存到客户端,并且同步到Zookeeper。可以选择批量同步,这样做的优势是提升吞吐量,风险是如果消费者崩溃,未同步的偏移量会导致消息重新消费。这个就引出了消息传递的语意。系统可以提供3种可能的消息传递保障方式:至多一次,至少一次和仅仅一次。至多一次是消息发送以后,无论消费者是否成功消费,消息都不会再重新发送。这个风险比较大,会丢消息。至少一次是,消息即使被消费,如果由于网络等原因造成消费状态没有同步,那么下次还是会消费同样的消息。这样虽然不会丢失消息,但是会导致重复消费,这就需要业务程序实现幂等性,即无论消费多少次都是同样的结果,这个对业务端的程序要求比较苛刻。最理想的方式当然是仅仅一次。这样如果消费消息之后,再存储消息已经被消费的状态时出现异常,那么被消费的数据会回滚,就当做消息没有消费。这是消息系统最完美的保障,但是是以牺牲性能为前提,所以使用仅仅一次的消费模型时需要确认,是不是真的有必要。ActiveMQ等JMS实现的消息中间件支持仅仅一次的消费模型,Kafka由于设计理念不同,只支持至少一次,牺牲一致性换取性能。

说到性能,最后一点需要关注的就是Kafka的存储方式。Kafka直接使用磁盘进行存储,没有使用缓存。由于操作系统本身是有缓存功能的,会先将数据放入缓存,经过一定时间刷盘存入硬盘。如果再使用JVM缓存,就会造成有两份缓存。Kafka最大限度的利用操作系统的缓存,所以如果想提升Kafka的性能,使用固态硬盘是个很好的手段。因为Kafka只是追加数据和顺序读,不会随机读写,所以即使直接使用磁盘 效率也很高。如果想不丢消息,可以修改Kafka的配置参数,每发送一条消息就同步一下磁盘,用降低性能的方式提高安全性。传统的消息中间件一般是使用Btree的方式存储消息,但是由于Kafka不会有随机读,所以使用BTree并无意义。而且BTree只有在内存中查找数据才比较快,是Log(n)。如果在硬盘中查找,每一次寻道都需要一定时间,大约(10ms),多次寻道会大幅降低效率。

Kafka会自动清理过期消息。无论消息是否被消费,创建时间2天(可设置)的消息将会被删除。

最后再说一下Kafka的消息高可用实现。Kafka使用复制备份机制存储消息。Kafka收到消息之后会向主节点和从节点发送消息。主节点用于接收和被消费消息,从节点只用于同步消息。Kafka的主从节点不是以服务器为粒度,而是以主题的分区为粒度。这样每台服务器都可能有主分区和从分区。最大限度的利用机器资源,而不是只有一台服务器接收请求,其他服务器等待。

总结一下,Kafka的优势是高性能,高可用。不足是消息可能会被消费多次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Kafka 消息中间件