Hatena::ブログ(Diary)

matsukazの日記 このページをアンテナに追加 RSSフィード

2011-07-11

MongoDBでReplicaSetにメンバーを追加/削除する方法と、その注意点

MongoDBで、ReplicaSetにメンバーを追加/削除する方法は、Adding a New Set Memberにある通りです。

rs.add("node1:27018");

で追加したり、

rs.remove("node1:27018");

で削除したり。

追加する際は

  1. 既存データを物理的にコピーしてきて戻す方法
  2. カラの状態から同期を取る方法

があります。

1000万件程度であれば、1.でも数分で終わる模様。数億件以上ある場合は、2.で戻した方が作業が早いかもしれません。

注意点1

その際に気をつける点は、local.*のファイルはコピーしてこないこと。local以外のコレクションに対応するファイルだけコピーしてきて、あとは起動後にrs.add()すればOKです。local.*がいると、データの整合が取れなくなって「still initiating」って状態で止まってしまいます。これやっちゃってハマりました・・・orz

ちなみに、その場合でも一度サーバを止めてlocal.*ファイルを全部削除して起動し直せばOKみたいです。

注意点2

あともう一つ注意する点は、メンバーのvotesの数の合計が偶数にならないこと。MongoDB sharding and replication with (only) 3 servers - Part 2: One Replica-Setに以下のように説明されています。

The members of a set will elect their master just as well as we do with our politicians. The master has to get more than half of the available votes. Problem: Imagine a set with four members. What happens if two vote for node A to get master and the two others vote for node B?

Neither A nor B will get master, because no node got more than half of the available votes.

Therefore the number of votes in a replica set has to be odd-numbered. You can reach this by easily add one more node as a new slave to the set - simultaneously increasing database availability. But if you don't have the resources for an additional node, there are two other possibilities:

1. Add an arbiter, which is a mongod process and a member of the set, but only exists to solve majority problems (http://www.mongodb.org/display/DOCS/Adding+an+Arbiter)

2. Change the number of votes the members have, so the number is unequal.

PRIMARYになるためには、全体のvotes数の過半数より多い票を獲得しなければならないため、votes数が偶数になってしまうと、残りのvotes数が半数になった時点でPRIMARYがいなくなってしまいます。例えば、

ノードvotes
node11
node21
node31
node41

となると、上記のうち2台が死んだ時点でvotesの数が過半数の2となってしまい、PRIMARYがいなくなってしまいます。PRIMARYがいなくなるということは、ReplicaSetの構成変更も出来なくなるので、死んだ2台のうちいずれかを起動するまでは何も出来ません。

ノードvotes
node12
node21
node31
node41

であれば、仮にnode3/node4が死んでも、残りのvotes数は3なので、node1/node2のいずれかはPRIMARYでいられます(node1が死んでしまうと、あと1台しか死ぬことは出来ませんが)。この辺はArbiterで調整したり。

自分は、

ノードvotes
node11
node21
node31

に対して

ノードvotes
node11
node21
node31
node41
node51
node61

と新たに3つのノードを追加したところ、追加した3つが前述した理由で起動できない状態となっていたため、既存ノードからPRIMARYがいなくなってしまいました。

ノードvotesState
node11SECONDARY
node21SECONDARY
node31SECONDARY
node41still initiating
node51still initiating
node61still initiating

追加した3つのノードを起動することも出来ず、PRIMARYがいないのでrs.remove()でノードを消すこともできず、完全に詰んだ状態に・・・orz

local.*を消せばよかったみたいですが、このときには気付かなかったので、node1/node2/node3を取得していたバックアップから復元して対応しました。

yoshidayoshida 2011/08/10 14:27 勉強になりました。
ありがとうございます。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

リンク元