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抓取某汽车网数据解析html存入excel示例
Dec 04 Python
python复制与引用用法分析
Apr 08 Python
Python2.7简单连接与操作MySQL的方法
Apr 27 Python
替换python字典中的key值方法
Jul 06 Python
python实现祝福弹窗效果
Apr 07 Python
浅谈python图片处理Image和skimage的区别
Aug 04 Python
Python(PyS60)实现简单语音整点报时
Nov 18 Python
python操作cfg配置文件方式
Dec 22 Python
Python ini文件常用操作方法解析
Apr 26 Python
Python爬虫如何应对Cloudflare邮箱加密
Jun 24 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
Feb 25 Python
OpenCV-Python实现怀旧滤镜与连环画滤镜
Jun 09 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之第四天
2006/10/09 PHP
将一维或多维的数组连接成一个字符串的php代码
2010/08/08 PHP
Laravel4中的Validator验证扩展用法详解
2016/07/26 PHP
Jquery easyUI 更新行示例
2014/03/06 Javascript
jQuery类选择器用法实例
2014/12/23 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
JavaScript每天必学之基础知识
2016/09/17 Javascript
vue树形结构获取键值的方法示例
2018/06/21 Javascript
快速解决angularJS中用post方法时后台拿不到值的问题
2018/08/14 Javascript
vue新建项目并配置标准路由过程解析
2019/12/09 Javascript
JavaScript实现英语单词题库
2019/12/24 Javascript
Electron整合React使用搭建开发环境的步骤详解
2020/06/07 Javascript
Openlayers实现距离面积测量
2020/09/28 Javascript
[01:37]PWL S2开团时刻DAY1&2——这符有毒
2020/11/20 DOTA
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
Python外星人入侵游戏编程完整版
2020/03/30 Python
python的paramiko模块实现远程控制和传输示例
2017/10/13 Python
简单实现python数独游戏
2018/03/30 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
Python定义一个函数的方法
2020/06/15 Python
pycharm2020.1.2永久破解激活教程,实测有效
2020/10/29 Python
纯DOM+CSS3实现简单的小风车动画
2016/09/27 HTML / CSS
使用css如何制作时间ICON方法实践
2012/11/12 HTML / CSS
Qoo10马来西亚:全球时尚和引领潮流的购物市场
2016/08/25 全球购物
StubHub哥伦比亚:购买和出售您的门票
2016/10/20 全球购物
Booking.com缤客中国:全球酒店在线预订网站
2020/05/03 全球购物
如何在Cookie里面保存Unicode和国际化字符
2013/05/25 面试题
网络专业学生个人的自我评价
2013/12/16 职场文书
生日主持词
2014/03/20 职场文书
给校长的建议书600字
2014/05/15 职场文书
2014年会计工作总结
2014/11/27 职场文书
小学英语课教学反思
2016/02/15 职场文书
求职信如何撰写?
2019/05/22 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
古诗之爱国古诗5首
2019/09/20 职场文书
nginx设置资源请求目录的方式详解
2022/05/30 Servers