簡體   English   中英

如何使用來自 Kafka 的 Python 解碼/反序列化 Avro

[英]How to decode/deserialize Avro with Python from Kafka

我從遠程服務器 Kafka Avro 接收 Python 中的消息(使用 Confluent Kafka Python 庫的使用者),這些消息用帶有用戶代理、位置、url 等字段的 json 字典表示點擊流數據。這是一條消息的樣子:

b'\x01\x00\x00\xde\x9e\xa8\xd5\x8fW\xec\x9a\xa8\xd5\x8fW\x1axxx.xxx.xxx.xxx\x02:https://website.in/rooms/\x02Hhttps://website.in/wellness-spa/\x02\xaa\x14\x02\x9c\n\x02\xaa\x14\x02\xd0\x0b\x02V0:j3lcu1if:rTftGozmxSPo96dz1kGH2hvd0CREXmf2\x02V0:j3lj1xt7:YD4daqNRv_Vsea4wuFErpDaWeHu4tW7e\x02\x08null\x02\nnull0\x10pageview\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x10Thailand\x02\xa6\x80\xc4\x01\x02\x0eBangkok\x02\x8c\xba\xc4\x01\x020*\xa9\x13\xd0\x84+@\x02\xec\xc09#J\x1fY@\x02\x8a\x02Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/58.0.3029.96 Chrome/58.0.3029.96 Safari/537.36\x02\x10Chromium\x02\x10Chromium\x028Google Inc. and contributors\x02\x0eBrowser\x02\x1858.0.3029.96\x02"Personal computer\x02\nLinux\x02\x00\x02\x1cCanonical Ltd.'

如何解碼? 我嘗試了 bson 解碼,但該字符串未被識別為 UTF-8,因為我猜它是特定的 Avro 編碼。 我找到了https://github.com/verisign/python-confluent-schemaregistry但它只支持 Python 2.7。 理想情況下,我希望使用 Python 3.5+ 和 MongoDB 來處理數據並將其存儲為我當前的基礎架構。

我以為Avro庫只是讀取Avro文件,但它實際上解決了解碼Kafka消息的問題,如下:我首先導入庫並將schema文件作為參數,然后創建一個函數將消息解碼成字典,我可以在消費者循環中使用。

import io

from confluent_kafka import Consumer, KafkaError
from avro.io import DatumReader, BinaryDecoder
import avro.schema

schema = avro.schema.Parse(open("data_sources/EventRecord.avsc").read())
reader = DatumReader(schema)

def decode(msg_value):
    message_bytes = io.BytesIO(msg_value)
    decoder = BinaryDecoder(message_bytes)
    event_dict = reader.read(decoder)
    return event_dict

c = Consumer()
c.subscribe(topic)
running = True
while running:
    msg = c.poll()
    if not msg.error():
        msg_value = msg.value()
        event_dict = decode(msg_value)
        print(event_dict)
    elif msg.error().code() != KafkaError._PARTITION_EOF:
        print(msg.error())
        running = False

如果您使用 Confluent Schema Registry 並想要反序列化 avro 消息,只需將 message_bytes.seek(5) 添加到解碼函數中,因為 Confluent 在典型的 avro 格式數據之前添加了 5 個額外字節。

def decode(msg_value):
    message_bytes = io.BytesIO(msg_value)
    message_bytes.seek(5)
    decoder = BinaryDecoder(message_bytes)
    event_dict = reader.read(decoder)
    return event_dict

如果您有權訪問 Confluent 模式注冊服務器,您還可以使用 Confluent 自己的AvroDeserializer來避免弄亂他們神奇的 5 個字節:

from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.schema_registry.avro import AvroDeserializer

def process_record_confluent(record: bytes, src: SchemaRegistryClient, schema: str):
    deserializer = AvroDeserializer(schema_str=schema, schema_registry_client=src)
    return deserializer(record, None) # returns dict

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM