Значительно низкая производительность Apache Avro в Python, разные результаты при кодировании сообщений и файлов

Итак, следуя ответу здесь: закодировать объект с помощью Avro в байтовый массив в Python. Я могу отправлять сообщения через ZeroMQ, но производительность крайне низкая.

Этого следует ожидать, так как реализация Avro Python - это чистый Python, и мы видим аналогичные комментарии по производительности от автора (ов) FastAvro. AFAIK, FastAvro нельзя использовать для генерации сообщения для использования с очередью сообщений, он предназначен для записи в файлы.

Итак, вернемся к ссылке выше, мне любопытно узнать, не является ли этот метод более сложным, чем он должен быть на самом деле - кажется странным, что Avro DatumWriter не может быть изначально использован для создания чего-то подходящего для обмена сообщениями.

Это приводит меня к моей последней точке (и причина моего подозрения). Когда я использую стандартный пример из примера " Приступая к работе с Avro (Python)", я могу транслировать один из моих двоичных файлов в файл.avro, и он занимает около 5,8 МБ. Когда я использовал метод сообщения для его кодирования в виде байтового массива, общий размер сообщения составлял 11 МБ. Почему существует такое огромное расхождение между этими методами? Предположительно они были бы очень похожи...

Обратите внимание, что я удалил кодек deflate из примера писателя, чтобы убедиться, что это сравнение яблок с яблоками. Когда включен deflate, размер составляет всего 2,8 МБ.

1 ответ

Решение

Я не уверен, как вы отправляете сообщения, но вы должны быть в состоянии получить fastavro работать. Например, поскольку он может сериализоваться в любой файлоподобный объект, вы можете получить байты напрямую:

from fastavro import dump
from io import BytesIO

# A sample schema.
schema = {
  'name': 'Person',
  'type': 'record',
  'fields': [
    {'name': 'name', 'type': 'string'},
    {'name': 'age', 'type': 'int'}
  ]
}

record = {'name': 'Ann', 'age': 23} # Corresponding record.
buf = BytesIO() # Target buffer (any file-like object would work here).
dump(buf, record, schema) # Serialize record into buffer.
message = buf.getvalue() # The raw bytes of your message.

Если вы хотите проверить, что это работает:

from fastavro import load

buf.seek(0)
print load(buf, schema) # {'age': 23, 'name': 'Ann'}

Если в ваших сообщениях есть верхние и нижние колонтитулы и т. Д., Вы просто напишите их buf по мере необходимости.

Наконец, по поводу несоответствия размеров, я подозреваю, что включается куча избыточной информации (может быть, схема?).

Другие вопросы по тегам