前面讲到,Kafka的消息会分发到不同Topic,这样既解决了消息混乱的问题,又顺带将流量进行了分摊,减少单个业务写入压力。
但是,不同业务对应的数据量级是不一样的,就算按业务分了Topic,但一个Topic可能信息还是会非常多,我们需要进一步分而治之,所以Topic下面还划分了Partition来实际存储,每个Topic都可以有多个Partition,即分区,也可以叫分片。
分片的好处
通过将Topic进一步划分为Partition,我们实际上收获了如下好处:
- 提高写入性能,分片使得数据分布在多个Broker上,允许并行处理更多的数据请求,从而提高整体系统的吞吐量。
- 提高消费并发度,因为有多了个分片,那么不同消费者就可以对不同分片进行拉取消费,消费者和分区的关系在后面会单独展开
- 有了分片,显然后续更容易实现Kafka的水平扩展的能力
- 一定程度提高了 容错性,分片可以提高系统的容错能力。如果一个服务器上的分片发生故障,其他服务器上的分片可以继续处理数据请求,确保系统的高可用性。
怎么创建分片
之前我们创建了主题niugetest2,我们回顾一下它的信息:
可以看到只有一个Partition 0,那我们如何创建多个分片呢?
其实只需要加一个--partitions 参数,命令如下:
css
./kafka-topics.sh --create --bootstrap-server localhost:9092 --topic niugetest3 --partitions 3
通过这个命令,我们创建出来的主题就具备了3个分片:
怎么更改分片数量
运行时候我们可能会对分片数量进行调整,比如随着业务发展,原来的分片个数已经不足以支撑现有数据的流入速度,就通过如下命令可以更新分片数量
css
./kafka-topics.sh --alter --bootstrap-server localhost:9092 --topic niugetest3 --partitions 5
注意,分片数量只能调大不能变小,比如我们这里的分片数量已经是5了,如果试图用以下命令调整回3,会抛出如下错误:
分片的逻辑结构是怎样的
注意,同一个Partition里的数据,消息是有序的。即使同一个主题里的消息,如果分布在多个Partition,不同Partition 的消息之间也是无序的,这一点直接从这个结构图里也是能看出的。
数据流入哪个分片
一个主题的数据分散成了多个分片,我们就需要有一种方式来决定消息是写入哪个分片,规则如下:
- 如果指定了Partition,那么就是发送到特定的Partition,但是一般情况下,业务其实不需要感知Partition,除非有特殊理由,否则不建议直接指定要发送到哪个Partition;
- 如果没有指定Partition,但是指定了一个Key,那么就是根据Key的Hash对Partition数目取模来决定是哪个Partition,也就是说只要发送时指定了相同的Key,那么相关消息一定会发送到相同的Partition,比如图中我们假设Key是bbb时,Hash取模算出来是1,那么就写入对应的Partition1,如果每条数据都指定Key是bbb,那么这些数据都会流入Partition1;
- 如果没有指定Partition,也没有指定Key,那么就采取轮询调度算法,也就是每一次把来自用户的请求轮流分配给Partion,从第一个开始,直到最后一个,然后又从第一个开始,用我们上图的分片情况来说,就是第一条消息是Partition0,第二条消息是Partition1,第三条消息是Partition2,第四条又轮到Partition0,至此就是打了一圈。
从上面规则可以看到,如果是业务对顺序没有要求,那么就可以不指定Partition,也不指定Key,比如发短信这种业务,谁先谁后无所谓;如果业务对顺序有要求,比如先来先到的抢购,那么就可以指定一个Key,最简单的就是用业务名字当Key,这样来自同一个业务的消息,就放在同一个Partition里,这样数据就具备了有序性,这些数据也就达成了先进先出。
建议创建多少个分片?
一个主题,到底多少个分片比较合适?其实没有一个定数,一切按业务实际情况来规划。这里可以提供一个简单的思路:
- 就默认设置3个分片,大多数业务都是OK的,具体是否有问题,还是经过完善的测试才知道
- 根据产品预计的写入TPS来估计,比如你需要50000TPS的写入性能,那么先单个分区来测试,看看能达到多少,假设就是10000TPS,那我们来就试试2个分区是否能达到20000TPS,如果可以那么就可以设置5个分片来试试看是否达标,当然这里应该也并不是线性增长,具体还是以测试为准
- 根据产品预计的消费TPS来估计,假设一个消费者在消费一个分区的情况下性能能达到200/s,但是希望的是20000TPS的消费能力,这里就需要100台消费者才能满足,而对应的,分片也需要扩展到100个来进行支持。
总结
相比于主题这个逻辑概念而言,Partition就是实实在在的物理存储了,我们需要能理解分片的基础操作,同时对分片的逻辑结构也要有一定程度的了解。