Сериализация с использованием протокольных буферов в базе данных без схемы - PullRequest
7 голосов
/ 25 ноября 2010

Мы используем MySQL для хранения данных без схемы (см .: Использование реляционной базы данных для данных без схемы для решения, основанного на том, как FriendFeed использует MySQL для хранения данных без схемы).

Одна большая таблица содержит все сущности для нашего приложения:

CREATE TABLE entities (
  added_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, id BINARY(16) NOT NULL
, body MEDIUMBLOB
, UNIQUE KEY (id)
) ENGINE=InnoDB ;

Несколько подробностей:

  • Единственное обязательное свойство хранимых сущностей - id, 16-байтовый UUID.Остальная часть объекта непрозрачна для базы данных.Мы можем изменить «схему», просто сохранив новые свойства в body.

  • Столбец added_id присутствует, поскольку InnoDB физически хранит строки данных в порядке первичного ключа.Первичный ключ AUTO_INCREMENT обеспечивает последовательную запись новых сущностей на диск после старых сущностей, что помогает обеспечить локальность чтения / записи (новые сущности читаются чаще, чем старые сущности).

  • Хранилища нашей базы данныхнаши данные без схемы в body. <- это тема этого вопроса. </em>

  • Множество других интересных деталей, таких как "попадание в" данные bodyсоздавать асинхронные материализованные представления (индексы - это просто таблицы, которые создаются в автономном режиме), но они не имеют отношения к текущему обсуждению ...

Как мы должны сериализоватьструктурированные данные (пары ключ-значение) в body?

JSON или BSON будут простыми, поскольку имена полей повторяются для каждой строки.Это дает ему преимущество в гибкости, но также и большой недостаток в эффективности использования пространства (накладные расходы на строку для имен полей в сериализованных данных).Мы пытаемся сохранить вещи в памяти, и здесь важно минимизировать как память, так и площадь сети.Чем больше записей мы сможем разместить в одном пространстве, тем быстрее будут выполняться наши запросы.Мы предпочитаем относительно длинные описательные имена полей, и сокращать их, чтобы ускорить мою базу данных, неправильно!

В конце концов, JSON / BSON не работает для наших целей, если мы не усложним и не сопоставим маленькие ключи с болееописательные ключи в драйвере приложения, который обращается к базе данных.Что заставило нас задуматься ...

Хотя наша база данных не имеет схемы, на самом деле: 1) существует не слишком много разных типов сущностей, 2) версии одного и того же вида сущностей меняются не часто,и 3) когда они меняются, обычно просто добавляют другое поле.JSON / BSON не имеют встроенной поддержки управления версиями.

Буферы протокола и Thrift гораздо сложнее, когда дело доходит до управления версиями и определениями данных.Как Thrift, так и Protocol Buffers являются отличными кандидатами для сериализации данных в базы данных, а Thrift спроектирован таким образом, что формат кодирования является расширяемым.

Protocol Buffers выглядят как отличный выбор для сериализации данных в базе данных без схемы.

CouchDB и MongoDB (две самые популярные базы данных без схем?) Используют JSON и BSON соответственно, но мы не можем найти что-нибудь об использовании чего-то более продвинутого, такого как буфер протокола, в качестве формата сериализации для храненияданные без схемы.Существуют продукты, в которых хранится версия объектов определенного языка (например, хранение объектов Externalizable в Java в сетке данных или выполнение NoSQL с MySQL в Ruby), но это проблема (попробуйте получить доступ к ним с других платформ или даже из самого MySQL,и забудьте о версиях).

Кто-нибудь хранит более совместимые буферы протокола в своей базе данных или какой-то другой расширенный формат сериализации в своей базе данных без схемы?Это вопрос о том, есть ли другие варианты, кроме прямой сериализации JSON / BSON / XML для каждой строки или сериализации объектов определенного языка.Это вообще возможно?Мы что-то упустили? извините за повествование в стиле потока сознания!

Ответы [ 4 ]

3 голосов
/ 30 ноября 2010

Как вы узнали, MongoDB и CouchDB имеют твердое мнение о том, как вы храните ваши данные. Если вы ищете подход, не зависящий от хранилища, вам нужно сделать что-то вроде того, что предлагает @Joshua, и взглянуть на Cassandra или HBase. Даже эти два хранилища данных имеют мнения о том, как следует хранить данные (оба они основаны на Google Bigtable ) и хранить данные в семействах столбцов .

Riak использует буферы протокола как один из способов сериализации данных из вашего приложения в хранилище данных. Возможно, стоит проверить, соответствует ли это вашим потребностям. Похоже, что вы в основном планируете выполнять поиск по одному ключу, поэтому Riak может стать серьезным конкурентом для вашего решения.

1 голос
/ 06 марта 2014

PostgreSQL теперь имеет тип JSON: http://www.postgresql.org/docs/9.3/static/datatype-json.html

Вы можете делать запросы, когда вы "достигаете" этих значений.

Преобразование Protobuf в JSON должно быть довольно простым.

1 голос
/ 25 ноября 2010

Возможно, вы захотите посмотреть что-то вроде Cassandra или HBase для хранения ваших данных. Проблема с непрозрачным большим двоичным объектом данных заключается в том, что вы не можете делать запросы на основе этого с вашей схемой MySQL здесь. Если вы ищете что-то, вам придется читать каждый блоб и проверять его. Если это действительно неважно, как вы выполняете поиск (т. Е. Вы всегда ключ), то я бы предложил использовать буферы протокола для сериализации данных, возможно, сжатия с помощью zlib или LZO.

Буферы протокола позволяют вам создать простую структуру данных, которая может принимать дополнительные поля по мере развития ваших данных. Имена полей хранятся в виде чисел, а код для работы со структурами генерируется автоматически из вашего файла .proto. Производительность хорошая, а размеры данных довольно малы. При желании вы можете сжимать данные, используя MySQL compress () или одну из библиотек сжатия в реальном времени, приведенных здесь (не только Java):

Быстрое сжатие в Java?

Надеюсь, это поможет.

0 голосов
/ 30 ноября 2010

Я отсылаю вас к ответу, который я выдвинул несколько месяцев назад на подобную тему.Мы используем MySQL и пользовательский текстовый формат, который оказался быстрее, чем форматы XML или JSON:

С какими проблемами масштабирования вы столкнулись при использовании хранилища данных NoSQL?

Хорошо работает длянас.Хотя я не пробовал буферы протокола.

...