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使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
May 15 Python
最近Python有点火? 给你7个学习它的理由!
Jun 26 Python
python实现简单多人聊天室
Dec 11 Python
python与字符编码问题
May 24 Python
python爬虫 爬取超清壁纸代码实例
Aug 16 Python
Python爬虫 批量爬取下载抖音视频代码实例
Aug 16 Python
python实现矩阵和array数组之间的转换
Nov 29 Python
python爬虫开发之selenium模块详细使用方法与实例全解
Mar 09 Python
python 等差数列末项计算方式
May 03 Python
DataFrame 数据合并实现(merge,join,concat)
Jun 14 Python
python使用matplotlib绘制折线图的示例代码
Sep 22 Python
scrapy处理python爬虫调度详解
Nov 23 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
PHPMyadmin 配置文件详解(配置)
2009/12/03 PHP
php+mysqli事务控制实现银行转账实例
2015/01/29 PHP
php下载文件,添加响应头的简单实例
2016/09/22 PHP
PHP使用Redis替代文件存储Session的方法
2017/02/15 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
通过源码解析Laravel的依赖注入
2018/01/22 PHP
jquery创建一个ajax关键词数据搜索实现思路
2013/02/26 Javascript
javascript 小数取整简单实现方式
2014/05/30 Javascript
简单的jquery左侧导航栏和页面选中效果
2014/08/21 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
JavaScript中字面量与函数的基本使用知识
2015/10/20 Javascript
解析Node.js基于模块和包的代码部署方式
2016/02/16 Javascript
浅谈javascript中的Function和Arguments
2016/08/30 Javascript
Vue.js如何优雅的进行form validation
2017/04/07 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
2017/12/14 Javascript
vue cli webpack中使用sass的方法
2018/02/24 Javascript
vue实现可视化可拖放的自定义表单的示例代码
2019/03/20 Javascript
jQuery内容选择器与表单选择器实例分析
2019/06/28 jQuery
JavaScript进阶(一)变量声明提升实例分析
2020/05/09 Javascript
Vue scoped及deep使用方法解析
2020/08/01 Javascript
[02:52]DOTA2新手基础教程 米波
2014/01/21 DOTA
python解决字典中的值是列表问题的方法
2013/03/04 Python
使用Python的Tornado框架实现一个简单的WebQQ机器人
2015/04/24 Python
浅谈Python的垃圾回收机制
2016/12/17 Python
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
python构建指数平滑预测模型示例
2019/11/21 Python
python数据分析:关键字提取方式
2020/02/24 Python
HTML5 实战PHP之Web页面表单设计
2011/10/09 HTML / CSS
意大利独特而优质的家居用品:Fazzini
2018/12/05 全球购物
美国浴缸、水槽和水龙头购物网站:Vintage Tub & Bath
2019/11/05 全球购物
医学生个人求职信范文
2014/02/07 职场文书
政风行风整改方案
2014/10/25 职场文书
2016年端午节寄语
2015/12/04 职场文书
高中16字霸气押韵班级口号集锦!
2019/06/27 职场文书
MySQL高速缓存启动方法及参数详解(query_cache_size)
2021/07/01 MySQL