Кворум (Quorum) в перекладі з латині означає більшість, а кворумние моделі використовується в відмовостійких кластерах Windows для визначення працездатності кластера. При виході з ладу одного або декількох вузлів кластера серед решти проводиться голосування, і якщо вони набирають більшість голосів (кворум), то кластер продовжує роботу, якщо ж не набирають - кластер зупиняється.
Служба кластера (Failover Clustering) з'явилася ще в Windows NT 4.0. Тоді під кластером малося на увазі два вузла (Node), об'єднані разом і мають доступ до загальної сховища, на якому розташовувався кворумний диск, або диск-свідок (Disk Witness). Голосування як такого не було, а працездатність кластера визначалася доступністю кворумного диска. При виході з ладу одного з вузлів другої захоплював диск і продовжував роботу.
Така модель кворуму збереглася і до сих пір під назвою Disk Only. При використанні цієї моделі кластер може пережити втрату всіх вузлів кластера крім одного, який володіє кворумним диском. Як ви розумієте, тут диск є єдиною точкою відмови і в разі його відмови весь кластер стає непрацездатним.
Node Majority (більшість вузлів) - кожному вузлу кластера призначається голос, диск-свідок голосу не має.
Node and Disk Majority (більшість вузлів і диск) - кожен вузол кластера і диск-свідок має голос і бере участь в голосуванні.
Вибір моделі прямо залежав від кількості вузлів в кластері, так Node Majority зручніше використовувати при непарній кількості вузлів, а Node and Disk Majority при парному. У будь-якому випадку для продовження роботи кластера необхідно набрати більшість голосів (> 50%).
Для прикладу візьмемо 5-ти вузловий кластер з кворумной моделлю Node Majority. У кожного вузла 1 голос, відповідно всі 5 голосів становлять 100%. Для того, щоб набрати кворум, необхідно більше 50% голосів, що в даному випадку становить 3 голоси з 5. Шляхом нескладних підрахунків 🙂 отримуємо, що даний кластер може перенести вихід з ладу не більше 2 вузлів. При виході з ладу третього вузла залишилися вузли не зможуть зібрати більшість і кластер буде зупинений.
Node Weight
Сенс зміни ваги полягав в тому, в тому, щоб виключити один або декілька вузлів з процесу голосування, щоб їх падіння не приводило до зупинки кластера. При цьому вузол продовжує брати участь в роботі кластера і обробляти клієнтські підключення, але не бере участі в голосуванні. Виняток з голосування досягалося шляхом установки значення параметра NodeWeight рівним 0. Зміна ваги вузла вироблялося вручну, за допомогою PowerShell або через правку реєстру.
Для прикладу візьмемо мультісайтового кластер, що складається з 5 вузлів і використовує кворумную модель з файлової шарою (Node and File Share Majority). Три вузла кластера знаходяться в основному сайті, два в резервному, і десь в третьому розміщена файлова кулі-свідок. При звичайному підході вихід трьох вузлів в основному сайті з ладу (напр. Відключення електрики) призведе до падіння всього кластера, оскільки які у резервному сайті 2 вузла + файлова кулі не наберуть більше половини голосів (3 голоси з 6).
А ось якщо відібрати в одного з вузлів в основному сайті голос, то ми отримаємо 2 голоси в основному сайті і 2 в резервному. Відповідно при падінні основного сайту решта вузли в резервному за допомогою кулі зможуть набрати більшість (3 з 5) і стартувати кластер.
Dynamic Quorum
• При виході з ладу вузла - вузол з найменшим номером (Node ID) з решти призводить вага вузла в 0;
• При штатному виключенні вузла - вузол сам видаляє свій голос в процесі вимикання сервера;
• При додаванні вузла в кластер - вузол додає свій голос в процесі додавання.
При використанні динамічного кворуму кожен вузол має два параметри - динамічний вага (DynamicWeight) і цільової вага (NodeWeight) вузла. Динамічний кворум працює тільки з динамічним вагою, не змінюючи цільової вагу. Принцип такий: при відключенні вузла його динамічний вага встановлюється в 0, а коли вузол стартував і працює, то його динамічний вага підвищується до цільового. Таким чином, динамічний кворум дозволяє кластеру вижити навіть в тому випадку, якщо у нього залишився всього один вузол. Єдине обмеження - вузли повинні виходити з ладу по черзі, щоб був час на перерахунок кворуму. При одночасному виході з ладу понад 50% вузлів динамічний кворум не спрацює і кластер буде зупинений.
Як приклад візьмемо 5-ти вузловий кластер з моделлю Node Majority. Як ви пам'ятаєте з попереднього прикладу, при використанні стандартної кворумной моделі такої кластер переживає втрату максимум двох вузлів. Але оскільки динамічний кворум автоматично перераховує загальну кількість голосів, то тепер при виході з ладу 3 вузлів ми отримаємо не 2 голоси з 5, а 2 голоси з 2, що дасть можливість кластеру продовжити роботу при послідовній втраті більше половини вузлів (3 з 5).
Примітка. Якщо в кластері залишаються тільки 2 вузла і немає диска-свідка, то можлива ситуація Split-Brain, коли при втраті зв'язку між вузлами кожен з них вважатиме себе самостійним. Для уникнення цього кластерна служба знижує вагу одного з решти вузлів до 0. Відповідно при втраті зв'язку служба кластера на одному вузлі буде зупинена, а на другому продовжить працювати.
Dynamic Witness
При використанні динамічного свідка вага диска є величиною змінною і залежить від кількості працюючих вузлів в кластері. Так наприклад, в 5-ти вузловому кластері з моделлю Node and Disk Majority диск-свідок має нульову вагу і не бере участі в голосуванні. При втраті одного вузла і перерахунку кворуму кількість голосів стає парних, і щоб цього уникнути диск свідок отримує голос. І так аж до останнього вузла, при непарній кількості вузлів в кластері вага диска дорівнює 0, а при парному 1.
Примітка. При наявності диска-свідка служба кластера ніколи не знижує кількість голосів нижче 2.
LowerQuorumPriorityNodeID
При використанні геораспределенних кластерів актуальна проблема одночасної втрати 50% вузлів, що може привести до різних неприємних ситуацій.
Для прикладу візьмемо мультісайтового 4-х вузловий кластер із загальним диском (Node and Disk Majority). Кластер розділений рівно навпіл, два вузла кластера знаходяться в основному сайті, два в резервному, всього 5 голосів (4 вузли + диск). Начебто все красиво, при виході з ладу одного сайту сайту вузли в іншому разом зі свідком зможуть набрати кворум і продовжити роботу.
А тепер припустимо, що диск-свідок виходить з ладу і стає недоступний. Динамічний кворум автоматично підтримує непарна кількість голосів, тому у одного з вузлів, обраного довільно, динамічний вага знижується до 0. У результаті ми маємо 3 голоси - 2 в одному сайті і 1 в іншому. Якщо тепер зв'язок між сайтами перерветься, то кворум буде зібраний в тому сайті, де залишилося 2 голоси, і не факт що це буде основний сайт.
Force quorum resiliency
У ситуації, коли кворум неможливо зібрати автоматично, є можливість примусово запустити службу кластера на що залишилися вузлах, використавши форсування кворуму (ForceQuorum). Для цього адміністратор повинен вибрати один з доступних вузлів і вручну запустити на ньому службу кластера у форсованому режимі. Зробити це можна з командного рядка, командою net start clussvc / fq або за допомогою PowerShell, Командлети Start-ClusterNode з ключем ForceQuorum.
Після цього на всіх інших вузлах служба кластера також повинна бути запущена вручну, командою net start clussvc / pq або Командлети Start-ClusterNode з ключем PreventQuorum. Це не дасть їм зібрати свій власний кластер, а змусить шукати існуючий і приєднуватися до нього.
Подібний підхід не завжди можливий. Наприклад візьмемо ситуацію, коли у нас є мультісайтового 5-ти вузловий кластер, вузли якого рознесені на два сайти (основний і резервний). В основному сайті знаходяться 3 вузли, в резервному соответствено 2. Зв'язок з основним сайтом втрачається, що мається на увазі одночасна втрату понад 50% вузлів. У цій ситуації динамічний кворум не допоможе, і для відновлення роботи кластера в резервному сайті адміністратор повинен буде вручну запустити службу кластера з ключем ForceQuorum.
А тепер припустимо, що мали місце проблеми з мережею, і в самому ЦОДі все продовжує працювати. Відповідно, маючи більшість, вузли в основному сайті зберуть кворум і будуть продовжувати роботу. А як тільки підключення буде відновлено, ми отримаємо Split-Brain, тому що вузли кластера в основному і резервному сайтах, втративши зв'язок один з одним, будуть вважати себе себе самостійним кластером.
А тепер для наочності давайте розглянемо кілька живих прикладів.
Приклад 1. Налаштування ваги вузла
Для прикладу візьмемо 4-х вузловий кластер з "оригінальним" ім'ям Cluster1. Відкриємо оснащення Failover Cluster Manager, зайдемо в розділ «Nodes» і подивимося список його вузлів. Тут нас цікавлять дві колонки:
• Assigned Vote - голос, який призначений вузлу в загальному випадку. Визначається цільовим вагою вузла (NodeWeight);
• Current Vote - голос, який має вузол в даний момент. Залежить від поточного значення динамічного ваги вузла (DynamicWeight).
За замовчуванням для працюючих вузлів ці параметри ідентичні і рівні 1.
Як ви пам'ятаєте, цільової вага вузла може бути змінений вручну. Для цього натискаємо правою клавішею на імені кластера та в контекстному меню переходимо в розділ More Actions -> Configure Cluster Quorum Settings.
І перейшовши в розширені налаштування кворуму (Advanced quorum configuration) вибираємо ті вузли кластера, які будуть мати право голосу.
Примітка. Вибравши пункт No Nodes ми отримаємо кворумную модель Disk Only, в якій право голосу є тільки у кворумного ресурсу.
Також знизити цільової вага обраних вузлів можна за допомогою PowerShell, ось такою командою:
(Get-ClusterNode -Name SRV5) .NodeWeight = 0
(Get-ClusterNode -Name SRV6) .NodeWeight = 0
В результаті вузли позбавляються голосу і не беруть участі в голосуванні, хоча і продовжують працювати в кластері. Зверніть увагу, що тепер для обраних вузлів обидва параметри мають нульове значення. Це пов'язано з тим, динамічний вага вузла ніколи не встановлюється в 1 при цільовому вазі рівному 0.
Приклад 2. Dynamic Quorum
На відміну від ручного зниження ваги, динамічний кворум не чіпає цільової вага вузла, а працює тільки з динамічним вагою. Для наочності зупинимо 2 вузла кластера і подивимося, що стало з їх вагами. Оскільки після зупинки динамічний вага їх став дорівнює о, то вони більше не мають голосу. Однак їх цільової вага залишився колишнім, і як тільки вузли будуть включені, механізм динамічного кворуму тут же підвищить їх динамічний вага до цільового, вони отримають назад свої голоси і зможуть брати участь в голосуванні.
(Get-Cluster -Name Cluster1) .DynamicQuorum = 0
Приклад 3. Dynamic Witness
Перейдемо до демонстрації роботи динамічного свідка. В якості піддослідного використовуємо всі той же 4-х вузловий кластер з диском-свідком. Відкриємо консоль PowerShell і перевіримо стан і ваги кластерних вузлів командою:
Get-ClusterNode -Cluster Cluster1 | ft -a Name, State, NodeWeight, DynamicWeight
А для виведення ваги диска-свідка виконаємо команду:
Get-Cluster -Name Cluster1 | fl WitnessDynamicWeight
Як бачите, оскільки у нас парне число вузлів (4 вузли), свідок має вагу рівний 1.
Зупинимо один з вузлів і ще раз перевіримо їх стан. Оскільки тепер кількість активних вузлів непарне (3 вузла), то вага свідка стає зайвим і його значення автоматично встановлюється рівним 0.
Приклад 4. LowerQuorumPriorityNodeID
Беремо 4-х вузловий кластер і диск-свідок. Перевіряємо його параметри - тип кворуму Node and Disk Majority, ваги всіх вузлів і диска рівно 1, всього в наявності 5 голосів.
Відключаємо диск-свідок, роблячи його вага дорівнює 0. Ще раз перевіряємо параметри вузлів, і бачимо, що динамічний кворум перерахувала голоси і для збереження непарного їх кількості знизив динамічний вага першого вузла.
Припустимо нас не влаштовує такий стан речей, і ми хочемо, щоб в подібній ситуації завжди знижувався вага четвертого вузла. Для цього встановимо значення LowerQuorumPriorityNodeID рівним 4, виконавши команду:
(Get-Cluster -Name Cluster1) .LowerQuorumPriorityNodeID = 4
Примітка. Значення LowerQuorumPriorityNodeID це номер вузла (ID), якому треба знизити вагу. Одночасно можна вказати тільки один вузол.
Ще раз змоделюємо ситуацію з відключенням диска і подивимося параметри вузлів. Як бачите, тепер вага знижений у вузла з ID = 4, який вказаний у властивості LowerQuorumPriorityNodeID.
Таким чином, за допомогою LowerQuorumPriorityNodeID ми можемо більш гнучко управляти кластером і вибирати, яка з його частин в разі розриву зв'язку продовжить роботу, а яка буде зупинена.