Сравнение форматов и библиотек сериализации / Антон...

67
Сравнение форматов и библиотек сериализации Антон Рыжов, Qrator Labs

Transcript of Сравнение форматов и библиотек сериализации / Антон...

Page 1: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Сравнение форматов и библиотек сериализацииАнтон Рыжов, Qrator Labs

Page 2: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Задача

Сериализовать данные:● Без потерь● Компактно● Быстро● Удобно

Page 3: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON

✔ Привычно

✔ Удобно

✔ Человекочитаемо

[

  {

    "very": "simple"

  }

]

Page 4: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON

✔ Привычно

✔ Удобно

✔ Человекочитаемо

✗ Не компактно

[

  {

    "very": "simple"

  },

  {

    "very": "big"

  }

]

Page 5: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

7              1 byte (1:1)→

Page 6: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

7              1 byte (1:1)→

65535          5 bytes (5:2)→

1000 000 000   10 bytes (10:4)→

Page 7: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

3 / 2   1.5 (3 byte)→

Page 8: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

3 / 2   1.5 (3 byte)→

1 / 3   0.3333333333333333 (18 bytes)→

Page 9: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

Hello   "Hello" (+2 bytes)→

Page 10: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

Hello   "Hello" (+2 bytes)→

     "\u0420\u0418\u0422" (×3)РИТ →

Page 11: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

Hello   "Hello" (+2 bytes)→

     "\u0420\u0418\u0422" (×3)РИТ →

     " " ( )РИТ → РИТ опция

Page 12: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

[

  {"userId": 1, "userName": "John Smith"},

  {"userId": 2, "userName": "Jane Dow"}

]

Page 13: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

[

  {"userId": 1, "userName": "John Smith"},

  {"userId": 2, "userName": "Jane Dow"}

]

Page 14: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — компактность

[

  "keys": ["userId", "userName"],

  "values": [

    [1, "John Smith"],

    [2, "Jane Dow"]

  ]

]

Page 15: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — целостность

dict(1: "foo")   { "1": "foo" }→

Page 16: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — целостность

dict(1: "foo")   { "1": "foo" }→

object = { "type_id": 5 }

types = { "5": "Type name" }

Page 17: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — целостность

Python   JSON:→{ 1: "foo", "1": "bar" }   ?→

PHP   JSON:→

Array(1=> "foo", "1"=> "bar")   ?→

Page 18: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — целостность

Python   JSON:→{ 1: "foo", "1": "bar" }   {"1": "bar", "1": "foo"}→

PHP   JSON:→

Array(1=> "foo", "1"=> "bar")   {"1": "bar"}→

Page 19: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — целостность

Python   JSON:→{ 1: "foo", "1": "bar" }   {"1": "bar", "1": "foo"}→

PHP   → PHP:

Array(1=> "foo", "1"=> "bar")   → Array(1=> "bar")

Page 20: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — binary

{"message": "0KDQmNCiKys="}  +30%

Page 21: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

JSON — binary

{"message": "0KDQmNCiKys="}  +30%

{"message_bin": "0KDQmNCiKys="}

{"message": { "type": "bin", "value": "0KDQmNCiKys="}}

Page 22: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Альтернативы

Схема данных Binary Ключи map

BSON ✗ ✓ str

Msgpack ✗ ✓ any

Google Protobuf ✓ ✓ ✗Apache Thrift ✓ ✓ any

Apache Avro ✓ ✓ str

Page 23: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

Page 24: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

✔Уменьшает дублирование

Page 25: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

✔Уменьшает дублирование

✔Валидирует данные

Page 26: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

✔Уменьшает дублирование

✔Валидирует данные

✔Приводит типы

Page 27: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

✔Уменьшает дублирование

✔Валидирует данные

✔Приводит типы

✗ Надо писать

Page 28: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Зачем схема?

✔Описывает данные

✔Уменьшает дублирование

✔Валидирует данные

✔Приводит типы

✗ Надо писать

✗ … а иногда ещё и компилировать

Page 29: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf

✔ Старое проверенное решение

✔ Разработан Google

✔ Хорошие результаты в тестах в интернете

✔ Хорошая документация

Page 30: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf

✔ Старое проверенное решение

✔ Разработан Google

✔ Хорошие результаты в тестах в интернете

✔ Хорошая документация

✗ Не всё можно описать– Список списков, map

Page 31: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf — схема

message Point {

  required int32 x = 1;

  required int32 y = 2;

}

message PointsList {

  repeated Point points = 1;

}

Page 32: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Thrift

● Более новый формат● Разработал Facebook, отдал в Apache● Документация — справочник типов и BNF● Есть “Thrift: The Missing Guide”● RPC-клиент/сервер

Page 33: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Thrift — схема

struct PointsList {

    1: required list< list<i32> > points,

}

Page 34: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Apache Avro

● Ещё более новый формат● Разработан для Apache Hadoop● Документация на схему — подробная● Кодогенерации нет

Page 35: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Avro — схема

{

    "namespace": "test.avro",

    "type": "array",

    "items": {

        "type": "array",

        "items": "int"

    }

}

Page 36: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер integer: «0»; 1-, 2-, 4-byte

Msgpack

Avro

Protobuf

JSON

Thrift

BSON*

0 2 4 6 8 10 12

Page 37: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер float: «0», 2.5, 1/3, 1e9/3

Avro

Protobuf

Msgpack

Thrift

BSON*

JSON

0 2 4 6 8 10 12 14 16 18 20

Page 38: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер string: "", "Z"×10, "Я"×10

Msgpack

Avro

Protobuf

JSON

Thrift

BSON*

0 5 10 15 20 25 30 35

Page 39: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер string: "Z"×1000, "Я"×1000

Msgpack

Avro

Protobuf

Thrift

BSON*

JSON

0 500 1000 1500 2000 2500

Page 40: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер 0, 10 bytes

Avro

Msgpack

Protobuf

Thrift

JSON

BSON*

0 5 10 15 20 25

Page 41: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер 1000 bytes

Avro

Msgpack

Protobuf

Thrift

BSON*

JSON

0 200 400 600 800 1000 1200 1400 1600

Page 42: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер array [0], [10]

Avro

Msgpack

Protobuf

JSON

Thrift

BSON*

0 5 10 15 20 25

Page 43: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер map [0], [10]

Msgpack

Avro

Protobuf*

JSON

BSON

Thrift

0 2 4 6 8 10 12 14 16 18 20

Page 44: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Размер struct vs map

Msgpack

Avro

Protobuf*

BSON

JSON

Thrift

0 20 40 60 80 100 120 140 160 180 200

Page 45: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Топ по размеру

1.Apache Avro

2.Msgpack

3.Google Protobuf

4.Apache Thrift

5.JSON

6.BSON

Page 46: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Методика бенчмарка

Характерные объекты — строки, байты, словари разных размеров, массивы

Замер времени на сериализацию и десериализацию каждой библиотекой в python2 и python3

Сравнение данных до и после

Железо:

Intel(R) Xeon(R) CPU E5-2683 v4 @ 2.10GHz

64 Gb RAM

Page 47: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Без схемы

Поддержка Установка Реализация Генерация кода

uJSON 2, 3 pip C-ext ✗BSON 2, 3 pip Python ✗

Msgpack 2, 3 pip C-ext ✗

Page 48: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Без схемы — затраченное время

msgpack

ujson

json

bson

encode py2.7

decode py2.7

encode py3.5

decode py3.5

Page 49: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf

Поддержка Установка Реализация Генерация кодаprotobuf 2, 2to3 make + pip Python ✓cprotobuf 3 protobuf + pip C-ext ✓protobuf3 3 protobuf + pip Python ✓

Page 50: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf — пример кода protobuf, cprotobuf

data = test_pb2.PointsList(

    points=[

        test_pb2.Point(x=1, y=2),

        test_pb2.Point(x=3, y=4),

    ]

).SerializeToString()

pl = test_pb2.PointsList()

pl.ParseFromString(data)

print(pl.points[0].x)

Page 51: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf — пример для protobuf3

pl = test_pb2.PointsList()

po = test_pb2.Point()

po.x = 1; po.y = 2

pl.points.append(po)

data = pl.encode_to_bytes()

pl = test_pb2.PointsList()

pl.parse_from_bytes(data)

print(pl.points[0].x)

Page 52: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Protobuf — затраченное время

cprotobuf*

google_proto

protobuf3*

encode py2.7

decode py2.7

encode py3.5

decode py3.5

Page 53: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Thrift

Поддержка Установка Реализация Генерация кода

(apache) thrift

2 make + pip Python ✓(facebook)

Thrift2, 3 ☠nightmare☠ Python ✓

thriftpy 2, 3 pip Cython ✗thriftrw 2, 3 pip Cython ✗

Page 54: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

(Apache) thrift — пример кода

data = serialize(

    test_ttypes.PointsList([(1, 2)])

)

points = deserialize(

    test_ttypes.PointsList(),

    points_list,

).points

print(points[0][0])

Page 55: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

(facebook)Thrift, thriftpy, thriftrw

Совместим с (Apache) thrift по API

Page 56: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Thrift — затраченное время

thriftrw

fb_thrift**

apache_thrift*

thriftpy+cython*

thriftpy*

Py2.7 Py3.5

Page 57: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Thrift — затраченное время

thriftrw

fb_thrift**

apache_thrift*

thriftpy+cython*

thriftpy*

encode py2.7

decode py2.7

encode py3.5

decode py3.5

Page 58: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Avro

Поддержка Установка Реализация Генерация кода(apache)

avro2, 3

2 pip3 src

Python ✗fastavro 2, 3 pip Cython ✗pyavroc 2, 3 shell + make libavro + wrapper ✗

Page 59: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

(Apache) avro — пример упаковки

schema = avro.schema.parse(open('points_list.avsc', 'r').read())

io_stream = io.BytesIO()

avro.io.DatumWriter(schema).write(

    [(1, 2), (3, 4)],

    avro.io.BinaryEncoder(io_stream),

)

data = io_stream.getvalue()

Page 60: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

(Apache) avro — пример распаковки

schema = avro.schema.parse(open('points_list.avsc', 'r').read())

io_stream = io.BytesIO(data)

points = avro.io.DatumReader(schema).read(

    avro.io.BinaryDecoder(io_stream),

)

print(points[0][0])

Page 61: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

fastavro — пример упаковки

schema = json.loads(open('points_list.avsc', 'r').read())

io_stream = io.BytesIO()

fastavro.schemaless_writer(

    io_stream,

    schema,

    [(1, 2), (3, 4)],

)

return io_stream.getvalue()

Page 62: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

fastavro — пример распаковки

schema = json.loads(open('points_list.avsc', 'r').read())

io_stream = io.BytesIO(points_list)

points = fastavro.schemaless_reader(

    io_stream,

    schema,

)

print(points[0][0])

Page 63: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

pyavroc — пример кода

schema = open('specs/points_list.avsc', 'r').read()

points_writer = _pyavroc.AvroSerializer(schema)

data = points_writer.serialize(

    [(1, 2), (3, 4)],

)

points_reader = _pyavroc.AvroDeserializer(schema)

points = points_reader.deserialize(data)

print(points[0][0])

Page 64: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Avro — затраченное время

pyavroc*

fastavro

avro

encode py2.7

decode py2.7

encode py3.5

decode py3.5

Page 65: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Топ — затраченное время

pyavroc*

msgpack

cprotobuf*

thriftrw

ujson

fastavro

thriftpy+cython*

Py2.7 Py3.5

Page 66: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Общие рекомендации

● Следить за новыми разработками● Рассматривать альтернативы● Референсная библиотека — не всегда самая лучшая● Альтернативные — бывают ещё хуже● Не верить бенчмаркам в интернете (В том числе

этому)● Кодогенерация только мешает

Page 67: Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)

Всё

[email protected]://github.com/QratorLabs/ritfest2016