Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Kafka消费者解压gz文件流并读取_Python_Apache Kafka_Gzip_Kafka Consumer Api - Fatal编程技术网

Python Kafka消费者解压gz文件流并读取

Python Kafka消费者解压gz文件流并读取,python,apache-kafka,gzip,kafka-consumer-api,Python,Apache Kafka,Gzip,Kafka Consumer Api,Kafka producer正在发送.gz文件,但无法在使用者端解压缩和读取文件。获取错误为“IOError:不是gzip文件” 制作人- bin/kafka-console-producer.sh--代理列表localhost:9092--主题机场

Kafka producer正在发送.gz文件,但无法在使用者端解压缩和读取文件。获取错误为“IOError:不是gzip文件”

制作人- bin/kafka-console-producer.sh--代理列表localhost:9092--主题机场<~/Downloads/stocks.json.gz

消费者-

import sys 
import gzip
import StringIO
from kafka import KafkaConsumer

consumer = KafkaConsumer(KAFKA_TOPIC, bootstrap_servers=KAFKA_BROKERS)

try:
    for message in consumer:
        f = StringIO.StringIO(message.value)
        gzip_f = gzip.GzipFile(fileobj=f)
        unzipped_content = gzip_f.read()
        content = unzipped_content.decode('utf8')
        print (content)
except KeyboardInterrupt:
    sys.exit()
消费者错误-

Traceback (most recent call last):
  File "consumer.py", line 18, in <module>
    unzipped_content = gzip_f.read()
  File "/usr/lib64/python2.6/gzip.py", line 212, in read
    self._read(readsize)
  File "/usr/lib64/python2.6/gzip.py", line 255, in _read
    self._read_gzip_header()
  File "/usr/lib64/python2.6/gzip.py", line 156, in _read_gzip_header
    raise IOError, 'Not a gzipped file'
IOError: Not a gzipped file
回溯(最近一次呼叫最后一次):
文件“consumer.py”,第18行,在
解压内容=gzip\u f.read()
文件“/usr/lib64/python2.6/gzip.py”,第212行,已读
自读(readsize)
文件“/usr/lib64/python2.6/gzip.py”,第255行,已读
self._read_gzip_header()
文件“/usr/lib64/python2.6/gzip.py”,第156行,在读取头中
引发IOError,“不是gzip文件”
IOError:不是gzip文件

卡夫卡不是用来发送大量有效载荷/信息的。您应该将其视为分布式消息总线,它为您提供分布式系统的所有特权

卡夫卡限制了可以发送的消息的大小,原因如下

  • 巨大的消息会增加代理中的内存压力
  • 大型消息会减慢代理的速度,并且处理它们的成本非常高
解决方案:

  • 您可以很好地使用基于引用的消息传递,将大量消息的位置发送给消费者,而不是按原样发送大量数据。这将允许您使用外部数据存储的功能,还可以减轻卡夫卡代理的压力
  • 您还可以将数据分块并将其内联发送,然后在接收器处重新组装
使用批量大小:

batch.size
以字节总数而不是消息数度量批大小。它控制向Kafka代理发送消息之前要收集的数据字节数。在不超过可用内存的情况下,将其设置为尽可能高的值。默认值为16384

如果增加缓冲区的大小,它可能永远不会满。生产者最终根据其他触发器发送信息,例如以毫秒为单位的延迟时间。虽然您可以通过将缓冲区批大小设置得过高来降低内存使用,但这不会影响延迟

如果您的制作人一直在发送,您可能会获得最佳吞吐量。如果生产者经常处于空闲状态,您可能没有写入足够的数据来保证当前的资源分配

由于您的数据是
gzip
,因此您可以使用
基于引用的消息传递


不要使用fetch size和message max byte size(无法覆盖所有文件大小),而是将文件存储在诸如NFS/HDFS/S3之类的分布式文件系统上,并将引用发送给使用者。使用者可以选择位置并解压缩数据。

控制台生产者不是为输入文件中的每一行创建消息吗?您确定这适用于您的gzip文件吗?你能检查一下这个主题产生了多少条消息吗?如果我们用print(message)而不是gzip.gzip文件(fileobj=f),我们会得到输出——ConsumerRecord(主题=u'Airport',分区=0,偏移量=961956,时间戳=1525798407789,时间戳类型=0,键=None,值='\x1f\xef\xbf\xbd\x08\x08)\XF\XF\\XF\\\XF\\XXF\XF\XF\XF\XF\XXF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XB\XB\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\XF\\XF\\XF\XF\XF\XF\XF\\XF\\XF\\XF\\\\XF\\\XF\XF\XF\XF\\\XB\\XF\XF\XF\XF\XF size=-1,序列化的_值_size=81),因此只有81个字节。您的文件更大,不是吗?每个输入行都有不同大小的消息值。需要解压缩该值。感谢您的帮助。配置中的获取大小(以字节为单位)是多少?因为这里的文件名为
stocks.json.gz
,我假设它也可以以非常简单的方式拆分为多条消息(每个股票或交易日一条)。当然,消费者需要知道预期结果。@Thilo我无法对此发表评论,因为OP没有向我们提供任何关于数据模型或JSON外观的信息。只是进一步阐述了您的观点:“您还可以将数据分块并以内联方式发送,然后在接收器处重新组装”这看起来非常可行,甚至可能产生本身就有意义的块。但是卡夫卡不会保留顺序,除非你有一个分区。如果使用单分区,则会失去分布式消息传递语义。@PhaniKumarYadavilli,试图在运行中保存传入的.gz文件,我们得到了与头相关的错误。我尝试过将传入的数据分块解压缩,但没有成功。基于引用的消息很好,但我不能在我的情况下使用。