MongoDB チュートリアルレプリケーション セットを使用する理由の概要
推奨(無料): MongoDB チュートリアル
レプリケーション セットを使用する理由
1. データのバックアップ
組み込みの mongo_dump/mongo_restore
ツールでもバックアップを実装できますが、結局のところ、レプリカ セットの自動同期バックアップほど便利ではありません。
2. 自動フェイルオーバー
レプリカ セットがデプロイされ、マスター ノードに障害が発生すると、クラスターはサービスの提供を継続するためにノードから新しいマスター ノードを自動的に選択します。そして、それはすべて自動的に、運用者や開発者に対して透過的に行われます。もちろん、障害が発生した場合は、手動でタイムリーに対処する必要があります。レプリカ セットに頼りすぎないでください。すべて障害が発生すると、息つく暇もありません。
3. 一部の特定のシナリオでの読み取りパフォーマンスの向上
デフォルトでは、読み取りと書き込みは両方ともマスター ノードでのみ実行できます。
MongoDB クライアントでサポートされる 5 つのレプリケーション セット読み取りオプションは次のとおりです。
出典: http://docs.mongetting.com/manual-zh/core/re...
スレーブ ノードでの読み取り操作は推奨されません、スレーブ ノード上のデータが最新のデータではない可能性があるためです (主な理由)。
スレーブ ノードで読み取り操作を実行するシナリオは非常に限られています。公式マニュアルには、適用可能なシナリオと、スレーブ ノードでの読み取り操作が推奨されない複数の理由が記載されています: http://docs.mongetting.com/manual-zh/ core /re...
私自身の意見をお話します: レプリカ セットは読み取りパフォーマンスを向上させるために存在するものではありません。いくつかのシナリオを除いて、スレーブ ノードで読み取り操作を実行することはお勧めできません。読み取りパフォーマンスを向上させたい場合は、インデックスとシャーディングを使用します。ちなみに、データサイズが大きくない場合はシャーディングを使用する必要はありません。当社のオンライン データベースには 2 億近くの単一コレクション レコードがあり、パフォーマンスは比較的良好です (もちろん、マシン構成は悪くなく、その上で 1 つの Redis と 1 つの MongoDB のみが実行されています)。
レプリカ セットのデプロイ方法
マニュアルを参照してください: http://docs.moncoming.com/manual-zh/tutoria...
プログラムで設定された MongoDB レプリケーションの自動フェイルオーバー機能を使用する方法
PHP mongo ドライバーを例に挙げます。
$client = new MongoClient('mongodb://192.168.1.2:27018,192.168.1.3:27019,192.168.1.4:27020', array('replicaSet' => 'rs0'));
この構成後、MongoDB サービスの 1 つだけがハングアップした場合、残りのノードが自動的に新しいマスター ノードを選択し、プログラムは正常に実行を続けることができます。選択プロセス中も、プログラムは例外をスローします。選択プロセスは高速ですが、プログラムの堅牢性のために、例外処理を考慮する必要があります。もちろん、新しいマスター ノードを選択できない場合は、MongoDB 全体が使用できなくなります。 (上記によれば、レプリカ セットの読み取りオプションが primaryPreferred
に設定されている場合。プライマリ ノードがなくてもスレーブ ノードがまだ利用可能な場合、読み取り操作はスレーブ ノードに転送されます。 、つまり、MongoDB レプリケーション全体が読み取り操作サービスも提供できるようになります)
実際、レプリカ セット名 'replicaSet' => 'rs0'
が指定されている場合でも、すべてのノード アドレスはリストされていません。有効なノード アドレスは 1 つだけです。ノード アドレスについては、mongo ドライバーがすべての有効なノードを自動的に取得します。$client->getHosts()
メソッドは、すべての有効なノードのアドレスを表示できます。
しかし、ノード アドレスを 1 つだけ書き込んだ場合、そのノードがたまたまダウンしていた場合、接続できなくなります。 私が推奨するのは、ノード アドレスの完全なリストを構成することだけです。
同期の原理は何ですか?
レプリカ セットを開いた後、oplog.rs# というセットが
local の下に生成されます。 ライブラリ ##、これは限定されたセット、つまりサイズが固定されています。データベースへのすべての書き込み操作がこのコレクションに記録されます。レプリケーション セット内のノードは、他のノードの oplog を読み取ることでデータ同期を実現します。
举个例子:
用客户端向主节点添加了 100 条记录,那么 oplog 中也会有这 100 条的 insert 记录。从节点通过获取主节点的 oplog,也执行这 100 条 oplog 记录。这样,从节点也就复制了主节点的数据,实现了同步。
需要说明的是:并不是从节点只能获取主节点的 oplog。
为了提高复制的效率,复制集中所有节点之间会互相进行心跳检测(通过ping)。每个节点都可以从任何其他节点上获取oplog。
还有,用一条语句批量删除 50 条记录,并不是在 oplog 中只记录一条数据,而是记录 50 条单条删除的记录。
oplog中的每一条操作,无论是执行一次还是多次执行,对数据集的影响结果是一样的,i.e 每条oplog中的操作都是幂等的。
什么情况下需要重新同步
在上一个问题中得知:oplog 大小是固定的,而且 oplog 里面的记录数不一定和节点中的数据量成正比。那么,新记录肯定会将前面的老记录给覆盖。
如果,有天一个从节点挂了,其他节点还在正常运行,继续有写操作,oplog 继续增长。而这个挂掉的节点一直不能从其他节点那里同步最新的 oplog 记录,当其他节点的 oplog 已经发生的覆盖。即使这个从节点后来恢复了正常,也不会和其他节点保持数据一致了。因为,覆盖的就永远回不来了。
那么,这个时候就得重新同步了。恩,回不去的就永远回不去了,再找个新的重新开始吧。(逃
如何重新同步
参见:复制集成员的重新同步
什么时候应该使用投票节点
当复制集中有偶数个节点时,应该再加一个投票节点,用于打破投票僵局。
比如:我线上共有3台服务器,其中1台是作为 Web 服务器;其余2台作为 DB 服务器,各部署了1个MongoDB节点,构成了2个节点的复制集。这个时候,我并没有多余的机器了。在这个情况下,如果任意一台 DB 服务器上的 MongoDB 挂了,那么另外一台的 MongoDB 必然变为 SECONDARY 节点,那么就意味着 MongoDB 是不可用的了。为了避免这种情况,提高服务的可用性,可以在 Web 服务器上部署一个投票节点。投票节点并不存储数据,因此不能升职为 PRIMARY 节点,它对于硬件资源要求很低,并不会对 Web 服务器上的其他程序产生太大影响。这种情况下,如果任意一台 DB 服务器挂了,另外一台服务器上的 MongoDB 将成为 PRIMARY 节点,此时 MongoDB 还是依旧对外提供服务的。乘此时机,赶紧排查出故障的那台服务器的原因,尽快恢复服务。
为了让投票节点可以占用更少的资源,可以在配置文件中添加以下几个配置项:
journal = false smallfiles = true noprealloc = true
主从复制
master-slave 复制架构已经不推荐使用了,建议使用 replica sets 复制集架构。
参见:http://docs.mongoing.com/manual-zh/core/ma...
以上がMongoDB レプリカ セットに関するいくつかの問題について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。