kafka-python实现生产同步和异步发送

1.kafka的生产三种方式:

发送并忘记
同步发送
异步发送加回调函数

2.kafka发送的ack值含义:

acks=0, 表示消息发送之后就不管了,无论消息是否写成功
acks=1,表示消息发送后并写成功kafka的topic对应分区的leader节点就返回成功
acks=-1/all,表示消息发送并写成功topic对应分区的leader节点,所有副本follow来同步数据成功,返回给leader节点,leader节点在一起返回确认给生产侧才表示写成功
那么下面就来看一下具体三种生产方式对应的代码:

1.1发送并忘记

-此方式只管发送,不关心消息是否都发送成功,对结果不做任何判断处理,实质上是异步发送不做回调,吞吐效率最高,无法保障可靠性

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from kafka import KafkaProducer
import logging,time
from datetime import datetime
logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
                    filename='producer.log',
                    filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
                    #a是追加模式,默认如果不写的话,就是追加模式
                    format=
                    '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
                    #日志格式
                    )
start = time.time()
producer = KafkaProducer(bootstrap_servers=['192.168.211.110:9092'],
                         #batch_size=5000,
                         #linger_ms=5
                        )
for i in range(20):
    #time.sleep(1)
    value = 'feifei' + str(i) + '_' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
    producer.send('test_pp01',value=value)
producer.flush()
end = time.time()
print "task cost {} s".format(end - start)

1.2 同步发送

-此方式是同步发送,会对每条消息的结果进行判断,future.get会进行阻塞直到返回数据表示发送成功,才会继续下一条消息的发送,可以直到每条信息的发送情况

此方式如果发送失败会进行重试并抛出异常,直至重试达到retries最大次数,此方式也是最大程度确保数据可靠性,可以记录对应的结果日志

# -*- coding:utf-8 -*-
#!/usr/bin/env python
from kafka import KafkaProducer
import time
broker = '192.168.211.110:9092'
topic = 'test_0613'
producer = KafkaProducer(bootstrap_servers=broker,
                        retries=3,
                        acks=-1
                        )
start_time = time.time()
for i in range(10):
    data = 'this is %s'%str(i)
    try:
       future = producer.send(topic,data)
       result = future.get(timeout=10)
       partition,offset = result.partition,result.offset
       print "partition={},offset={}".format(partition,offset)

    except kafka_errors as e:
       print e
end_time = time.time()
print "cost = %ss"%(end_time-start_time)

1.3 异步发送加回调函数

-在使用异步加回调的情况下,在使用send方法时指定一个回调函数,服务器在响应时会调用此函数,通过回调函数对结果进行处理,可以直到消息是写成功还是失败,回调函数执行完后才会结束,否则会一直阻塞

#!/usr/bin/evn python
from kafka import KafkaProducer
import time
broker = '192.168.211.110:9092'
topic = 'test_0613'
producer = KafkaProducer(bootstrap_servers=broker)

def on_send_success(*args,**kargs):
   print args
   return args

def on_send_error(*args,**kwargs):
   print args
   return args

start_time = time.time()
for i in range(0,10):
   data = 'test %s'%str(i)
   producer.send(topic,data).add_callback(on_send_success).add_errback(on_send_error)
producer.flush()
end_time = time.time()
print "cost={}".format(end_time-start_time)

综上对比可以看出,

使用发送并忘记也就异步发送最快,但是结果未知,无法保障可靠

同步方式最可靠可以重试,最大程度保障网络异常消息丢失等情况,可以通过异常自己做本地处理,可以确保消息不丢失

异步加回调效率高,也可以异步知道消息发送结果,缺点是无法重试

可以根据生产的场景选择同步发送或者异步加回调的方式

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐