| ユーザフォーラムで議論/質問 | マニュアル検索 | ハイライト | ハイライトオフ | ポータル | php spot |
書き込み確認MongoDB では、書き込みをデータベースに永続化させるための方法を選べます。 この方法のことを 書き込み確認 (Write Concern) と呼びます。 あらゆるエラーを無視することもできるし、 特定のサーバーへの書き込みを確認するまで書き込み完了と見なさないようにもできます。 書き込み操作 (MongoCollection::insert() や MongoCollection::update()、 MongoCollection::remove()) で Write Concern オプション ("w") を指定すると、ドライバはクエリを MongoDB に送信してから getLastError コマンド (GLE) に Write Concern オプションを付けて実行します。 これは Write Concern 条件を満たすかタイムアウト ("wtimeout" で指定でき、デフォルトは 10000 ミリ秒) に達するまでブロックします。 警告
getLastError コマンドがタイムアウトしたとしても、 ほとんどの場合はデータはプライマリサーバーに書き込まれており、 そのうちにすべてのセカンダリにレプリケートされるでしょう。 タイムアウトの発生要因として一番ありがちなのは、 書き込み確認を指定するときに現在使えるサーバー数よりも大きなサーバー数を指定したというものです。 書き込み確認を使っているときにレプリカセットのフェイルオーバーが発生すると、 ドライバは自動的にプライマリとの接続を切断して例外をスローし、 次の操作のときに新しいプライマリを探そうとします (新しいプライマリでもう一度操作をやり直すかそうしないかは、 アプリケーション側で決めないといけません)。 書き込み確認をしない (w=0) の場合にレプリカセットのフェイルオーバーが発生すると、 ドライバ側でそれを知る手段がありません。そのため、何も気づかずに操作を続け、 結果的に書き込みは失敗してしまいます。 MongoClient でのデフォルトの書き込み確認は 1 になっており、書き込み完了を確認するようになっています。
書き込み確認の使いかた書き込みを行うメソッド (MongoCollection::insert()、 MongoCollection::update()、 MongoCollection::remove() そして MongoCollection::batchInsert()) はどれも、オプションの引数で MongoDB サーバーに送るオプションを設定できます。 このオプション配列を使って、次の例のように書き込み確認を指定できます。 例1 書き込み操作での書き込み確認の指定
<?php 書き込み確認を操作ごとに option 引数で設定するだけでなく、 デフォルトの書き込み確認方法を設定することもできます。 最初の方法は、接続文字列 を使うものです。接続文字列には journal や w そして wTimeoutMS というオプションを指定できます。 例2 接続文字列での書き込み確認の指定
<?php ドライバのバージョン 1.5 以降では、 MongoDB::setWriteConcern() や MongoCollection::setWriteConcern() を呼んでデフォルトの書き込み確認方法を設定できるようになりました。その MongoDB や MongoCollection から作るすべての操作のデフォルトを設定できます。 例3 MongoDB::setWriteConcern および MongoCollection::setWriteConcern
<?php 確認なしの書き込みサーバー側で書き込み確認をしないようにすると、書き込み操作が極めて高速になります。 ただし、書き込みが本当に成功したのかどうかは確認できません。 いろんな理由で書き込みが失敗する可能性があります。 ネットワーク障害、データベースサーバーがダウンしている、 書き込み操作自体が無効 (system コレクションに書き込もうとしたり、 キーの重複エラーになったり) などが考えられます。 開発時には常に、確認付き書き込みを使うべきです (構文エラーや不正な操作、キーの重複などのうっかりミスを防ぐためです)。 実運用のときには、「あまり重要ではない」データについては確認なしで書き込んでもいいでしょう。 何が重要で何が重要でないかはアプリケーションによって異なりますが、一般的に 「重要でない」とみなされるのは、ユーザーが生成したのではない自動生成されるデータ (クリックトラッキング情報や GPS の位置情報など) です。 これらは秒間何千件ものレコードを受け取ることになります。 一連の確認なし書き込みの最期は、必ず確認付き書き込みで終えることを強く推奨します。 そのせいでパフォーマンスが大きく落ちることはないし、 何かエラーがあればそれを捕捉できるようになります。 例4 確認なしの書き込みの後に確認付き書き込みを続ける例
<?php 最後の書き込みで例外が発生すれば、データベースに何か問題が発生したことがわかります。 確認付き書き込みこの書き込みの場合、データベースが書き込み操作を受け付けたことを確認するまでは、 書き込みが成功したとはみなしません。書き込みが失敗した場合は MongoCursorException をスローして失敗の内容を説明します。 MongoClient のデフォルト設定は、確認付き書き込み (w=1) です。 レプリカセットの中で何台のメンバーに書き込み終える (レプリケートされる) まで書き込み完了とみなさないかを指定することもできます。 例5 確認付き書き込み
<?php 確認付き書き込みの設定には十分注意しましょう。もしレプリカセットのメンバー数が 5 の場合に確認付き書き込みの値を 4 にすると、レプリカセットのどれか一つのメンバーがメンテナンス中だったり 一時的にネットワーク障害が発生した場合などに、書き込み操作がブロックされてしまいます。 警告
確認付き書き込みの設定に文字列を渡すと、特別な意味になります (レプリカセットのタグセットとして扱います)。数字を指定するつもりで文字列を使ってしまう (array("w" => "1") など) ことが ない ように気をつけましょう。これはタグセット名として扱われてしまいます。 過半数の書き込み確認書き込み確認オプションとして、特別な文字列 majority を指定することができます。これは書き込み用におすすめの設定で、 大災害に巻き込まれないようにするために必須です。 この設定にすると、レプリカセットの過半数に書き込みが行き渡るまで成功したとみなさないので、 ありがちなあらゆる障害に対応できるようになります。 例6 過半数の確認付き書き込み
<?php ジャーナル書き込みレプリカセットへの接続時のデフォルトの書き込み確認は、 プライマリへの書き込みさえできていればよいというものです。 しかし、プライマリへの書き込みがディスクに反映されるまでには、 数百ミリ秒単位の遅延があります。 書き込みがディスクに記録されるまで成功とみなさないようにするには、 j オプションを指定します。 例7 確認付きジャーナル書き込み ジャーナルのフラッシュを強制します。
<?php 変更履歴
|
![]() |
各種マニュアル:
PHPマニュアル |
PEARマニュアル |
Smarty(英語)マニュアル |
PHP-GTKマニュアル |
「書き込み確認」をGoogle検索
|