Skip to content

Postgresql и ZFS

Почему мне нужен ZFS вместо встроенного TOAST?

Для tghub я использую довольно дешевый VPS с только 1тб хранилища. Поэтому мне нужно сжимать мои данные. Несмотря на то, что в Postgresql есть функция TOAST (Техника хранения атрибутов увеличенного размера), она мне не подходит. По умолчанию, TOAST срабатывает для текстовых данных размером 2 кБ. Таблица сообщений моего проекта tghub имеет почти 3 миллиарда строк и продолжает расти, но они обычно маленькие, поэтому TOAST не сработает для меня. Я решил попробовать хранить данные сообщений в отдельном пространстве таблиц и переместить их на файловую систему ZFS.

Общая схема

Текущая производительность

Мне удалось достичь хорошего баланса между дисками.

img1

  • sda -- Default Tablespace
  • sdb -- ZFS Tablespace
  • sdc -- Index Tablespace

Во время нормальной рабочей нагрузки диск с индексами самый загруженный, что ожидаемо. На диске размещены 2 индекса, которые изменяются случайными вставками (~800 строк в секунду). Лучше не перегружать диск с основным пространством таблиц, так как там хранятся индексы для поиска. Когда много пользователей решат что-то искать одновременно, этот диск должен иметь запас мощности.

Настройка Postgresql и ZFS

Я сделал некоторую дополнительную настройку для zfs и postgresql:

  1. Отключил TOAST, чтобы не сжимать данные дважды:
sql
ALTER TABLE channel_message 
    ALTER COLUMN text SET STORAGE EXTERNAL;
  1. Следовать рекомендациям zfs для баз данных и установить размер сектора в 32К. По умолчанию размер составляет 128К. Это слишком много и вызывает нежелательные чтения. Мы можем даже установить размер сектора в 8К, но это уменьшает коэффициент сжатия. Поэтому важно найти баланс между скоростью чтения (меньший сектор) и коэффициентом сжатия (больший сектор)
shell
sudo zfs set recordsize=32K datapool
  1. Выключить обновленное время, это действительно не имеет смысла:
shell
sudo zfs set atime=off datapool
  1. Установить компрессию на zstd, она медленнее, чем lz4, но имеет лучший коэффициент сжатия (может быть x2 для текстовых данных):
shell
sudo zfs set atime=off datapool

На данный момент моя таблица channel_message с почти 3 миллиардами строк занимает 1061Гб несжатых данных против 291Гб сжатых на диске ZFS. Это более чем 3x коэффициент!