時刻同期
このトピックでは、Milvusの時刻同期メカニズムについて紹介します。
概要
Milvusのイベントは一般的に2種類に分類されます:
データ定義言語 (DDL) イベント: コレクションの作成/削除、パーティションの作成/削除など。
データ操作言語(DML)イベント: 挿入、検索など。
DDLイベントであれDMLイベントであれ、どのイベントにも、このイベントがいつ発生したかを示すタイムスタンプが付けられます。
例えば、2人のユーザがMilvusのDMLイベントとDDLイベントを以下の表のような順序で開始したとします。
| タイムスタンプ | ユーザ 1 | ユーザ 2 |
|---|---|---|
| t0 | C0 という名前のコレクションを作成した。 | / |
| t2 | / | コレクションC0 を検索。 |
| t5 | データA1 をコレクションに挿入C0. | / |
| t7 | / | コレクションC0 を検索。 |
| t10 | データA2 をコレクションに挿入C0. | / |
| t12 | / | コレクションを検索C0 |
| t15 | コレクションからデータA1 を削除C0. | / |
| t17 | / | コレクションを検索C0 |
理想的には、ユーザー2は以下を見ることができる:
空のコレクション
C0att2.t7にあるデータA1。t12のデータA1とA2の両方。t17のデータA2のみ(この時点より前に、データA1がコレクションから削除されているため)。
この理想的なシナリオは、ノードが1つしかない場合には容易に達成できる。しかし、milvusは分散ベクタデータベースであり、異なるノードにおけるすべてのDMLおよびDDL操作が整然と保たれるようにするために、milvusは以下の2つの問題に対処する必要がある:
上の例の2人のユーザが異なるノードにいる場合、タイムクロックが異なります。例えば、ユーザ 2 がユーザ 1 より 24 時間遅れている場合、ユーザ 1 によるすべての操作は翌日までユーザ 2 には見えません。
ネットワークの待ち時間が発生することもあります。ユーザー2がコレクション
C0の検索をt17で行った場合、milvusはt17以前のすべての操作が正常に処理され、完了したことを保証できるはずです。t15での削除操作がネットワーク遅延のために遅延した場合、ユーザ 2 がt17で検索を行う際に、削除されたはずのデータA1をまだ見ることができる可能性が非常に高い。
そこでMilvusでは、この問題を解決するために時刻同期システム(timetick)を採用している。
タイムスタンプ・オラクル(TSO)
前節で述べた最初の問題を解決するために、Milvusは他の分散システム同様、タイムスタンプオラクル(TSO)サービスを提供している。つまり、Milvusのすべてのイベントはローカルクロックからではなく、TSOからのタイムスタンプで割り当てられなければならない。
TSOサービスはMilvusのルートコーディネーターによって提供される。クライアントは1つのタイムスタンプ割り当てリクエストで1つ以上のタイムスタンプを割り当てることができます。
TSOタイムスタンプは物理的な部分と論理的な部分で構成されるuint64 。下図はタイムスタンプのフォーマットを示している。
TSO_Timestamp。
図示されているように、先頭の46ビットは物理的な部分、すなわちミリ秒単位のUTC時間である。最後の18ビットは論理部分である。
時刻同期システム(timetick)
Milvusにおける時刻同期の仕組みについて、データ挿入操作を例に説明する。
プロキシはSDKからデータ挿入要求を受け取ると、主キーのハッシュ値に従って挿入メッセージを異なるメッセージストリーム(MsgStream)に分割する。
各挿入メッセージ(InsertMsg)はMsgStream に送信される前にタイムスタンプが割り当てられる。
MsgStream はメッセージ・キューのラッパーで、Milvus 2.0ではデフォルトでPulsarとなっています。
timesync_proxy_insert_msg
一般的な原則の1つは、MsgStream 、同じプロキシからのInsertMsgs のタイムスタンプはインクリメンタルでなければならないということである。しかし、異なるプロキシからのInsertMsgs のタイムスタンプにはそのようなルールはない。
以下の図は、MsgStream の中のInsertMsgs の例である。このスニペットには5つのInsertMsgs が含まれ、そのうちの3つはProxy1 からのもので、残りはProxy2 からのものである。
msgstream
Proxy1 からの3つのInsertMsgs のタイムスタンプはインクリメンタルであり、Proxy2 からの2つのInsertMsgs もインクリメンタルである。しかし、Proxy1 とProxy2 InsertMsgs の間には特定の順序はない。
考えられるシナリオとしては、Proxy2 からのタイムスタンプ110 のメッセージを読むときに、Proxy1 からのタイムスタンプ80 のメッセージがまだMsgStream の中にあることをMilvusが発見することです。したがって、Milvusは時間同期システムtimetickを導入し、MsgStream からのメッセージを読むときに、タイムスタンプ値の小さいメッセージはすべて消費されなければならないようにしています。
時間同期
上の図に示すように
各プロキシは、定期的(デフォルトでは200ミリ秒ごと)に、
MsgStreamの最新のInsertMsgの最大のタイムスタンプ値をroot coordに報告する。ルートコーデ ィックは、
InsertMsgsがどのプロキシに属していても、このMsgstreamの最小タイムスタンプ値を特定する。それからルートコーデ ィックは、この最小タイムスタンプをMsgstream。 このタイムスタンプはtimetickとも呼ばれる。コンシューマーコンポーネントがルートコー ディネートによって挿入されたタイムスティックを読むとき、コンシューマー コンポーネントは、より小さいタイムスタンプ値を持つすべての挿入メッセー ジが消費されたことを理解する。したがって、関連するリクエストは、オー ダーを中断することなく安全に実行できる。
以下の図は、タイムティックが挿入されたMsgstream の例である。
タイムティック
MsgStream は、出力メッセージがタイムスタンプの要件を満たすように、タイムティッ クに従ってメッセージをバッチ処理します。上の例では、 の を除くすべてのレコードを、 で消費する。これは、最新のタイムティックの後だからである。Proxy2 InsertMsgs Timestamp: 120
次へ
- タイムスタンプの概念について学ぶ。
- Milvusのデータ処理ワークフローについて学ぶ。