多分区生产及消费问题
当kafka中的某一个topic数据量很大的时候就会导致消费者处理数据很慢,那我们可能会想着适当的增加分区(partition)来提高消费者的消费速度,那么我们创建多个分区的时候,生产者是如何分配生产的消息到分区的尼,并且如何指定分区消费消息的,让我走进科学世界.
一. 创建一个topic同时建立多个分区
./kafka-topics.sh --create --zookeeper 172.18.10.48:2181 --replication-factor 1 --partitions 2 --topic kafka_test
我们创建了一个叫kafka_test的topic,同时设置partition(分区)为2.
二.创建一个生产者
import json
from kafka import KafkaProducer
servers = ['172.18.10.48:9092']
topic_name = 'kafka_test'
def method_one():
def kafka_product(servers, topic_name, msg):
# 将数据放入kafka生产者中
producer = KafkaProducer(bootstrap_servers=servers)
message = json.dumps(msg).encode()
producer.send(topic_name, message)
for index in range(1, 1000):
data = {'tracking_number': 'data_%s' % index}
kafka_product(servers=servers, topic_name=topic_name, msg=data)
def method_two():
def kafka_product(servers, topic_name, msg, sign):
# 将数据放入kafka生产者中
producer = KafkaProducer(bootstrap_servers=servers)
message = json.dumps(msg).encode()
if sign:
producer.send(topic_name, message,partition=0)
else:
producer.send(topic_name, message, partition=1)
for index in range(1, 1000):
sign = True if index % 2 == 1 else False
data = {'tracking_number': 'data_%s' % index}
kafka_product(servers=servers, topic_name=topic_name, msg=data, sign=sign)
if __name__ == '__main__':
method_one()
method_two()
我们将采用两者方式对比生产者分配消息到分区的情况:
方式一: 让生产者自由分配消息到分区;
方式二: 我们采用计算的方式均匀的分配到各个分区;
三. 创建一个消费者
import json
from pykafka import KafkaClient
servers = ['172.18.10.48:9092']
topic_name = 'kafka_test'
def kafka_customer_handle(servers, topic_name,partition):
# kafka消费数据
servers = ','.join(servers) # '127.0.0.1:9092,127.0.0.2:9092,127.0.0.3:9092'
client = KafkaClient(hosts=servers)
topic = client.topics[topic_name]
partitions = topic.partitions
consumer = topic.get_simple_consumer(consumer_group=topic_name, auto_commit_interval_ms=1, auto_commit_enable=True,
consumer_id=b'rpo', partitions=[partitions[partition]])
print(consumer.held_offsets) # 获取偏移量
print("分区 {}".format(partitions))
earliest_offsets = topic.earliest_available_offsets()
print("最早可用offset {}".format(earliest_offsets))
last_offsets = topic.latest_available_offsets()
print("最近可用offset {}".format(last_offsets))
offset = consumer.held_offsets
print("当前消费者分区offset情况{}".format(offset))
number = 0
for message in consumer:
value = json.loads(message.value.decode(encoding='utf-8'))
number+=1
print(number)
partition = 0 # 分区
kafka_customer_handle(servers, topic_name,partition)
注意这里需求手动修改下partition分区,因为消费者是阻塞的.
四. 结论
如果存在多个分区,生产者会均匀的分配到各个分区,不需要手动指定分区,当然我们特殊情景的除外.