[О блоге]
[наверх]
[пред]
[2017-11-16 22:14:57+03:00]
[55935d7c520287c6127014e305f62d52eac4610b]
Форматы кодирования данных
В рассылке http://www.metzdowd.com/pipermail/cryptography/2017-November/033025.html
и на работе уже не первый день поднята тема про вообще форматы
кодирования данных. Имеется в виду для отправки по сети между
гетерогенными системами.
Всяких Protocol Buffers, Apache Thrift, MsgPack и прочего -- уйма.
Огромная уйма. Но я уже, видимо старею, но склоняюсь к тому чтобы
использовать семейство возможно чуть ли не самых старых форматов:
ASN.1 либо XDR.
Вот просто по сути своей чем тот же Protocol Buffer отличается от ASN.1
BER? Или MsgPack от BER? Да ничем. Всё это TLV! Одно но: в ASN.1 куча
всяких типов данных которые можно и не реализовывать. Но, в отличии от
многих, в нём есть DATETIME, так необходимый чуть ли не постоянно и
всегда на практике.
Да, ASN.1 BER можно было бы упростить в плане кодирования -- получим
BSON или MsgPack (если без схемы) или Protobuf (если с ней). Но так ли
это должно терзать и мучать людей? Сложность это конечно плохо, но
всё-равно регулярно все безропотно используют XML или JSON. Будь
возможность заменяют на что-то другое, попроще, но ё моё, не каждый же
раз в каждой компании и каждом стартапе писать очередной сериализатор?
liblber из состава OpenLDAP, говорят, может много гигабит спокойно
просасывать. Так что вопрос скорости тут уже не так важен. BER далеко не
самый компактный -- ok, берём ASN.1 PER. Да, сложен, даже сейчас мало
FOSS библиотек для работы с ним. Но я на полном серьёзе склоняюсь к тому
что надо бы взять и допилить или написать! PER ОЧЕНЬ компактен. Если так
волнует трафик -- нефига изобретать велосипед. PER вовсю например во
всей сотовой связи используется -- именно в нём между сотовым и станцией
передаются сообщения, так как там ёмкость канала важно экономить. Есть
aligned PER, где выравнивание произойдёт по байтам -- будет менее
эффективен чем unaligned вариант, зато на обычных
процессорах/компьютерах куда удобнее обрабатывать будет. Есть canonical
вариант PER -- можно будет применять в криптографии.
Недостаток BER в том, что одно и то же представление можно получиться
разными способами и поэтому там где происходит аутентификация или
подпись -- его не поиспользуешь. Для этого есть DER. DER это
подмножество BER -- BER его всегда сможет прочитать. Но он создаёт
другую фигню: его нельзя потоково передавать и обрабатывать. Для решения
этой проблемы есть CER -- почти ничем не отличается от DER, но позволяет
потоково обрабатывать данные. Имея в руках BER кодек, можно легко
сделать и DER и CER из него. PER значительно сложнее, но в компактности
с ним не потягаешься.
Но кроме ASN.1 я однозначно ещё считаю что стоит смотреть в сторону XDR.
Изобретён аж тоже в 80-х Sun Microsystems и почти во всём что они делают
используется этот формат (а также автоматом у всех в NFS и ZFS). Его
главное отличие, как мне кажется, это простота! Реализовать BER -- не
один день работы. А XDR -- пару часов. Выравнивание по четыре байтам,
говорят, ОЧЕНЬ помогает с обработкой данных на 32-бит и старше
процессорах. Очень просто и очень эффективно. Просасывать фигову тучу
гигабит на нём не проблема. Реализовать -- любой сможет с нуля. И лично
я в своих проектах (например NNCP) использую именно его.
Но всё-равно у XDR есть недостатки: нельзя потоково обрабатывать (длину
и количество элементов нужно знать сразу же при посылке), нельзя
передавать большие integer-ы (хотя конечно может быть кто-то и никогда в
жизни не столкнётся с такой задачей) и максимальный объём бинарного
блоба или количества элементов в массиве может быть только 2^32. То
есть, на практике большие файлы просто так одним куском не всегда можно
будет засунуть и придётся городить сверху этого ещё что-то.
Но BER, DER/CER, PER, XDR требуют схемы. Чтобы без схемы жить, то лично
я поклонник bencode. Один экран кода на Python -- вся его реализация.
Типов данных мало. Кодировать списки можно потоково -- остальные
элементы потоково нельзя. Но декодировать можно всё в потоке. Не самый
компактный, но и не жирный, как JSON. Но, что мне очень нравится, так
это то, что у него каноническое представление -- применим в
криптографии! Ну и, в отличии от JSON, в нём можно передавать бинарные
данные.
Есть вот например MsgPack или CBOR или BSON. Ну обычные yet another TLV
кодеки. Да, попроще чем ASN.1, но из-за этого городить таакой зоопарк?
У Google действительно есть объективные причины писать Protobuf или
Cap'n'proto, но Google один и у него свои условия эксплуатации. Это
очередная статья из серии "вы не Google -- не надо делать как Google,
потому-что они так делают". Если они используют сложный распределённый
map-reduce это не значит что для обработки отчётов вам тоже самое надо
делать. 99% подойдёт и просто обычный PostgreSQL какой-нибудь, с набором
скриптов обсчитывальщиков. Если Netflix-ы пилят свои sendfile примитивы,
внедряются в драйвера сетевых карт чтобы сделать DMA доступ, настраивают
хитро прерывания и CPU affinity для сетевых процессов это не значит что
не сделав этого у вас будет всё плохо. Так же как если у вас нет
zero-copy сериализации данных, то возможно вы никогда в жизни на своих
проектах в сериализацию и не упрётесь.
[оставить комментарий]