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动态监控日志内容的示例
Feb 16 Python
Python实现定时任务
Feb 08 Python
浅谈对yield的初步理解
May 29 Python
Python中input与raw_input 之间的比较
Aug 20 Python
python 上下文管理器使用方法小结
Oct 10 Python
Python实现打印螺旋矩阵功能的方法
Nov 21 Python
python决策树之C4.5算法详解
Dec 20 Python
python面向对象实现名片管理系统文件版
Apr 26 Python
如何在Django配置文件里配置session链接
Aug 06 Python
pytorch下大型数据集(大型图片)的导入方式
Jan 08 Python
在pycharm中创建django项目的示例代码
May 28 Python
详细分析Python垃圾回收机制
Jul 01 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调用三种数据库的方法(1)
2006/10/09 PHP
php中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
2010/12/19 PHP
基于PHP导出Excel的小经验 完美解决乱码问题
2013/06/10 PHP
PHP函数addslashes和mysql_real_escape_string的区别
2014/04/22 PHP
php用户登录之cookie信息安全分析
2016/05/13 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
JavaScript 比较时间大小的代码
2010/04/24 Javascript
jQuery创建插件的代码分析
2011/04/14 Javascript
javascript中的window.location.search方法简介
2013/09/02 Javascript
js操作iframe父子窗体示例
2014/05/22 Javascript
jQuery判断对象是否存在的方法
2015/02/05 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
2015/09/16 Javascript
javascript+HTML5自定义元素播放焦点图动画
2016/02/21 Javascript
AngularJS表单基本操作
2017/01/09 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
python中实现指定时间调用函数示例代码
2017/09/08 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
python决策树之CART分类回归树详解
2017/12/20 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
python实现随机漫步算法
2018/08/27 Python
python 实现selenium断言和验证的方法
2019/02/13 Python
详解Python下载图片并保存本地的两种方式
2019/05/15 Python
keras .h5转移动端的.tflite文件实现方式
2020/05/25 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
台湾流行服饰购物平台:OB严选
2018/01/21 全球购物
Funko官方商店:源自美国,畅销全球搪胶收藏玩偶
2018/09/15 全球购物
音乐教学随笔感言
2014/02/19 职场文书
文化建设工作方案
2014/05/12 职场文书
2014年城市管理工作总结
2014/12/02 职场文书
2014年党支部书记工作总结
2014/12/04 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
javaScript Array api梳理
2021/03/31 Javascript
MySQL中IO问题的深入分析与优化
2022/04/02 MySQL
大脑的记忆过程在做数据压缩,不同图形也有共同的记忆格式
2022/04/29 数码科技