Обслуговування

Посібник з періодичного обслуговування кластера etcd

Огляд

Кластер etcd потребує періодичного обслуговування, щоб залишатися надійним. Залежно від потреб застосунку etcd, це обслуговування зазвичай можна автоматизувати та виконувати без простоїв або значного зниження продуктивності.

Все обслуговування etcd керує ресурсами зберігання, які споживає ключовий простір etcd. Недостатній контроль розміру ключового простору захищений квотами на дисковий простір; якщо учаснику etcd не вистачає місця, квота викликає кластерні тривоги, які переводять систему в режим обмеженого обслуговування. Щоб уникнути нестачі місця для записів у ключовий простір, історія ключового простору etcd повинна бути стиснута. Сам дисковий простір можна відновити шляхом дефрагментації учасників etcd. Нарешті, періодичні резервні копії знімків стану учасників etcd дозволяють відновити будь-які ненавмисні логічні втрати даних або пошкодження, спричинені операційною помилкою.

Збереження журналу Raft

etcd --snapshot-count налаштовує кількість застосованих записів Raft, які зберігаються в памʼяті перед стисненням. Коли досягається --snapshot-count, сервер спочатку зберігає дані знімка на диск, а потім обрізає старі записи. Коли повільний послідовник запитує журнали до стисненого індексу, лідер надсилає знімок, змушуючи послідовника перезаписати свій стан.

Вищий --snapshot-count зберігає більше записів Raft у памʼяті до знімка, що призводить до постійного вищого використання памʼяті. Оскільки лідер зберігає останні записи Raft довше, повільний послідовник має більше часу, щоб наздогнати перед знімком лідера. --snapshot-count є компромісом між вищим використанням памʼяті та кращою доступністю повільних послідовників.

З версії v3.2 стандартне значення --snapshot-count змінено з 10 000 на 100 000.

З погляду продуктивності, --snapshot-count більш як 100 000 може вплинути на пропускну здатність запису. Більша кількість обʼєктів у памʼяті може уповільнити фазу маркування Go GC runtime.scanobject, а рідкісне відновлення памʼяті уповільнює виділення. Продуктивність варіюється залежно від робочих навантажень і системних середовищ. Однак, загалом, занадто часте стиснення впливає на доступність кластера та пропускну здатність запису. Занадто рідкісне стиснення також шкідливе, оскільки створює занадто великий тиск на збирач сміття Go. Дивіться https://www.slideshare.net/mitakeh/understanding-performance-aspects-of-etcd-and-raft для отримання додаткових результатів досліджень.

Стиснення історії: v3 API База даних ключ-значення

Оскільки etcd зберігає точну історію свого ключового простору, цю історію слід періодично стискати, щоб уникнути зниження продуктивності та вичерпання дискового простору. Стиснення історії ключового простору видаляє всю інформацію про ключі, які були замінені до певної ревізії ключового простору. Простір, який використовували ці ключі, стає доступним для додаткових записів у ключовий простір.

Ключовий простір можна стискати автоматично за допомогою політики збереження історії з часовими вікнами etcd, або вручну за допомогою etcdctl. Метод etcdctl забезпечує точний контроль над процесом стиснення, тоді як автоматичне стиснення підходить для додатків, яким потрібна історія ключів лише на певний час.

Стиснення, ініційоване etcdctl, працює наступним чином:

# стиснути до ревізії 3 $ etcdctl compact 3

Ревізії до ревізії стиснення стають недоступними:

$ etcdctl get --rev=2 somekey Error: rpc error: code = 11 desc = etcdserver: mvcc: required revision has been compacted

Автоматичне стиснення

etcd можна налаштувати на автоматичне стиснення ключового простору за допомогою опції --auto-compaction-* з періодом у години:

# зберігати одну годину історії $ etcd --auto-compaction-retention=1

v3.0.0 та v3.1.0 з --auto-compaction-retention=10 виконують періодичне стиснення на v3 сховищі ключ-значення кожні 10 годин. Ущільнювач підтримує лише періодичне стиснення. Ущільнювач записує останні ревізії кожні 5 хвилин, поки не досягне першого періоду стиснення (наприклад, 10 годин). Щоб зберегти історію ключ-значення останнього періоду стиснення, він використовує останню ревізію, яка була отримана до періоду стиснення, з записів ревізій, які збиралися кожні 5 хвилин. Коли --auto-compaction-retention=10, ущільнювач використовує ревізію 100 для ревізії стиснення, де ревізія 100 є останньою ревізією, отриманою 10 годин тому. Якщо стиснення вдається або запитувана ревізія вже була стиснута, він скидає таймер періоду та починає заново з новими записами історичних ревізій (наприклад, перезапуск збору ревізій та стиснення для наступного 10-годинного періоду). Якщо стиснення не вдається, він повторює спробу через 5 хвилин.

v3.2.0 ущільнювач працює щогодини. Ущільнювач підтримує лише періодичне стиснення. Ущільнювач продовжує записувати останні ревізії кожні 5 хвилин. Щогодини він використовує останню ревізію, яка була отримана до періоду стиснення, з записів ревізій, які збиралися кожні 5 хвилин. Тобто щогодини ущільнювач видаляє історичні дані, створені до періоду стиснення. Вікно збереження періоду стиснення переміщується на наступну годину. Наприклад, коли щогодинні записи становлять 100, а --auto-compaction-retention=10, v3.1 стискає ревізії 1000, 2000 і 3000 кожні 10 годин, тоді як v3.2.x, v3.3.0, v3.3.1 і v3.3.2 стискають ревізії 1000, 1100 і 1200 кожну годину. Якщо стиснення вдається або запитувана ревізія вже була стиснута, він скидає таймер періоду та видаляє використану стиснуту ревізію з історичних записів ревізій (наприклад, починає наступний збір ревізій та стиснення з раніше зібраних ревізій). Якщо стиснення не вдається, він повторює спробу через 5 хвилин.

У v3.3.0, v3.3.1 та v3.3.2, --auto-compaction-mode=revision --auto-compaction-retention=1000 автоматично Compact на "latest revision" - 1000 кожні 5 хвилин (коли остання ревізія становить 30000, стиснути на ревізії 29000). Наприклад, --auto-compaction-mode=periodic --auto-compaction-retention=72h автоматично Compact з 72-годинним вікном збереження кожні 7,2 години. Наприклад, --auto-compaction-mode=periodic --auto-compaction-retention=30m автоматично Compact з 30-хвилинним вікном збереження кожні 3 хвилини. Періодичний ущільнювач продовжує записувати останні ревізії кожні 1/10 заданого періоду стиснення (наприклад, 1 година, коли --auto-compaction-mode=periodic --auto-compaction-retention=10h). Кожні 1/10 заданого періоду стиснення ущільнювач використовує останню ревізію, яка була отримана до періоду стиснення, щоб видалити історичні дані. Вікно збереження періоду стиснення переміщується кожні 1/10 заданого періоду стиснення. Наприклад, коли щогодинні записи становлять 100, а --auto-compaction-retention=10, v3.1 стискає ревізії 1000, 2000 і 3000 кожні 10 годин, тоді як v3.2.x, v3.3.0, v3.3.1 і v3.3.2 стискають ревізії 1000, 1100 і 1200 кожну годину. Крім того, коли записи за хвилину становлять 1000, v3.3.0, v3.3.1 і v3.3.2 з --auto-compaction-mode=periodic --auto-compaction-retention=30m стискають ревізії 30000, 33000 і 36000 кожні 3 хвилини з більш тонкою гранулярністю.

Коли --auto-compaction-retention=10h, etcd спочатку чекає 10 годин для першого стиснення, а потім виконує стиснення щогодини (1/10 від 10 годин) після цього, як показано нижче:

0Hr  (rev = 1)
1hr  (rev = 10)
...
8hr  (rev = 80)
9hr  (rev = 90)
10hr (rev = 100, Compact(1))
11hr (rev = 110, Compact(10))
...

Незалежно від того, чи вдається стиснення, цей процес повторюється кожні 1/10 заданого періоду стиснення. Якщо стиснення вдається, він просто видаляє стиснуту ревізію з історичних записів ревізій.

У v3.3.3, --auto-compaction-mode=revision --auto-compaction-retention=1000 автоматично Compact на "latest revision" - 1000 кожні 5 хвилин (коли остання ревізія становить 30000, стиснути на ревізії 29000). Раніше, --auto-compaction-mode=periodic --auto-compaction-retention=72h автоматично Compact з 72-годинним вікном збереження кожні 7,2 години. Тепер, Compact відбувається кожну годину, але все ще з 72-годинним вікном збереження. Раніше, --auto-compaction-mode=periodic --auto-compaction-retention=30m автоматично Compact з 30-хвилинним вікном збереження кожні 3 хвилини. Тепер, Compact відбувається кожні 30 хвилин, але все ще з 30-хвилинним вікном збереження. Періодичний ущільнювач продовжує записувати останні ревізії кожного періоду стиснення, коли заданий період менше ніж 1 година, або кожної години, коли заданий період стиснення більше ніж 1 година (наприклад, 1 година, коли --auto-compaction-mode=periodic --auto-compaction-retention=24h). Кожного періоду стиснення або години ущільнювач використовує останню ревізію, яка була отримана до періоду стиснення, щоб видалити історичні дані. Вікно збереження періоду стиснення переміщується кожного заданого періоду стиснення або години. Наприклад, коли щогодинні записи становлять 100, а --auto-compaction-mode=periodic --auto-compaction-retention=24h, v3.2.x, v3.3.0, v3.3.1 і v3.3.2 стискають ревізії 2400, 2640 і 2880 кожні 2,4 години, тоді як v3.3.3 або пізніше стискають ревізії 2400, 2500, 2600 кожну годину. Крім того, коли --auto-compaction-mode=periodic --auto-compaction-retention=30m і записи за хвилину становлять близько 1000, v3.3.0, v3.3.1 і v3.3.2 стискають ревізії 30000, 33000 і 36000 кожні 3 хвилини, тоді як v3.3.3 або пізніше стискають ревізії 30000, 60000 і 90000 кожні 30 хвилин.

Дефрагментація

Після стиснення ключового простору, базу даних бекенду може бути внутрішньо фрагментовано. Будь-яка внутрішня фрагментація — це простір, який доступний для використання бекендом, але все ще займає дисковий простір. Стиснення старих ревізій внутрішньо фрагментує etcd, залишаючи прогалини в базі даних бекенду. Фрагментований простір доступний для використання etcd, але недоступний для файлової системи хосту. Іншими словами, видалення даних застосунку не відновлює простір на диску.

Процес дефрагментації повертає цей дисковий простір назад до файлової системи. Дефрагментація виконується на основі кожного учасника, щоб уникнути кластерних піків затримки.

Щоб дефрагментувати учасника etcd, використовуйте команду etcdctl defrag:

$ etcdctl defrag Finished defragmenting etcd member[127.0.0.1:2379]

Зверніть увагу, що дефрагментація живого учасника блокує систему від читання та запису даних під час відновлення його станів.

Зверніть увагу, що запит на дефрагментацію не реплікується по кластеру. Тобто запит застосовується лише до локального вузла. Вкажіть усіх учасників у прапорці --endpoints або прапорці --cluster, щоб автоматично знайти всіх учасників кластера.

Запустіть операції дефрагментації для всіх точок доступу у кластері, повʼязаних зі стандартною точкою доступу:

$ etcdctl defrag --cluster Finished defragmenting etcd member[http://127.0.0.1:2379] Finished defragmenting etcd member[http://127.0.0.1:22379] Finished defragmenting etcd member[http://127.0.0.1:32379]

Щоб дефрагментувати теку даних etcd безпосередньо, коли etcd не працює, використовуйте команду:

$ etcdctl defrag --data-dir <path-to-etcd-data-dir>

Квота на дисковий простір

Квота на дисковий простір в etcd забезпечує надійну роботу кластера. Без квоти на дисковий простір etcd може страждати від поганої продуктивності, якщо ключовий простір стає надто великим, або він може просто вичерпати дисковий простір, що призводить до непередбачуваної поведінки кластера. Якщо база даних бекенду ключового простору для будь-якого учасника перевищує квоту на дисковий простір, etcd здіймає кластерну тривогу, яка переводить кластер у режим обслуговування, який приймає лише читання та видалення ключів. Тільки після звільнення достатньої кількості місця в ключовому просторі та дефрагментації бази даних бекенду, а також зняття тривоги квоти на дисковий простір кластер може відновити нормальну роботу.

Стандартно etcd встановлює консервативну квоту на дисковий простір, яка підходить для більшості застосунків, але її можна налаштувати у командному рядку в байтах:

# встановити дуже маленьку квоту 16 МіБ $ etcd --quota-backend-bytes=$((16*1024*1024))

Квоту на дисковий простір можна викликати за допомогою циклу:

# заповнити ключовий простір $ while [ 1 ]; do dd if=/dev/urandom bs=1024 count=1024 | ETCDCTL_API=3 etcdctl put key || break; done ... Error: rpc error: code = 8 desc = etcdserver: mvcc: database space exceeded # підтвердити, що квота на дисковий простір перевищена $ ETCDCTL_API=3 etcdctl --write-out=table endpoint status +----------------+------------------+-----------+---------+-----------+-----------+------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | +----------------+------------------+-----------+---------+-----------+-----------+------------+ | 127.0.0.1:2379 | bf9071f4639c75cc | 2.3.0+git | 18 MB | true | 2 | 3332 | +----------------+------------------+-----------+---------+-----------+-----------+------------+ # підтвердити, що тривогу здійнято $ ETCDCTL_API=3 etcdctl alarm list memberID:13803658152347727308 alarm:NOSPACE

Видалення надлишкових даних ключового простору та дефрагментація бази даних бекенду поверне кластер у межі квоти:

# отримати поточну ревізію $ rev=$(ETCDCTL_API=3 etcdctl --endpoints=:2379 endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*') # стиснути всі старі ревізії $ ETCDCTL_API=3 etcdctl compact $rev compacted revision 1516 # дефрагментувати надлишковий простір $ ETCDCTL_API=3 etcdctl defrag Завершено дефрагментацію учасника etcd[127.0.0.1:2379] # зняти тривогу $ ETCDCTL_API=3 etcdctl alarm disarm memberID:13803658152347727308 alarm:NOSPACE # перевірити, що записи знову дозволені $ ETCDCTL_API=3 etcdctl put newkey 123 OK

Метрика etcd_mvcc_db_total_size_in_use_in_bytes вказує на фактичне використання бази даних після стиснення історії, тоді як etcd_debugging_mvcc_db_total_size_in_bytes показує розмір бази даних, включаючи вільний простір, що чекає на дефрагментацію. Остання збільшується лише тоді, коли перша наближається до неї, тобто коли обидві ці метрики наближаються до квоти, необхідно стиснути історію, щоб уникнути виклику квоти на дисковий простір.

etcd_debugging_mvcc_db_total_size_in_bytes перейменовано на etcd_mvcc_db_total_size_in_bytes з версії v3.4.

ПРИМІТКА: можливо отримати помилку ErrGRPCNoSpace для запиту Put/Txn/LeaseGrant і все ж успішно виконати запит на запис у бекенді, оскільки etcd перевіряє квоту на дисковий простір на рівні API та внутрішньому рівні Apply, і рівень Apply здійме тривогу NOSPACE без блокування транзакції.

Резервне копіювання знімків

Регулярне створення знімків кластера etcd служить надійною резервною копією для ключового простору etcd. Роблячи періодичні знімки бази даних бекенду учасника etcd, кластер etcd можна відновити до певного моменту часу з відомим хорошим станом.

Знімок робиться за допомогою etcdctl:

$ etcdctl snapshot save backup.db $ etcdutl --write-out=table snapshot status backup.db +----------+----------+------------+------------+ | HASH | REVISION | TOTAL KEYS | TOTAL SIZE | +----------+----------+------------+------------+ | fe01cf57 | 10 | 7 | 2.1 MB | +----------+----------+------------+------------+