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 09 Python
python difflib模块示例讲解
Sep 13 Python
python简单实例训练(21~30)
Nov 15 Python
Python中创建二维数组
Oct 17 Python
Django objects的查询结果转化为json的三种方式的方法
Nov 07 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
Dec 05 Python
python3实现带多张图片、附件的邮件发送
Aug 10 Python
python 字典访问的三种方法小结
Dec 05 Python
Pytorch实现LSTM和GRU示例
Jan 14 Python
Python读取图像并显示灰度图的实现
Dec 01 Python
python的scipy.stats模块中正态分布常用函数总结
Feb 19 Python
Pytorch 统计模型参数量的操作 param.numel()
May 13 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
php中将html中的br换行符转换为文本输入中的换行符
2013/03/26 PHP
2014年10个最佳的PHP图像操作库
2014/07/14 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
php curl请求信息和返回信息设置代码实例
2015/04/27 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
js监听键盘事件示例代码
2013/07/26 Javascript
简介JavaScript中substring()方法的使用
2015/06/06 Javascript
js数组如何添加json数据及js数组与json的区别
2015/10/27 Javascript
JS实现点击按钮获取页面高度的方法
2015/11/02 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
两种方法解决javascript url post 特殊字符转义 + & #
2016/04/13 Javascript
第六章之辅组类与响应式工具
2016/04/25 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
快速解决js开发下拉框中blur与click冲突
2016/10/10 Javascript
JS设计模式之数据访问对象模式的实例讲解
2017/09/30 Javascript
vuejs前后端数据交互之从后端请求数据的实例
2018/08/11 Javascript
微信小程序canvas.drawImage完全显示图片问题的解决
2018/11/30 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
[01:04:06]DOTA2上海特级锦标赛A组资格赛#2 Secret VS EHOME第一局
2016/02/26 DOTA
Python单元测试框架unittest简明使用实例
2015/04/13 Python
Python监控主机是否存活并以邮件报警
2015/09/22 Python
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/26 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
基于SQLAlchemy实现操作MySQL并执行原生sql语句
2020/06/10 Python
Python 实现一个简单的web服务器
2021/01/03 Python
html5中的一些标签学习(心得)
2016/10/18 HTML / CSS
html5组织内容_动力节点Java学院整理
2017/07/10 HTML / CSS
心理健康教育心得体会
2013/12/29 职场文书
公司董事长岗位职责
2014/06/08 职场文书
上海世博会口号
2014/06/19 职场文书
齐云山导游词
2015/02/06 职场文书
敬老院志愿者活动总结
2015/05/06 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
2022/04/18 MySQL