Состояния пулов

Пул активен — то есть, полностью доступен для клиентского ввода-вывода — когда все его PG активны, то есть, имеют статус active, возможно, с любым набором дополнительных флагов.

Если хотя бы 1 PG неактивна, пул неактивен и все клиенты зависают и ждут, пока вы почините кластер. :-)

Состояния PG

Вы можете видеть состояния PG в выводе команды vitastor-cli status.

Состояние PG состоит из ровно 1 базового флага состояния, плюс любого числа дополнительных.

Базовые состояния PG

Состояние PG включает в себя ровно 1 флаг из следующих:

  • active — PG активна и обрабатывает запросы ввода-вывода от пользователей.
  • incomplete — Недостаточно живых OSD, чтобы включить эту PG. То есть, дисков потеряно больше, чем разрешено схемой отказоустойчивости пула и pg_minsize. Например, если у пула pg_size=3 и pg_minsize=1, то часть данных может записаться всего на 1 OSD. Если потом конкретно этот OSD упадёт, PG окажется incomplete.
  • offline — PG вообще не активирована ни одним OSD. Либо первичный OSD не назначен вообще (если пул только создан), либо в качестве первичного назначен недоступный OSD, либо назначенный OSD отказывается запускать эту PG (например, из-за несовпадения block_size), либо PG остановлена монитором через флаг pause: true в /vitastor/pg/config в etcd.
  • starting — первичный OSD захватил блокировку PG в etcd, PG запускается.
  • peering — первичный OSD опрашивает вторичные OSD на предмет списков объектов данной PG и рассчитывает её состояние.
  • repeering — PG ожидает завершения текущих операций ввода-вывода, после чего перейдёт в состояние peering.
  • stopping — PG ожидает завершения текущих операций ввода-вывода, после чего перейдёт в состояние offline или поднимется на другом OSD.

Все состояния, кроме active, означают, что PG неактивна и ввод-вывод приостановлен.

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

Состояния starting, repeering, stopping в норме практически не заметны вообще, PG должны очень быстро переходить из них в другие. Если эти состояния заметны хоть сколько-то значительное время — вероятно, какие-то операции на каких-то OSD зависли. Чтобы найти их, ищите “slow op” в журналах OSD — операции, зависшие дольше, чем на slow_log_interval, записываются в журналы OSD как “slow op”.

Диаграмма переходов:

Диаграмма переходов

Дополнительные состояния PG

Если PG активна, она также может иметь любое число дополнительных флагов состояний:

  • degraded — PG поднята на неполном числе дисков (OSD), избыточность хранения всех объектов снижена.
  • has_incomplete — часть объектов в PG неполные (невосстановимые), то есть, у них потеряно слишком много EC-частей (больше, чем parity_chunks пула).
  • has_degraded — часть объектов в PG деградированы, избыточность их хранения снижена по сравнению с остальным содержимым данной PG (то есть, PG может одновременно быть degraded+has_degraded). Данные объекты должны восстановиться автоматически, если только восстановление не отключено через no_recovery.
  • has_misplaced — часть объектов в PG сейчас расположена не на целевом наборе OSD этой PG. Данные объекты должны переместиться автоматически, если только перебалансировка не отключена через no_rebalance. Объекты, являющиеся одновременно degraded и misplaced, считаются просто degraded.
  • has_unclean — ещё одно состояние, в норме заметное только очень короткое время при поднятии PG. Применяется только к EC и означает, что на каких-то OSD этой PG есть EC-части объектов, для которых был начат, но не завершён процесс записи. Все такие объекты первичный OSD либо завершает, либо откатывает при поднятии PG первым делом, поэтому состояние и не должно быть заметно. Опять-таки, если оно заметно — значит, скорее всего, операции отката или завершения записи на каких-то OSD зависли.
  • has_invalid — в PG найдены объекты с некорректными ID части. В норме не проявляется вообще никогда, проявляется только если, не удалив данные, создать на месте EC-пула либо реплика-пул, либо EC-пул с меньшим числом частей данных.
  • has_corrupted — в PG есть повреждённые объекты, обнаруженные с помощью контрольных сумм или скраба (сверки копий). Если объекты можно восстановить, они восстановятся автоматически. Если не восстанавливаются, используйте команду vitastor-cli describe для выяснения деталей и/или смотрите в журнал первичного OSD данной PG.
  • has_inconsistent — в PG есть объекты, у которых не совпадают копии/части данных на разных OSD, и при этом автоматически определить, какая копия верная, а какая нет, невозможно. Такое может произойти, если вы используете 2 реплики, не включали контрольные суммы, и на одной из реплик данные повредились. В этом случае тоже надо использовать команды vitastor-cli describe и fix для удаления некорректной версии.
  • left_on_dead — часть данных PG осталась на отключённом, но не удалённом из кластера окончательно, OSD. Вам нужно либо вернуть соответствующий OSD в строй и дать ему очистить лишние данные, либо удалить его из кластера окончательно с помощью vitastor-cli rm-osd, если известно, что он уже не вернётся (например, если умер диск).
  • scrubbing — идёт фоновая проверка данных PG (скраб).

Удаление исправного диска

Перед удалением исправного диска из кластера установите его OSD вес в 0, чтобы убрать с него данные. Для этого выполните команду vitastor-cli modify-osd --reweight 0 <НОМЕР_OSD>.

Дождитесь завершения перебалансировки данных, после чего удалите OSD командой vitastor-disk purge /dev/vitastor/osdN-data.

Также вес 0 можно прописать вручную прямо в etcd в ключ /vitastor/config/osd/<НОМЕР_OSD>, например:

etcdctl --endpoints=http://1.1.1.1:2379/v3 put /vitastor/config/osd/1 '{"reweight":0}'

Удаление неисправного диска

Если диск уже умер, его OSD, скорее всего, уже будет/будут остановлен(ы).

В этом случае просто удалите OSD из etcd командой vitastor-cli rm-osd НОМЕР_OSD.

Добавление диска

Если сервер новый, установите на него пакеты Vitastor и скопируйте файл конфигурации /etc/vitastor/vitastor.conf.

После этого достаточно выполнить команду vitastor-disk prepare /dev/nvmeXXX, разумеется, с параметрами, аналогичными другим OSD в вашем кластере.

Восстановление потерянной конфигурации пулов

Если удалить или повредить ключ /vitastor/config/pools в etcd, все пулы будут удалены. Не волнуйтесь, данные потеряны не будут, но вам нужно будет провести специальную процедуру восстановления.

Сначала нужно будет восстановить конфигурацию пулов, создав пул с таким же ID и с такими же параметрами EC/реплик, и подождать, пока PG пула появятся в vitastor-cli status.

Далее нужно будет добавить все OSD в исторические записи всех PG. Примерно так (только подставьте свои PG_COUNT и POOL_ID):

PG_COUNT=32
POOL_ID=1
ALL_OSDS=$(etcdctl --endpoints=your_etcd_address:2379 get --keys-only --prefix /vitastor/osd/stats/ | \
    perl -e '$/ = undef; $a = <>; $a =~ s/\s*$//; $a =~ s!/vitastor/osd/stats/!!g; $a =~ s/\s+/,/g; print $a')
for i in $(seq 1 $PG_COUNT); do
    etcdctl --endpoints=your_etcd_address:2379 put /vitastor/pg/history/$POOL_ID/$i '{"all_peers":['$ALL_OSDS']}'
done

После этого все PG должны пройти peering и найти все предыдущие данные.

Обновление Vitastor

Обычно каждая следующая версия Vitastor совместима с предыдущими и “вперёд”, и “назад” с точки зрения сетевого протокола и структур данных в etcd.

Так что по умолчанию, если на данной странице не указано обратное, считается, что для обновления достаточно обновить пакеты и перезапустить все OSD и мониторы Vitastor в произвольном порядке.

Обновление производится без остановки клиентов (виртуальных машин/контейнеров), для этого достаточно обновлять серверы по одному. Однако, конечно, чтобы запущенные виртуальные машины начали использовать новую версию клиентской библиотеки, их тоже нужно перезапустить.

1.7.x -> 1.8.0

После обновления с версий <= 1.7.x до версий >= 1.8.0, НО <= 1.9.0: перезапустите всех клиентов (процессы виртуальных машин можно перезапустить путём миграции на другой сервер), иначе они зависнут, когда монитор удалит старый ключ конфигурации PG, что происходит через 24 часа после обновления.

Однако, это исправлено в 1.9.1. Так что, если вы обновляетесь с <= 1.7.x сразу до >= 1.9.1, вам НЕ нужно сразу перезапускать всех клиентов - они будут работать, как раньше. Минус, правда, в том, что старый ключ конфигурации PG (/vitastor/config/pgs) будет нужно удалить вам из etcd вручную - после того, как вы убедитесь, что все клиенты перезапущены.

1.1.x -> 1.2.0

Обновляться с версий <= 1.1.x до версий >= 1.2.0, если вы используете EC n+k и k>=2, рекомендуется с временной остановкой кластера — сначала нужно остановить всех клиентов, потом все OSD, потом обновить и запустить всё обратно — из-за нескольких багов, которые могли приводить к некорректному чтению данных в деградированных EC-пулах.

0.8.7 -> 0.9.0

Версии <= 0.8.7 несовместимы с версиями >= 0.9.0, поэтому при обновлении с <= 0.8.7 нужно сначала обновиться до 0.8.8 или 0.8.9, а уже потом до любых версий >= 0.9.x. Иначе клиентский ввод-вывод зависнет до завершения обновления.

0.5.x -> 0.6.x

Обновление с версий 0.5.x и более ранних до 0.6.x и более поздних не поддерживается.

Откат версии

Откат (понижение версии) тоже свободно разрешён, кроме указанных ниже случаев:

1.8.0 -> 1.7.1

Перед понижением версии с >= 1.8.0 до <= 1.7.1 вы должны скопировать ключ etcd /vitastor/pg/config в /vitastor/config/pgs:

etcdctl --endpoints=http://... get --print-value-only /vitastor/pg/config | \
  etcdctl --endpoints=http://... put /vitastor/config/pgs

После этого можно просто установить более старые пакеты и перезапустить все сервисы.

Если вы откатили версию, не скопировав предварительно этот ключ - выполните “добавление всех OSD в исторические записи всех PG” из раздела Восстановление потерянной конфигурации пулов.

1.0.0 -> 0.9.x

В версии 1.0.0 поменялся дисковый формат, поэтому OSD, созданные на версии >= 1.0.0, нельзя откатить до версии 0.9.x и более ранних.

0.8.0 -> 0.7.x

В версиях ранее 0.8.0 нет vitastor-disk, значит, созданные им OSD не запустятся на более ранних версиях (0.4.x - 0.7.x). :-)

Потребление памяти OSD

Основное потребление памяти складывается из:

  • Индекс метаданных: размер_данных/block_size * примерно 1.1 * 32 байт. Потребляется всегда.
  • Копия дисковой области метаданных: размер_данных/block_size * 28 байт. Потребляется, если не отключена настройка inmemory_metadata.
  • Битмапы: размер_данных/bitmap_granularity/8 * 2 байт. Потребляется всегда.
  • Индекс журнала: от 0 до, приблизительно, размера журнала. Потребляется всегда.
  • Копия дисковой области журнала: в точности размер журнала. Потребляется, если не отключена настройка inmemory_journal.
  • Контрольные суммы: размер_данных/csum_block_size * 4 байт. Потребляется, если включены контрольные суммы и не отключена настройка inmemory_metadata.

bitmap_granularity, как правило, никогда не меняется и равен 4 килобайтам.

Таким образом, при SSD-настройках по умолчанию (block_size=128k, journal_size=32M, csum_block_size=4k) потребляется:

  • Метаданные и битмапы: ~600 МБ на 1 ТБ данных
  • Журнал: до 64 МБ на 1 OSD
  • Контрольные суммы: 1 ГБ на 1 ТБ данных

При HDD-настройках по умолчанию (block_size=1M, journal_size=128M, csum_block_size=32k):

  • Метаданные и битмапы: ~128 МБ на 1 ТБ данных
  • Журнал: до 256 МБ на 1 OSD
  • Контрольные суммы: 128 МБ на 1 ТБ данных