save/load という既存機能に関わらず、状態書出/読込機能が必要とされるケースを列挙する。必ずしも、状態書出/読込で実現する必要はない。
- 「誤ったデータを学習させた」などのオペレーションミスへの対策
- チェックポイントの作成/チェックポイントへの復旧
- バックアップ/リカバリー(Jubatusの利用用途によって、粒度(要件)は様々ある)
- チェックポイントの作成/チェックポイントへの復旧(ある程度のデータ損失を許容出来るケース)
- 最新版の状態の保存、障害発生時点の状態への復旧(データ損失の範囲を最小限にする必要があるケース)
- 保存したファイルの集約、集約したファイルの配布
- 「あるシステムで学習させたデータを他のシステムへコピー」するなどの学習状態の再現
- システム環境、構成(クラスタ構成、IPアドレスなど)が異なる環境へのインポート
- チェックポイントの作成、チェックポイントへの復旧 が可能
- save/load 機能である程度実現
- 問題点1) システム状態を復元するための情報が揃っているか確認が必要
- 問題点2) 運用を考慮した機能になっているか確認が必要
- 異なる config でも load 可能になっている
- バージョンの異なる Jubatus でも load 可能になっている
- 異なる システム構成 でも load 可能となっている
- ファイルのタイムスタンプ か ログ でのみ取得時間を判別できない など...
- 問題点3) ノード間で一貫性が保たれていない save となる可能性がある(別途 一貫性/整合性について にてまとめる)
- ノード間で save の開始時間に時間差が生じた場合、ノードA での save 開始 から ノードB の save 開始までに ノードB update が行われると、ノードA と ノードB の状態には一貫性がない
- save/load 機能である程度実現
- 最新版のデータのバックアップ、発生時点の状態への復旧 が可能
- 未対応 : リバランシング機能 の実現を優先すべき、また、実現方法、実現範囲の検討 も必要
- スタンドアロン環境では、プロセス停止とともに最新のチェックポイントからの情報は失われる(Jubatus の外でクラスタ構成を形成している場合は、save/load で復旧が可能かもしれない)
- 分散環境でも、単体のノードで見た場合は、スタンドアロンと同じであるが、データ多重化、モデル情報の共有を行なっている
- モデルの状態は mix で共有しているが、mix は定期的な実行なので、Eventually Consistent な関係性
- cht によるデータ格納ノードの多重化を行なっているが、離脱したノードへ対する cht のリバランシング、多重化数の選択ができないなどの問題がある
- 未対応 : リバランシング機能 の実現を優先すべき、また、実現方法、実現範囲の検討 も必要
- システム環境、構成(クラスタ構成、IPアドレスなど)が異なる環境へのインポート
- 未対応 : リバランシング機能 の実現を優先すべき
- classifier や regression など、cht を利用していないアルゴリズムは、save したデータを load することできる
- IPアドレスを元にした cht であるため、cht を利用しているアルゴリズムでは、IPアドレスが異なる環境へ load することは不可能
- 異なるクラスタ構成への load も同様に、cht を利用している場合は、リバランシングが問題となるため、不可能
- 未対応 : リバランシング機能 の実現を優先すべき
- 保存したファイルの集約、集約したファイルの配布
- 未対応 : OSコマンドで代替可能なため、優先度は低い
update の頻度によらず、クラスタ全体で一貫性を保った状態書出を行うためには、クラスタ全体で書き込み(update, mix) がない状態で各ノードが save を開始しないと不可能である。
save を非同期で実行する場合であれ、クラスタ全体の update を瞬間的に止める必要があるが、Jubatus の場合、可用性を犠牲にした手段は許容されないと考える。
一般的に、分散システムでは 一貫性 と 可用性 はトレード・オフの関係にある言われる。可用性を維持しつつ、一貫性の欠落を最小限にする方法での状態書出が望まれる。
また、Jubatus では、mix の際に update された情報を破棄するような仕組みであり、コンセプトでもあるので、一貫性は保証していない。
この観点での実現は、より多くの利用ケースや要望を収集した後に、方向性の検討と実現をしていくこととする。
- バージョン付与によるノンブロッキングな方式
- 全ノードに get_version() を投げてモデルのバージョン番号取得
- 全ノードからバージョン番号を受け取ったら get_version_and_model() を投げてバージョン番号とモデルデータのペア取得
- 1回目 と 2回のバージョン の比較
- バージョンが全て一致したら一貫性のとれた状態
- バージョン番号の差の合計が許容範囲内に収まるか、特定の回数になるまで 2 と 3 を繰り返す
- update が少ないケースでは、一貫性のとれた状態の書出が可能
- update が多いケースでは、一貫性のある状態にならないが、利用用途に合わせて許容範囲を設定として提供する事が可能
- mix のタイミング
各ノードの mix完了 のタイミングで モデル を出力する
- liner_mixer では有効な手段
- Jubatus のコンセプトに従った一貫性であると言える
- liner_mixer 以外の mix戦略 では有効ではない可能性がある (要確認)
各々のノードで save させるのが得策なのかどうか
各々のノードで save する場合の問題点
- load する際に、クラスタ構成を意識する必要がある
- ノード間で重複データ (レプリカ))が生じるのでディスク容量が無駄
- ディスク起因で save に失敗するケースの考慮が必要
管理ノードを用意し、各ノードからモデルを集約し、管理ノードに単一ファイルを save するという案
- 台数を意識せずにloadできる
- 重複データは生じないので省ディスク容量
- サーバのローカルディスクの状態について考慮しなくてよい
- モデルファイルのハンドリングが容易
- NW 帯域のコストは高い
- 学習モデルデータ、本気出すとギガ級になる
実装コストを度外視するならHDFSのような抽象的な分散ストレージ層を作って共有するという案
- 実装コストが高い
本件は、Jubatus の方向性、コンセプト としてどうかという議論が必要であり、一旦ペンディング。
今後の開発方針、開発項目へ影響するため、将来的にどこを目指すかは決めておく必要がある
例)
- save/load 時には keeper で update をとめる。その間の update は keeper でキューイングする。
- 一貫性は保証しない。ノンブロッキングな方式を採用し、許容可能なバージョン差、リトライ数を設定可能とする。
- レプリケーションノードを用意し、レプリケーションノードから save させる。
- ジャーナル機能をもたせる。
状態書出/読込機能 が必要となるケースで、分散システム や Jubatus として不足している点からフォローできないケースが多い。
そういった不足している点を優先的に実現する必要がある。
問題になるのは、classifier, regression 以外のアルゴリズムで、storage に生データを保存しているようなアルゴリズム。
現状の機能としての save/load は「チェックポイントの作成、チェックポイントへの復旧」という点で、必要な機能であり、現状存在する問題は早期に解決しないと運用で問題が発生する可能性がある。
まずは、以下の 2点 について取り組むこととする。
- 問題点1) システム状態を復元するための情報が揃っているか確認が必要
- 問題点2) 運用を考慮した機能になっているか確認が必要
- 初期検討1: https://gist.github.com/9a4586bde31047ec96db
- 初期検討2: https://gist.github.com/6ae462fbe27aacb53e4c
- ノード追加削除時の各アルゴリズムで予想される挙動まとめ: https://gist.github.com/4563004
- 実行方法
- RPC リクエスト
- RPC メソッドには
name
とid
を指定する - 最も簡単な実行方法は、クライアントの利用する方法
- keeper で受け付けた場合は、broadcast する
- 保存先
- ローカルファイルシステム
-d, --datadir
で指定されたディレクトリ
- 保存ファイル名
ADDR_PORT_jubatus_ID.js
ID
は、メソッドの引数
- 保存対象
- mixable_holder へ登録された mixable0 を継承したクラスの状態
- 保存方法
- pficommon の archiver
- スレッドで write lock を取得する