python消费kafka数据批量插入到es的方法


Posted in Python onDecember 27, 2018

1、es的批量插入

这是为了方便后期配置的更改,把配置信息放在logging.conf中

用elasticsearch来实现批量操作,先安装依赖包,sudo pip install Elasticsearch2

from elasticsearch import Elasticsearch 
class ImportEsData:

  logging.config.fileConfig("logging.conf")
  logger = logging.getLogger("msg")

  def __init__(self,hosts,index,type):
    self.es = Elasticsearch(hosts=hosts.strip(',').split(','), timeout=5000)
    self.index = index
    self.type = type


  def set_date(self,data): 
    # 批量处理 
    # es.index(index="test-index",doc_type="test-type",id=42,body={"any":"data","timestamp":datetime.now()})
    self.es.index(index=self.index,doc_type=self.index,body=data)

2、使用pykafka消费kafka

1.因为kafka是0.8,pykafka不支持zk,只能用get_simple_consumer来实现

2.为了实现多个应用同时消费而且不重消费,所以一个应用消费一个partition

3. 为是确保消费数据量在不满足10000这个批量值,能在一个时间范围内插入到es中,这里设置consumer_timeout_ms一个超时等待时间,退出等待消费阻塞。

4.退出等待消费阻塞后导致无法再消费数据,因此在获取self.consumer 的外层加入了while True 一个死循环

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from pykafka import KafkaClient
import logging
import logging.config
from ConfigUtil import ConfigUtil
import datetime


class KafkaPython:
  logging.config.fileConfig("logging.conf")
  logger = logging.getLogger("msg")
  logger_data = logging.getLogger("data")

  def __init__(self):
    self.server = ConfigUtil().get("kafka","kafka_server")
    self.topic = ConfigUtil().get("kafka","topic")
    self.group = ConfigUtil().get("kafka","group")
    self.partition_id = int(ConfigUtil().get("kafka","partition"))
    self.consumer_timeout_ms = int(ConfigUtil().get("kafka","consumer_timeout_ms"))
    self.consumer = None
    self.hosts = ConfigUtil().get("es","hosts")
    self.index_name = ConfigUtil().get("es","index_name")
    self.type_name = ConfigUtil().get("es","type_name")


  def getConnect(self):
    client = KafkaClient(self.server)
    topic = client.topics[self.topic]
    p = topic.partitions
    ps={p.get(self.partition_id)}

    self.consumer = topic.get_simple_consumer(
      consumer_group=self.group,
      auto_commit_enable=True,
      consumer_timeout_ms=self.consumer_timeout_ms,
      # num_consumer_fetchers=1,
      # consumer_id='test1',
      partitions=ps
      )
    self.starttime = datetime.datetime.now()


  def beginConsumer(self):
    print("beginConsumer kafka-python")
    imprtEsData = ImportEsData(self.hosts,self.index_name,self.type_name)
    #创建ACTIONS 
    count = 0
    ACTIONS = [] 

    while True:
      endtime = datetime.datetime.now()
      print (endtime - self.starttime).seconds
      for message in self.consumer:
        if message is not None:
          try:
            count = count + 1
            # print(str(message.partition.id)+","+str(message.offset)+","+str(count))
            # self.logger.info(str(message.partition.id)+","+str(message.offset)+","+str(count))
            action = { 
              "_index": self.index_name, 
              "_type": self.type_name, 
              "_source": message.value
            }
            ACTIONS.append(action)
            if len(ACTIONS) >= 10000:
              imprtEsData.set_date(ACTIONS)
              ACTIONS = []
              self.consumer.commit_offsets()
              endtime = datetime.datetime.now()
              print (endtime - self.starttime).seconds
              #break
          except (Exception) as e:
            # self.consumer.commit_offsets()
            print(e)
            self.logger.error(e)
            self.logger.error(str(message.partition.id)+","+str(message.offset)+","+message.value+"\n")
            # self.logger_data.error(message.value+"\n")
          # self.consumer.commit_offsets()


      if len(ACTIONS) > 0:
        self.logger.info("等待时间超过,consumer_timeout_ms,把集合数据插入es")
        imprtEsData.set_date(ACTIONS)
        ACTIONS = []
        self.consumer.commit_offsets()




  def disConnect(self):
    self.consumer.close()


from elasticsearch import Elasticsearch 
from elasticsearch.helpers import bulk
class ImportEsData:

  logging.config.fileConfig("logging.conf")
  logger = logging.getLogger("msg")

  def __init__(self,hosts,index,type):
    self.es = Elasticsearch(hosts=hosts.strip(',').split(','), timeout=5000)
    self.index = index
    self.type = type


  def set_date(self,data): 
    # 批量处理 
    success = bulk(self.es, data, index=self.index, raise_on_error=True) 
    self.logger.info(success)

3、运行

if __name__ == '__main__':
  kp = KafkaPython()
  kp.getConnect()
  kp.beginConsumer()
  # kp.disConnect()

注:简单的写了一个从kafka中读取数据到一个list里,当数据达到一个阈值时,在批量插入到 es的插件

现在还在批量的压测中。。。

以上这篇python消费kafka数据批量插入到es的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
从零学Python之入门(二)基本数据类型
May 25 Python
深入理解python函数递归和生成器
Jun 06 Python
基于Python实现对PDF文件的OCR识别
Aug 05 Python
Python简单实现控制电脑的方法
Jan 22 Python
python实现自动发送报警监控邮件
Jun 21 Python
python 2.7 检测一个网页是否能正常访问的方法
Dec 26 Python
Django之创建引擎索引报错及解决详解
Jul 17 Python
python3中eval函数用法使用简介
Aug 02 Python
用django设置session过期时间的方法解析
Aug 05 Python
PIL对上传到Django的图片进行处理并保存的实例
Aug 07 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
Jun 04 Python
Python 抓取数据存储到Redis中的操作
Jul 16 Python
Python通过paramiko远程下载Linux服务器上的文件实例
Dec 27 #Python
Python基于Tkinter模块实现的弹球小游戏
Dec 27 #Python
python 读取Linux服务器上的文件方法
Dec 27 #Python
Python 脚本获取ES 存储容量的实例
Dec 27 #Python
Python数据结构之栈、队列及二叉树定义与用法浅析
Dec 27 #Python
python获取本机所有IP地址的方法
Dec 26 #Python
python检测IP地址变化并触发事件
Dec 26 #Python
You might like
解析PHP的session过期设置
2013/06/29 PHP
详解php的socket通信
2015/08/11 PHP
WordPress中制作导航菜单的PHP核心方法讲解
2015/12/11 PHP
Zend Framework校验器Zend_Validate用法详解
2016/12/09 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
TP3.2框架分页相关实现方法分析
2020/06/03 PHP
基于jquery & json的省市区联动代码
2012/06/26 Javascript
Jquery实现图片放大镜效果的思路及代码(自写)
2013/10/18 Javascript
angularJS 中input示例分享
2015/02/09 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
Select下拉框模糊查询功能实现代码
2016/07/22 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
2016/12/31 Javascript
nodejs实例解析(输出hello world)
2017/01/03 NodeJs
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
javascript 的变量、作用域和内存问题
2017/04/19 Javascript
js实现放大镜特效
2017/05/18 Javascript
Layui 设置select下拉框自动选中某项的方法
2018/08/14 Javascript
axios 封装上传文件的请求方法
2018/09/26 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
2019/02/22 Javascript
使用vue开发移动端管理后台的注意事项
2019/03/07 Javascript
js实现3D照片墙效果
2019/10/28 Javascript
JavaScript如何操作css
2020/10/24 Javascript
[59:08]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第一局
2016/02/27 DOTA
Python使用python-docx读写word文档
2019/08/26 Python
基于python2.7实现图形密码生成器的实例代码
2019/11/05 Python
VSCode中自动为Python文件添加头部注释
2019/11/14 Python
python DES加密与解密及hex输出和bs64格式输出的实现代码
2020/04/13 Python
python 实现 hive中类似 lateral view explode的功能示例
2020/05/18 Python
意大利独特而优质的家居用品:Fazzini
2018/12/05 全球购物
Vrbo英国:预订度假屋
2020/08/19 全球购物
新闻发布会活动策划方案
2014/09/15 职场文书
公司向个人借款协议书范本
2014/10/09 职场文书
关于分班的感言
2015/08/04 职场文书
年中了,该如何写好个人述职报告?
2019/07/02 职场文书
Java 垃圾回收超详细讲解记忆集和卡表
2022/04/08 Java/Android