Переизобретаем сжатие в распределенной базе данных

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет, Хабр!

Меня зовут Антон Виноградов, я Java developer в СберТехе, работаю в команде Platform V DataGrid — распределенной базы данных, основанной на Apache Ignite. Я реализовал альтернативный «ванильному» вариант сжатия данных в нашем продукте и хочу рассказать, какие особенности позволили превзойти оригинал.

В начале 2020 года мои коллеги уже рассказывали, как и зачем было организовано сжатие данных в Apache Ignite.

Сжатие данных в Apache Ignite

Кратко напомню, как мы сжимали данные раньше:

Сжимаем страницы в хранилище на диске (кратно блоку файловой системы) и в WAL; не сжимаем страницы в памяти, дельты и логические записи в WAL.
Сжимаем страницы в хранилище на диске (кратно блоку файловой системы) и в WAL; не сжимаем страницы в памяти, дельты и логические записи в WAL.

Cжатие данных производилось только на диске.

Специально увеличенные в размере страницы, занимающие несколько блоков файловой системы, например, размером в 16 Кб (4 x 4 Кб), при записи в хранилище сжимались до меньшего числа блоков файловой системы, например, до 12 Кб, 8 Кб или даже 4 Кб. Это происходило за счет использования файловых систем с разреженными файлами. При этом постраничная индексация прекрасно продолжала работать за счет того, что с точки зрения приложения страницы не изменяли свой размер.

Помимо этого, страницы сжимались и при записи в WAL, но уже без соблюдения кратности по отношению к блоку файловой системы, например, с 16 Кб до 5 Кб.

Однаĸо в WAL по-прежнему записывались:

  • несжатые дельты страниц (Δ), которые записываются вместо полной страницы при повторной записи в одну и ту же страницу в рамках одного чекпоинта;

  • несжатые логические записи (op), требующиеся для восстановления консистентности распределенной базы данных.

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

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

В противоположность описанному варианту мы придумали сжимать отдельные записи в памяти:

Сжимаем записи в памяти
Сжимаем записи в памяти

В результате на страницах помещается больше данных:

Используем освободившееся в странице место для хранения дополнительных данных
Используем освободившееся в странице место для хранения дополнительных данных

Записываем на диск меньшее число страниц:

На диск (хранилище, WAL) и в сеть попадают уже сжатые данные
На диск (хранилище, WAL) и в сеть попадают уже сжатые данные

В итоге и в памяти, и на диске храним больше данных, а в WAL пишем заметно меньше:

Нажми, чтобы сравнить с тем как было раньше

Сжимаем данные в хранилище (память, диск) и в WAL (физические, логические записи и дельты)
Сжимаем данные в хранилище (память, диск) и в WAL (физические, логические записи и дельты)
  • Страницы в WAL продолжают сжиматься, как и в первом описанном варианте, но сжимаются не с 16 Кб до 5Кб, а с 4 Кб до 2 КБ; записать 2 Кб — значительно быстрее, чем 5 Кб.

  • Логические записи в WAL (op), как и дельты страниц (Δ), теперь меньше благодаря тому, что значения уже сжаты при первоначальной записи в память.

Как следствие, в WAL пишем меньше, чем в любом другом варианте со сжатием и без.

Данные на диске не так хорошо сжимаются, как в первом варианте, но зато сжимаются в памяти. А чем больше данных вмещается в память, тем позже наступает Page Replacement — механизм, который при переполнении памяти подгружает нужную страницу с диска, заменяя ею менее востребованную. Уже начавшийся Page Replacement приводит к значительной дергадации быстродействия, поэтому минимизация этого риска — очень важный бонус.

Чего мы добились в итоге

Мы сравнили оба варианта сжатия — «ванильный» сценарий сжатия страниц на дисĸе и наш новый сценарий сжатия значений в памяти.

  • Мы добавляли данные в пропорции 1:4 к их чтению.

  • Использовали алгогитм сжатия SNAPPY.

  • Комбинировали размер страницы (4 Кб, 8 Кб и 16 Кб) и различные подходы к сжатию (None — без сжатия, Value — сжатие значений, Page — страниц, WAL — журнала изменений).

  • Использовали данные в формате: Ключ — Integer, Значение — String (размером в 1 Кб, сжимаемая до ~380 байт).

И получили следующие результаты:

1) При использовании нового подхода к сжатию уменьшается потребление памяти, что и было первоначальной целью. Это увеличивает зазор до Page Replacement.

Потребление оперативной памяти уменьшилось втрое, по сравнению с несжатой страницей
Потребление оперативной памяти уменьшилось втрое, по сравнению с несжатой страницей

2) Неплохое сжатие данных на диске — очень приятный бонус к первоначальной цели.

В 3 раза меньшее использование диска, по сравнению с несжатыми данными, близко к варианту сжатия страниц на диске.
В 3 раза меньшее использование диска, по сравнению с несжатыми данными, близко к варианту сжатия страниц на диске.

3) Невероятное уменьшение размеров WAL — неожиданный бонус, проявившийся именно на бенчмарках и кратно повышающий итоговую ценность решения.

В три раза по отношению к варианту без сжатия и в два раза — к варианту сжатия страниц.
В три раза по отношению к варианту без сжатия и в два раза — к варианту сжатия страниц.

4) Ускорение операций — следствие третьего пункта. Меньше пишем — быстрее работаем.

Даже на крутых SSD есть выигрыш по latency по отношению к любым другим вариантам:

Быстрый SSD
Быстрый SSD

На дисках похуже отрыв будет больше:

Медленный SSD
Медленный SSD

На дисĸе со «шпинделем» отрыв, по нашим предположениям, должен быть просто колоссальным.

Выводы

1) Сжатие значений в памяти не так эффективно, как сжатие целых страниц на диске «на бумаге», но кратно превосходит его в эффективности на реальных замерах.

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

И самое главное, мы достигаем первоначальной цели — уменьшения рисков неожиданной деградации системы из-за переполнения памяти и начавшегося Page Replacement.

2) Сжимать данные полезно не только для экономии места, но и для ускорения быстродействия системы.

Чем меньше вы пишете на диск, тем быстрее будут выполняться ваши операции записи. Следовательно, тем быстрее будут происходить и чтения, которые ждут своей очереди в thread pools.

WAL мы вынуждены писать синхронно. Чем больше записываем в WAL, тем хуже latency. Меньше всего в WAL (за весь бенчмарк) мы пишем при использовании нового сценария — 1,3 Гб против 2,6 Гб в старом.

3) Если ваша основная цель — минимизация объема содержимого на диске при малом числе операций записи (при околонулевой генерации WAL) и время выполнения операций чтения для вас не критично, то вам следует рассмотреть вариант использования «сжатия страниц на диске». При использовании старого сценария хранилище занимает 0,3 Гб против 0,5 Гб в новом.

Источник: https://habr.com/ru/companies/sberbank/articles/741894/


Интересные статьи

Интересные статьи

В наличии была база данных MSSQL (с которой забираем данные), а также PostgreSQL Pro Enterprise 10.3, развернутая на CentOS 7 (на которую импортируем). Ну и полное отсутствие интернета.
Команда Netflix Cloud Data Engineering с радостью открывает исходный код s3-flash-bootloader, нашего инструмента для выполнения обновления образа ОС на месте на государственных облачных инстансах, под...
Эта статья расскажет, какими общими способами можно защитить свое приложение от взлома или получения персональной информации третьими лицами посредством исполнения нескольких простых шагов, но стоит п...
Привет, друзья! В этой статье я хочу поделиться с вами опытом разработки хука для загрузки дополнительных данных (авось кому-нибудь пригодится). На самом деле, хуков будет целых 2 штуки: useL...
Geometry of Flowers by Mookiezoolook Для приложений, которые будут масштабироваться по трафику и сложности, крайне важно изначально спроектировать грамотную схему базы данных. Е...