一 新版本功能简介
书上第2章是介绍了kafka的版本历史。Kafka 的服务器端代码是由 Scala 语言编写的,而新版本客户端代码是由 Java语言编写的 .(书上指0.9.0版本),当然目前最新的版本是2.1.0. 版本演进的很快,大版本从0.11.0、1.0.0、1.1.0到2.0.从最初的标准消息系统,到现如今成为一个完整的包括导入导出和处理的流数据平台。功能越发完善,新功能不断添加进来。貌似我们现在还在用的是0.11版本。还没升到1.0.
1.1 producer
官网的demo如下:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("delivery.timeout.ms", 30000);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props);
for (int i = 0; i < 100; i++)
producer.send(new ProducerRecord<String, String>("my-topic", Integer.toString(i), Integer.toString(i)));
producer.close();
send()方法实现发送逻辑的主要入口。 后面看源码的时候会单独整理,这里只大概贴一下流程。
将待发送的消息封装成一个ProducerRecord对象,然后使用KafkaProducer.send()进行发送,KafkaProducer拿到消息后,先对其进行序列化,然后根据元数据信息确定目标分区,最后写入内存缓冲区,同时,KafkaProducer还有一个专门的Sender I/O线程,负责将缓冲区数据分批次发给broker。
producer较旧版本优点
1,发送过程分为两个线程,一个主线程和Sender I/O线程,逻辑更容易把控。
2,完全异步发送,回调(callback)机制用来判断发送是否成功
3,分批次(batching)发送,每个批次包含多个发送请求,提高吞吐量.
4,更合理的分区策略,旧版本对于没key的消息,会发送到固定分区,0.9.x采用轮询方式。
5,底层统一使用Java selector的网络客户端,结合future更优雅健壮实现生命周期管理。
设计优势如监控指标更完善,推荐新版本。
1.2 consumer
官网自动提交demo
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("foo", "bar"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records)
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
图片来源:zhangdd
消费者组的offset不依赖于zk旧版,大量的zk I/O会成为系统瓶颈,将消息封装到ConsumerRecord对象,然后使用KafkaConsumer.poll()进行拉取数据.
consumer较旧版本优点:
1.摒弃了消费不同分区时采用多线程的思想,只使用一个线程可以管理不同broker的多个socket
2.摆脱了offset对zk的依赖.
二 集群环境规划
这里需要根据实际业务情况去考虑,作者的第3章主要介绍了kafka的部署与参数。当然如果采用阿里云的alikafka 就更容易了。
2.1 操作系统选项
简单说下书上的结论Linux,
2.2 磁盘规划
机械硬盘满足需求,SSD更好。
2.3磁盘容量规划
对于磁盘容量的规划和以下结果因素有关:
第一:新增消息数;
第二:消息留存时间;
第四:平均消息大小;
第五:副本数;
第六:是否启用压缩;
2.4 内存规划
Kafka对于内存对使用可称作其设计亮点之一。虽然在前面我们强调了Kafka大量依靠和磁盘来保存消息,但其实它还会对消息进行缓存,而这个消息换粗你得地方就是内存,具体来说是操作系统对页缓存(page cache)。Kafka虽然会持久化每条消息,但其实这个工作都是底层对文件系统来完成。Kafka仅仅将消息写入page cache而已,之后将消息“flush”到磁盘对任务完全交由操作系统来完成。
一般情况下,broker所需的堆内存都不会超过6GB。所以对于一台16GB内存的机器而言,文件系统page cache的大小甚至可以达到10~14GB!总之对于内存规划的建议如下:
第一:尽量分配更多的内存给操作系统的page cache;
第二:不要为broker设置过大的堆内存,最好不超过6GB;
第三:page大小至少要大于一个日志段的大小;
2.5 CPU规划
比起磁盘和内存,CPU于kafka而言并没有那么重要,严格来说,kafka不属于计算密集型(CPU-bound)的系统,因此杜宇CPU需要记住一点就可以了:追求多核而非高时钟频率。咱们对CPU资源规划如下:
第一:使用多核系统,CPU核数最好大于8;
第二:如果使用Kafka 0.10.0.0之前的版本或clients端消息版本不一致(若无显式配置,这种情况多半由clients和broker版本不一致造成),则考虑多配置一些资源以防止消息解压操作消耗过多CPU)。
2.6.带宽规划
主流的以太网常见的前兆网络、万兆网络对于常见的kafka集群来说够用。建议规划如下:
第一:尽量使用高速网络;
第二:根据自身网络条件和带宽来评估Kafka集群机器数量;
第三:避免使用跨机房网络;