🐕

ひとりMongoDB University (2020年12月年末最終分 - Read Concern)

2020/12/31に公開

この記録は、アドベントカレンダー形式ではじめた、MongoDB Universityの学習コースの記録の続きになります!毎日ではありませんが、ある程度まとまったら上げます。

Chapter 2: Read Concerns (動画)

Write concern (書き込み確認) に対して、次は「読み込み確認」かな?

Read Concerns

Ref. https://docs.mongodb.com/manual/reference/read-concern/

The readConcern option allows you to control the consistency and isolation properties of the data read from replica sets and replica set shards.

Local

クラスタの中で最も最新のデータを返す。
ただ、その「最新」という意味に注意!
レプリカセット全体を通して整合性が保証された上での最新ではないので注意。

  • プライマリに書き込まれた最新のデータを返す(レプリカセットの他のノードに書き込まれているかどうかは保証されない)
  • セカンダリに書き込まれていない状態で、クライアントにデータを返すので、プライマリがクラッシュしたりセカンダリに書き込みができずにフェイルオーバーしてしまった場合は、MongoDB側のデータはロールバックしてしまう
  • localレベルでデータを取り出した場合、アプリケーション側と不整合が発生する可能性がある
  • localレベルはプライマリに対してのデフォルトのRead Concernの設定である
  • reads against secondaries if the reads are associated with causally consistent sessions.

causally consistent sessionsについてはちょっと理解が追いつかないので、ここではさっと流します....

Available

  • The query returns data from the instance with no guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back).
    • レプリカセットの過半数には書き込みが完了していない状態であっても、最新のデータを返す
    • 過半数ではないが1台でもセカンダリに書き込みが完了しているものなら、読み取り結果として返す
    • ロールバックする可能性があるので、障害時にはアプリケーション側と不整合が発生する可能性がある
  • レプリカセットのセカンダリメンバーに対して読み取りを行う場合の、デフォルトの設定

LocalとAvailableのRead Concernの一番の違いは、Sharded Cluster (シャーディングされたクラスタ)のコンテキストにあります。このあたりは、クラスタの章で扱うとのこと。
セカンダリに対しての読み取りについても、あとの章ーで細かく扱うみたい。

とりあえず、この時点では、Available Read Concern はSharded Clusterの場合の特別な動きだと認識していれば十分とのこと。

Majority

  • レプリカセットの過半数に対して書き込みが完了したデータのうちの最新のものを返す
    • たとえば3ノードのレプリカセット(プライマリ1つ、セカンダリ2つ)の場合は、プライマリとセカンダリ1つに書き込みが完了したものになる
  • このRead Concernのレベルが失敗するのはレアケース
    • 半分以上のノード(過半数を満たすレプリカセットのプライマリとセカンダリ)に書き込みが行われたあと、この書き込みが完了したノードがダウンしてしまい、残ったのは書き込みが完了していないノードだけ、というようなケースである
    • これもデプロイの仕方で変わってくる(限りなく抑えることはできそう)

LocalやAvailableに比べて、読み取り要求時点でのデータのロストが非常に少なく信頼性が高いと言える。
ただし、(他のプロセスで書き込まれている最新のデータやプライマリや一部のセカンダリにだけ反映されているデータ)は読み取れないため、最新のデータかどうかはトレードオフになってしまう。

linearizable

このRead ConcernはMongoDB 3.4から。
Ref. https://docs.mongodb.com/manual/reference/read-concern-linearizable/#readconcern.

  • The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results.
    • クエリの結果は、「読み取り操作の開始する前」にマジョリティに対して書き込みが完了したデータになる
    • また、読み取りと同時に書き込みが発生していたら、その書き込みが過半数のレプリカセットに書き込みが終わるまで処理を待つ形になる

どのRead Concernを採用する?

  • Latest & Fast (最新のデータかつ速い読み取りを重視)
    • Local or Available (ただし耐障害性は保証されない)
  • Fast & Safe (安全のデータかつ速い読み取りを重視)
    • Majority
  • Latest & Safe (安全かつ最新のデータの読み取りを重視)
    • linearizable
      • 他のRead Concernよりは待ちが発生する分遅い
      • ただし読み取りをする直前の書き込みを検知しその書き込みが終わるまで待って、そのデータを読み出せる
      • 最新の1ドキュメントのみ(複数のドキュメントは読み取れない)

Chapter 2: Read Concerns (クイズ)

Problem

Which of the following read concerns only return data from write operations that have been committed to a majority of nodes?
過半数のノードに書き込みが完了しているデータで最新のものを返してくれるのはどれ?

こたえ

  • Majority
  • Linearizable

※ Linearizableの場合は、読み取りのクエリが発行される直線に走っている書き込みが過半数まで反映されるのを待ってから、その結果を含めて返してくれます。(ただし、直前の1ドキュメントまでが対象です)

Chapter 2: Read Preferences (動画)

どのノードから優先して「読み取り」するかを決める設定みたい。
基本はプライマリだけど、セカンダリ(やもっとも近いもの)を指定できるみたい。
接続先情報はどうするのかな?

基本

  • Read Preferenceは、レプリカセットの特定のノードに対してアプリケーションからの読み取りを可能にするための設定
  • ただしこの設定はアプリケーション側(ドライバ側)での指定になるので、ドライバのドキュメントを参照すること

ここでやっとセカンダリノードを読み取りに利用できる設定が出てきた!
ただし、とにかくドライバ側での設定が必要。
種類は5つ

Primaly

  • プライマリノードからのみ読み取りを行う
  • プライマリノードがダウンしフェイルオーバーしたら、読み取りできない

PrimaryPreferred

  • プライマリノードを優先して読み取りを行う
  • プライマリノードがダウンしフェイルオーバーしたら、セカンダリもしくはフェイルオーバーしたプライマリから読み取る
  • データ書き込みのレイテンシ(遅延)を考慮すると、古いデータや上書きされる可能性のあるデータを読み取ってしまう可能性がある

Secondary

  • セカンダリノードからのみ読み取りを行う
  • セカンダリノードが全滅したら読み取りできない
  • データ書き込みのレイテンシ(遅延)を考慮すると、古いデータや上書きされる可能性のあるデータを読み取ってしまう可能性がある

SecondaryPreferred

  • セカンダリノードを優先するが、セカンダリノードがなくなってしまった場合はプライマリからの読み取りに切り替える
  • データ書き込みのレイテンシ(遅延)を考慮すると、古いデータや上書きされる可能性のあるデータを読み取ってしまう可能性がある

Nearlest

  • ネットワーク的(地理的)に一番近いところを指定する
  • アプリケーション側からの到達性は速いことが期待されるが、プライマリからの距離は遠い可能性がある
  • データ書き込みのレイテンシ(遅延)を考慮すると、古いデータや上書きされる可能性のあるデータを読み取ってしまう可能性がある

Chapter 2: Read Preferences (クイズ)

Problem

Which of the following read preference options may result in stale data?
古くなった(もしくはあとで上書きされてしまい役に立たなかったり最新でない)データを読み取ってしまう可能性があるものはどれ?

こたえ

  • primaryPreferred / secondary / secondaryPreferred / nearlest

Cgapter 2: Lab: Read Preferences (練習問題)

Problem

Consider a 3-node replica set that experiences a network outage.
Two of the three nodes were unreachable during the outage, leaving one node remaining.
Which of these readPreferences will allow you to read data from this node?

3ノード構成のレプリカセットで、ネットワーク障害が発生しました。
3つのうち2つが疎通が取れず、1ノードだけが残りました。
どのreadPreferencesを指定しておけばこういったケースでデータの読み取りが可能でしょうか?

こたえ

  • Primary以外!
    • secondary, secondaryPreferred, primaryPreferred, nearlest が該当!
    • nearlestはタグ指定で複数を指定できるみたい

間違えてしまった....。

ここまでの進捗

Chapter 2が終わりました...。
2章の練習問題(Grade Assignments) は、1発でのOKにはなかなかならず....!
Certificationの時は注意せねば。

M103コースは開始が12/6で、ここまでの61Stepに25日はかかっています。
1章に10日くらいかかっているので、1月10日までにChapter 3、 1月15日ごろでFinal Exam完走が目標です!

他の学習も並行したいところですが、無理しない...。

Discussion