最近在学习kafka,参考官网上的文档,概括kafka的主要设计点,希望能帮助大家对kafka的设计有一个大概的了解,没说清楚的地方,或者不对的地方希望大家指出,相互帮助学习,
4. kafka设计简介
1
2
3
4
4.1 动机
- 高吞吐量以支持大数据量的事件流,例如实时日志集结
- 能很好处理大数据积压以支持线下阶段性数据加载
- 低延迟的消息传送,以支持传统的消息系统应用
- 支持分区,分布式,实时处理
- 高可用,故障容错
因此,kafka被设计成一个有独特的元素,类似于数据库日志的传统的消息系统
4.2 持久化
- Kafka直接依赖系统的文件系统存储和缓存,(java NIO)
- 常量时长足够了
消息系统大多数使用Btree作为持久化数据结构,存储系统一般混合了高速缓存和真正的磁盘读取,所以读取性能是不错的。但是随着数据量的成倍的增长,性能也会成倍的下降
所以kafaka 使用的是持久化队列,这样设计明显的优势是与数据量大小无关,并且读不会阻塞写,服务器可以利用便宜的硬盘获得可观的性能
4.3 效率
支持批量存取,批量会有的影响,大的网络数据包,大的连续的磁盘操作,连续内存块请求等等,所有这些都可以使kafka将突发性的大的数据流量转变为线性写
支持数据压缩,并使用直接内存(javaNio)避免不必要的程序级别的复制,支持批量数据压缩(这样比单独压缩一个消息更有效),只有在消费信息的时候才会解压
4.4 Producer(生产者)
负载均衡
生产直接可以将消息发送到broker而不需要任何中间路由,因为kafka每个节点都提供关于其主题每个分区的leader在那个节点的相关元数据查询
异步发送
批量操作是效率提升的一个重要驱动,producer可以在指定的边界缓存操作以批量操作
4.5 Consumer(消费者)
- Push vs poll
Kafka遵从大多数消息系统的设计,由producer将数据push到broker,由consumer 从
Broker pull数据。而Scribe and Apache Flume 遵从了一个不同的设计(push based),但这样有个坑,假如consumer的处理效率没有broker转发效率高,就有可能压垮消费者
4.6 消息传播
4.7 复制
- 法定人数和状态机
大部分日志复制都采用state-machinestyle,即只要领导者可以用,领导者选择那些命令用来复制,跟随者只要有序的复制这些值就可以了
大部分系统使用多数人投票策略(This majority vote approach)来决定leader和消息提交确认,这样的好处就可以选择其中最快的机器作为新的leader.但是这种策略的坏处是,系统不能容忍多的故障。比如你要能容忍f个错,你就必须有2f+1的复制才足够,这样对于大规模数据来说是不可行的,因为这样你损失了太多吞吐量了,比如(paxos算法)
而kafak利用zookeeper动态地维护了一套in-syncreplica(ISR),只有ISR集里面的才可以被选为leader,所以容忍f个故障,只要有f+1个复制就可以了。虽然要容忍f个故障,
Majority vote 和 ISR都需要等同样多的复制完成。
kafka另一个特性是允许有不完整数据的节点恢复
- 耐用和高可用保证
Producer配置request.required.acks=-1,0,1
0
1表示只要in-sync里的replica都接受了,就认为提交成功
-1 表示要in-sync里的复制都完成写了,才认为提交成功
- 复制管理
以上复制讲的是一个主题的一个分区,而kafka管理者上千个这样的分区。所以kafka平衡分区以避免集中一个大的topic的所有分区在几个节点(broker)上,因此kafka将领导职权平衡到所有节点上,每个节点都是它所保存的分区的一部分的leader
当一个节点失败,只会对受影响的分区进行选举,我们选择一个broker作为controller,controller负责侦测broker级别的错误,并负责受影响分区重新选择leader