9
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

Organization

Corosync の quorum の設定

CentOS 7 のリポジトリからサクッとインストールできる下記で試しています。

  • corosync-2.3.4-7.el7_2.1
  • pacemaker-1.1.13-10.el7_2.2
  • resource-agents-3.9.5-54.el7_2.9

man corosync.confman votequorum から理解出来た部分をそれっぽく意訳しています。

corosync.conf(5)

man corosync.conf 曰く。

quorum セクションの provider ディレクティブで quorum アルゴリズムを指定できる。今のところ corosync_votequorum だけが指定できる。

quorum {
    provider: corosync_votequorum
}

詳細は votequorum(5) を参照。

votequorum(5)

man votequorum 曰く。

クラスタノードの過半数がどれだけであるかを知るために、クラスタの総票数を quorum セクションの expected_votes で指定するか、nodelist セクションでノードを一覧しておく必要がある。どちらも無い場合は votequorum は無効になる。両方が指定された場合は quorum.expected_votesnodelist から計算された値を上書きする。

例えば、8 ノードクラスタでは次のように。

quorum { 
    provider: corosync_votequorum
    expected_votes: 8
}

3 ノードクラスタで nodelist セクションを書くのであれば次のように。

quorum { 
    provider: corosync_votequorum
} 

nodelist {
    node {
        ring0_addr: 192.168.1.1
    }
    node {
        ring0_addr: 192.168.1.2
    }
    node {
        ring0_addr: 192.168.1.3
    }
}

two_node

two_node: 1 を指定すると 2 ノードクラスタが可能になる。

quorum {
    provider: corosync_votequorum
    expected_votes: 2
    two_node: 1
}

または、

quorum {
    provider: corosync_votequorum
    two_node: 1
}

nodelist {
    node {
        ring0_addr: 192.168.1.1
    }
    node {
        ring0_addr: 192.168.1.2
    }
}

2 ノードクラスタは特別な配慮が必要なユースケース。標準的な 2 ノードクラスタでは各ノードが 1 票を持つのでクラスタ内の合計は 2 票。単純に過半数を計算すると votes * 50% + 1 で 2 となる。これは、過半数を得るためには常に両方のノードが生きていないことを意味する。

two_node: 1 を有効にするとクオラムは人為的に? 1 に設定される。

two_node: 1 を設定すると自動的に wait_for_all: 1 が設定される。wait_for_all: 0 を明示的に指定することで上書きすることができる。

2 より多いノードがクラスタに参加した場合 two_node は自動的に無効になる。

wait_for_all

wait_for_all: 0 の場合(デフォルト)、過半数の投票が集まるとその他のノードの参加を待たずにクラスタは開始する。

例えば、8 ノードクラスタの場合、過半数は 5 票なので 5 ノードがクラスタに参加すると残りの 3 ノードを待たずにクラスタは開始する。

wait_for_all: 1 にすると、すべてのノードが少なくとも 1 回は揃うまで開始が待たされる。

quorum {
    provider: corosync_votequorum
    expected_votes: 8
    wait_for_all: 1
}

last_man_standing

通常、クラスタは過半数の票が集まらなければ停止するが、last_man_standing を設定すると、クラスタの総票数とクオラムが動的に再計算されるようになる。last_man_standing_window は再計算されるまでのミリ秒単位の時間。

quorum {
    provider: corosync_votequorum
    expected_votes: 8
    last_man_standing: 1
    last_man_standing_window: 20000
}

例えば、8 ノードクラスタの場合、expected_votes は 8 で quorum は 5 なので 3 台までの障害しか許容できないが、last_man_standing を設定すると、次のように動的に expected_votesquorum が計算されるようになる。

  1. クラスタが 8 ノードで稼働している
    • expected_votes: 8 / quorum: 5
  2. 3 ノードが死んで残り 5 ノードになった
  3. last_man_standing_window の時間が経過後に expected_votesquorum が再計算される
    • expected_votes: 5 / quorum: 3
  4. さらに 2 ノードが死んで残り 3 ノードになった
  5. last_man_standing_window の時間が経過後に expected_votesquorum が再計算される
    • expected_votes: 3 / quorum: 2
  6. さらに 1 ノードが死んで残り 2 ノードになった
  7. last_man_standing_window の時間が経過後に expected_votesquorum が再計算される
    • expected_votes: 2 / quorum: 2

ここから、さらに 1 ノードクラスタにダウングレードするためには後述の auto_tie_breaker も設定する必要がある。

auto_tie_breaker

一般的な動作ではクラスタは「50% - 1」ノードまでの故障を許容することができる(各ノードが 1 票を持っている場合)。

auto_tie_breaker を有効にすると、クラスタは 50% ノードまでの故障を許容できるようになる。

auto_tie_breaker のいデフォルトでは、クラスタが 50% のノードに分断されたときに最も小さいノード ID を持つセットが過半数に達しているとみなされる。

例えば、8 ノードクラスタで下記の 2 つのセットに分断された場合、

  • A = {1, 3, 5, 7}
  • B = {2, 4, 6, 8}

もっとも小さいノード ID は 1 であるため、A が過半数に達しているとみなされる。

auto_tie_breaker_node を指定することで条件を変更することができる。指定できる値は lowest|highest|<list of node IDs> のいずれかで、lowesthighest はそのままの意味、ノードの ID を指定した場合はそのノードのあるセットがクオラムに達する。ノード ID を空白区切りで複数指定した場合はクラスタに残っているノードの中で一番左の ID を持つセットがクオラムに達する。

quorum {
    provider: corosync_votequorum
    expected_votes: 8
    auto_tie_breaker: 1
    auto_tie_breaker_node: 1 3 5 7
}

allow_downscale

この機能は不完全で、現在サポートされていない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?