Ко всем новостям

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

Публикации в СМИ
Технологии
28.06.2023

Источник: Хабр ""

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

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

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

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

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

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

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

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

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

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

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

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

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

4e0fc320783f7338f86610414a5893e5.png
Сжимаем записи в памяти

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

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

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

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

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

78028984f5759944ec0529f4a2abea6c.png
Сжимаем данные в хранилище (память, диск) и в 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.

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

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

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

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

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

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

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

8dba998f1950a6aa4677e1f9d3d72475.png
Быстрый SSD

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

606962e1f2f14c550c400ed334d3f141.png
Медленный SSD