python kafka 多线程消费者&手动提交实例


Posted in Python onDecember 21, 2019

官方文档:https://kafka-python.readthedocs.io/en/master/apidoc/KafkaConsumer.html

import threading
 
import os
import sys
from kafka import KafkaConsumer, TopicPartition, OffsetAndMetadata
 
from consumers.db_util import *
from consumers.json_dispose import *
from collections import OrderedDict
 
 
threads = []
# col_dic, sql_dic = get()
 
 
class MyThread(threading.Thread):
  def __init__(self, thread_name, topic, partition):
    threading.Thread.__init__(self)
    self.thread_name = thread_name
    # self.keyName = keyName
    self.partition = partition
    self.topic = topic
 
  def run(self):
    print("Starting " + self.name)
    Consumer(self.thread_name, self.topic, self.partition)
 
  def stop(self):
    sys.exit()
 
 
def Consumer(thread_name, topic, partition):
  broker_list = '172.16.90.63:6667, 172.16.90.58:6667, 172.16.90.59:6667'
  '''
  fetch_min_bytes(int) - 服务器为获取请求而返回的最小数据量,否则请等待
  fetch_max_wait_ms(int) - 如果没有足够的数据立即满足fetch_min_bytes给出的要求,服务器在回应提取请求之前将阻塞的最大时间量(以毫秒为单位)
  fetch_max_bytes(int) - 服务器应为获取请求返回的最大数据量。这不是绝对最大值,如果获取的第一个非空分区中的第一条消息大于此值,
              则仍将返回消息以确保消费者可以取得进展。注意:使用者并行执行对多个代理的提取,因此内存使用将取决于包含该主题分区的代理的数量。
              支持的Kafka版本> = 0.10.1.0。默认值:52428800(50 MB)。
  enable_auto_commit(bool) - 如果为True,则消费者的偏移量将在后台定期提交。默认值:True。
  max_poll_records(int) - 单次调用中返回的最大记录数poll()。默认值:500
  max_poll_interval_ms(int) - poll()使用使用者组管理时的调用之间的最大延迟 。这为消费者在获取更多记录之前可以闲置的时间量设置了上限。
                如果 poll()在此超时到期之前未调用,则认为使用者失败,并且该组将重新平衡以便将分区重新分配给另一个成员。默认300000
  '''
  consumer = KafkaConsumer(bootstrap_servers=broker_list,
               group_id="xiaofesi",
               client_id=thread_name,
               enable_auto_commit=False,
               fetch_min_bytes=1024*1024,#1M
               # fetch_max_bytes=1024 * 1024 * 1024 * 10,
               fetch_max_wait_ms=60000,#30s
               request_timeout_ms=305000,
               # consumer_timeout_ms=1,
               # max_poll_records=5000,
               # max_poll_interval_ms=60000 无该参数
               )
  #查出数据库上次保存的offset,此offset已经是上次消费最后一条的offset的offset+1,也就是这次消费的起始位
  dic = get_kafka(topic, partition)
  tp = TopicPartition(topic, partition)
  print(thread_name, tp, dic['offset'])
  #分配该消费者的TopicPartition,也就是topic和partition,根据参数,我是三个消费者,三个线程,每个线程消费者消费一个分区
  consumer.assign([tp])
  #重置此消费者消费的起始位
  consumer.seek(tp, dic['offset'])
  print("程序首次运行\t线程:", thread_name, "分区:", partition, "偏移量:", dic['offset'], "\t开始消费...")
  num=0 #记录该消费者消费次数
  # end_offset = consumer.end_offsets([tp])[tp]
  # print(end_offset)
  while True:
    args = OrderedDict()
    msg = consumer.poll(timeout_ms=60000)
    end_offset = consumer.end_offsets([tp])[tp]
    print('已保存的偏移量', consumer.committed(tp),'最新偏移量,',end_offset)
    if len(msg) > 0:
      print("线程:", thread_name, "分区:", partition, "最大偏移量:", end_offset, "有无数据,", len(msg))
      lines=0
      for data in msg.values():
        for line in data:
          lines+=1
          line = eval(line.value.decode('utf-8'))
          '''
          do something
          '''
      # 线程此批次消息条数
      print(thread_name,"lines",lines)
      #数据保存至数据库
      is_succeed = save_to_db(args, thread_name)
      if is_succeed:
        #更新自己保存在数据库中的各topic, partition的偏移量
        is_succeed1 = update_offset(topic, partition, end_offset)
        #手动提交偏移量 offsets格式:{TopicPartition:OffsetAndMetadata(offset_num,None)}
        consumer.commit(offsets={tp:(OffsetAndMetadata(end_offset,None))})
        print(thread_name,"to db suss",num+1)
        if is_succeed1 == 0:
          #系统退出?这个还没试
          os.exit()
          '''
          sys.exit()  只能退出该线程,也就是说其它两个线程正常运行,主程序不退出
          '''
      else:
        os.exit()
    else:
      print(thread_name,'没有数据')
    num+=1
    print(thread_name,"第",num,"次")
 
 
if __name__ == '__main__':
  try:
    t1 = MyThread("Thread-0", "test", 0)
    threads.append(t1)
    t2 = MyThread("Thread-1", "test", 1)
    threads.append(t2)
    t3 = MyThread("Thread-2", "test", 2)
    threads.append(t3)
 
    for t in threads:
      t.start()
 
    for t in threads:
      t.join()
 
    print("exit program with 0")
  except:
    print("Error: failed to run consumer program")

以上这篇python kafka 多线程消费者&手动提交实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
深入解析Python中的线程同步方法
Jun 14 Python
python处理Excel xlrd的简单使用
Sep 12 Python
python实现Adapter模式实例代码
Feb 09 Python
Python装饰器用法实例总结
May 26 Python
python事件驱动event实现详解
Nov 21 Python
Python 获取中文字拼音首个字母的方法
Nov 28 Python
python Pexpect 实现输密码 scp 拷贝的方法
Jan 03 Python
深入浅析python3中的unicode和bytes问题
Jul 03 Python
pandas read_excel()和to_excel()函数解析
Sep 19 Python
python list数据等间隔抽取并新建list存储的例子
Nov 27 Python
logging level级别介绍
Feb 21 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
Dec 10 Python
Python序列类型的打包和解包实例
Dec 21 #Python
Python 使用threading+Queue实现线程池示例
Dec 21 #Python
Python CSV文件模块的使用案例分析
Dec 21 #Python
python实现的分析并统计nginx日志数据功能示例
Dec 21 #Python
Python数据持久化存储实现方法分析
Dec 21 #Python
python cv2截取不规则区域图片实例
Dec 21 #Python
Python lxml模块的基本使用方法分析
Dec 21 #Python
You might like
CodeIgniter扩展核心类实例详解
2016/01/20 PHP
PHP实现带进度条的Ajax文件上传功能示例
2019/07/02 PHP
一些常用的Javascript函数
2006/12/22 Javascript
javascript延时重复执行函数 lLoopRun.js
2007/06/29 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
《JavaScript函数式编程》读后感
2015/08/07 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
2015/08/18 Javascript
跟我学习javascript的Date对象
2015/11/19 Javascript
jQuery+ajax实现文章点赞功能的方法
2015/12/31 Javascript
如何抽象一个Vue公共组件
2017/10/17 Javascript
jquery ztree实现右键收藏功能
2017/11/20 jQuery
详解Vue2 SSR 缓存 Api 数据
2017/11/20 Javascript
vscode 开发Vue项目的方法步骤
2018/11/25 Javascript
vue写h5页面的方法总结
2019/02/12 Javascript
深入学习TypeScript 、React、 Redux和Ant-Design的最佳实践
2019/06/17 Javascript
jquery html添加元素/删除元素操作实例详解
2020/05/20 jQuery
node中短信api实现验证码登录的示例代码
2021/01/20 Javascript
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
Python随机函数random()使用方法小结
2018/04/29 Python
python批量复制图片到另一个文件夹
2018/09/17 Python
Python从数据库读取大量数据批量写入文件的方法
2018/12/10 Python
Python中GeoJson和bokeh-1的使用讲解
2019/01/03 Python
python实现人脸签到系统
2020/04/13 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
Python使用os.listdir和os.walk获取文件路径
2020/05/21 Python
HTML5 canvas基本绘图之文字渲染
2016/06/27 HTML / CSS
关于Assembly命名空间的三个面试题
2015/07/23 面试题
房屋继承公证书
2014/04/10 职场文书
保护母亲河倡议书
2014/04/14 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
文明寝室申报材料
2014/05/12 职场文书
投标保密承诺书
2014/05/19 职场文书
新党章的学习心得体会
2014/11/07 职场文书
我们的节日端午节活动总结
2015/02/11 职场文书
六五普法先进个人主要事迹材料
2015/11/03 职场文书