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列表推导式的使用方法
Nov 21 Python
详解Python中for循环的使用
Apr 14 Python
Python 模拟员工信息数据库操作的实例
Oct 23 Python
python按行读取文件,去掉每行的换行符\n的实例
Apr 19 Python
Python实现的读取/更改/写入xml文件操作示例
Aug 30 Python
Python 实现大整数乘法算法的示例代码
Sep 17 Python
tensorflow estimator 使用hook实现finetune方式
Jan 21 Python
Python编程快速上手——选择性拷贝操作案例分析
Feb 28 Python
使用Python发现隐藏的wifi
Mar 04 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
Python try except else使用详解
Jan 12 Python
python pyg2plot的原理知识点总结
Feb 28 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 CURL获取邮箱地址的详解
2013/06/03 PHP
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
PHP实现下载断点续传的方法
2014/11/12 PHP
php下pdo的mysql事务处理用法实例
2014/12/27 PHP
php单例模式实现方法分析
2015/03/14 PHP
PHP使用OB缓存实现静态化功能示例
2019/03/23 PHP
js文件中调用js的实现方法小结
2009/10/23 Javascript
javascript获取隐藏dom的宽高 具体实现
2013/07/14 Javascript
Jquery 获取对象的几种方式介绍
2014/01/17 Javascript
jQuery实现回车键(Enter)切换文本框焦点的代码实例
2014/05/05 Javascript
jQuery中的编程范式详解
2014/12/15 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
2016/01/04 Javascript
基于jquery实现的银行卡号每隔4位自动插入空格的实现代码
2016/11/22 Javascript
jQuery实现的动态文字变化输出效果示例【附演示与demo源码下载】
2017/03/24 jQuery
jquery实现图片上传前本地预览
2017/04/28 jQuery
浅谈jquery fullpage 插件增加头部和版权的方法
2018/03/20 jQuery
JavaScript实现连连看连线算法
2019/01/05 Javascript
JS判断两个数组或对象是否相同的方法示例
2019/02/28 Javascript
javascript事件监听与事件委托实例详解
2019/08/16 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
2019/10/23 jQuery
python with statement 进行文件操作指南
2014/08/22 Python
分析python切片原理和方法
2017/12/19 Python
Python3.5 创建文件的简单实例
2018/04/26 Python
python实现linux下抓包并存库功能
2018/07/18 Python
用python代码将tiff图片存储到jpg的方法
2018/12/04 Python
python实时获取外部程序输出结果的方法
2019/01/12 Python
详解Django配置JWT认证方式
2020/05/09 Python
Python 高效编程技巧分享
2020/09/10 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
日本最大级玩偶手办购物:あみあみ Amiami
2018/04/23 全球购物
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
《孙权劝学》教学反思
2014/04/23 职场文书
任命书怎么写
2014/06/04 职场文书
委托证明书
2014/09/17 职场文书
2015年禁毒工作总结
2015/04/30 职场文书
小学入学感言
2015/08/01 职场文书