Jubatus サーバは、メモリ上で機械学習に関するデータを管理しています。 メモリ上でデータを管理するという性質上、Jubatusサーバプロセスの終了とともに Jubatus 上のデータは失われます。
Jubatus では、予期せぬプロセスの終了や誤ったオペレーションに備え、バックアップとリカバリのための機能を提供しています。
現在、Jubatus では、以下の手段を提供しています。
Jubatus サーバは、メモリ上で機械学習に関するデータを管理しています。 メモリ上でデータを管理するという性質上、Jubatusサーバプロセスの終了とともに Jubatus 上のデータは失われます。
Jubatus では、予期せぬプロセスの終了や誤ったオペレーションに備え、バックアップとリカバリのための機能を提供しています。
現在、Jubatus では、以下の手段を提供しています。
Jubatus サーバの内部状態をファイルに保存し、そのファイルを読み込むことで、Jubatus サーバの内部状態を復元する機能です。
Jubatus では、この機能をクライアント向けに MessagePack-RPC インタフェースで提供しています。
現在、内部状態を保存した環境と異なる環境(クラスタ構成台数)への復元はサポートしていません。
Save は、クライアントからの save
という RPCメソッド の呼び出しにより Jubatus サーバの内部状態をファイル出力する機能です。
Save を実行中は、メモリ上の機械学習モデルへの書き込みの制限を行うため、いかなる RPC メソッド呼び出しもファイルの出力完了まで待たされることになります。
ファイルの出力先は、Jubatus サーバの起動オプション -d, --datadir
で指定することができ、標準では /tmp
が設定されます。
ファイルは、以下の命名規則に従ったファイル名で出力されます。すでに同じ名前のファイルが存在する場合、ファイルの上書きを行うため、save
メソッドの引数には十分に注意する必要があります。
${IPADDR}_${PORT}_${TYPE}_${ID}.jubatus
${IPADDR} | Jubatus サーバが RPCリクエストを受け付ける Ipv4 アドレス |
${PORT} | Jubatus サーバが RPCリクエストを受け付ける ポート番号 |
${TYPE} | 機械学習タスク名 (classifier, recommender, ...) |
${ID} | save メソッドの引数a-zA-Z0-9_- からなる 100文字
|
Save で出力されたファイルは、Jubatus のバージョンに依存する形式で出力され、互換性のあるバージョンの Jubatus でしか後述する Load を行うことができません。
現在の出力フォーマットは :doc:`savedata_format` を参照して下さい。
Load は、Save で作成されたファイルを読み込み、Jubatus サーバの内部状態をファイルに保存された状態へ復元する機能です。クライアントからの load
メソッドコールにより実行されます。
Load の実行中は、メモリ上の機械学習モデルへの書き込みの制限を行うため、Save と同様に、いかなる RPC メソッド呼び出しも処理完了まで待たされることになります。
ファイルの読込先は、Jubatus サーバの起動オプション -d, --datadir
で指定することができ、標準では /tmp
が設定されます。
save
メソッドでの引数で指定した ${ID}
を load
メソッドの引数に指定することで、読み込み対象のファイルを指定します。
ファイルの読み込み時、Jubatus サーバは以下のチェックを行い、バージョンの互換換性や復元対象の Jubatus サーバの内部状態との比較を行います。
現在の出力フォーマット と 比較内容 は :doc:`savedata_format` を参照して下さい。
Save により出力される情報は、大きく header
と system_data_container
と user_data_container
の 3のブロックに分けられています。
system_data_container
と user_data_container
は、それぞれ、機械学習タスクに依存しない情報 と 機械学習に依存する情報 を msgpack 形式で出力しており、フレームワークを利用して、あらたな機械学習タスクを実装する場合は、独自の user_data_container
を定義・実装する必要があります。
マルチバイト値はビッグエンディアンで読み書きを行います。
Item | Size | Description |
---|---|---|
header | 48 Byte | ヘッダー情報 |
system_data_container | 全機械学習タスクで共通の情報 [msgpack 形式] | |
user_data_container | 機械学習ごとに定義するコンテナ [msgpack 形式] |
header
は、ファイル自体の情報 を管理し、主にファイル読み込み時のチェックに利用します。
Item | Type | Size | Description |
---|---|---|---|
magic_number | char[8] | 8 Byte | マジックナンバー ('jubatus\0' 固定) |
format_version | uint64_t | 8 Byte | 出力フォーマットバージョン |
jubatus_version | uint32_t | 4 Byte | Jubatus のバージョン番号 (Major) |
uint32_t | 4 Byte | Jubatus のバージョン番号 (Minor) | |
uint32_t | 4 Byte | Jubatus のバージョン番号 (Maintenance) | |
crc32 | unit32_t | 4 Byte | crc32 を除くファイル全体の CRC32 値 |
system_data_size | uint64_t | 8 Byte | system_data_container の サイズ |
user_data_size | uint64_t | 8 Byte | user_data_container の サイズ |
magic_number
: 'jubatus\0' と一致することを確認します。format_version
: 動作している Jubatus サーバの format_version
と比較し、互換性があることを確認します。jubatus_version
: 動作している Jubatus サーバの jubatus_version
と比較し、互換性があることを確認します。crc32
: crc32
を除くエントリの CRC32 値と比較を行います。system_data_container
は、以下の通り 機械学習タスクに依存しない情報 を管理します。
将来的な拡張に備え、構造体として定義しています。
現時点では、動作している Jubatus サーバー に情報を取り込むことは行わず、動作している Jubatus サーバー の情報との確認のみに利用します。
Item | Type | Description |
---|---|---|
version | uint64_t | コンテナのバージョン番号 |
timestamp | time_t | タイムスタンプ(UNIX epoc time) |
type | string | 機械学習タスク名 |
id | string | save メソッドの引数 |
config | string | 設定ファイルの内容 |
version
: 動作している Jubatus サーバの system_data_container
の version と比較し、互換性があることを確認します。type
: 動作している Jubatus サーバの 機械学習タスク名 と一致していることを確認します。config
: 動作している Jubatus サーバの設定ファイルの内容と比較を行います。現時点では、セマンティクスレベルのチェックではなく、string の完全一致のみを確認します。一致していない場合は、警告ログを出力し、Load の処理を継続します。user_data_container
は、機械学習に依存する情報 を管理し、機械学習タスクごとに独自に定義を行います。
独自に定義する情報とは別に、以下の情報を共通で管理します。独自に定義した情報は動作中の Jubatus サーバー に取り込みを行います。
Item | Type | Description |
---|---|---|
version | uint64_t | コンテナのバージョン番号 |
既存の機械学習タスクの保存対象は以下に示すとおりです。
user_data_container
は継承関係が多い内部構造を出力するために、以下の様に msgpack 形式 の情報を続けて出力している。内部モジュール構成の見直し時に、これを簡単な定義を行えるようにしたい。[1] // version
[member, member, member] // model
以下のように 1つ の構造として出力できるようになれば、フレームワーク利用者の定義(実装)も容易にできると考える。
[
[1] // version
[member, member, member] // model
]
window_size
を保存しているが set_config されるので、必要ないstats_
を保存対象に含める必要があるglobal_id_generater
を保存すべきだが、zk 有り無しで分岐が必要。場合によっては、zk上の値も復元する必要もある。user_data_container
は、各機械学習タスクごとに実装します。
以下に、実装例を示します。
class task_data : public user_data_container {
// 保存対象とするメンバの定義
target model;
target fv_converter;
// コンテナのバージョン番号を定義する
uint64_t current_version() const {
return 1;
}
// msgpack 形式への変換
void pack(msgpack::sbuffer& buf) const;
// msgpack 形式からの変換
void unpack(msgpack::unpacker& unpacker);
}
class task {
task_data data_;
}
user_data_.reset(&data_);
void task_data::pack(msgpack::sbuffer& buf) const {
msgpack::pack(buf, *this);
model.pack(buf);
fv_converter.pack(buf);
}
void classifier_data::unpack(msgpack::unpacker& unpacker) {
msgpack::unpacked msg;
unpacker.next(&msg);
model.unpack(msg);
unpacker.next(&msg);
fv_converter.unpack(msg);
}
void pack(msgpack::sbuffer& buf) const {
msgpack::pack(buf, *this);
}
void unpack(msgpack::unpacked& msg) {
msg.get().convert(this);
}
SaveData Format
データ構造の表に型情報が欲しいです (unsigned?)。
jubatus_version: 動作している Jubatus サーバの jubatus_version と比較し、互換性があることを確認します。
互換性は、ファイルフォーマット + 構造体のバージョン情報の比較で担保されるのでは?
config: 動作している Jubatus サーバの設定ファイルの内容と比較を行います。現時点では、セマンティクスレベルのチェックではなく、string の完全一致のみを確認します。一致していない場合は、警告ログを出力し、Load の処理を継続します。
意見が分かれそうですが、set_config廃止の経緯も踏まえると、デフォルト安全側に倒したい気もします。
Define User Data Container
簡単に書けるマクロを用意したいですね。
crc32
:crc32
を除くファイル全体の CRC32 値
この CRC32 値は, crc32
フィールドの部分が切り詰められた仮データ,言い換えると, jubatus_version
の直後に system_data_size
が来る,本来のデータより 4 byte だけ短いような仮データに対する CRC32 値という認識でよいでしょうか?
crc32
フィールドが 0 で埋められた,本来のデータと同じ長さの仮データに対する CRC32 値という解釈も 不可能ではないので,一応 確認まで.
とりあえず読み込み時に限り id として空文字列が渡された場合, id をチェックしないことにしたいと思います.
その場合,書き込み時に id として空文字列が渡された場合には,例外を投げるようにするのが良いと思いますが,どうでしょうか
crc32
オフラインかチャットで返答済みだと思いますが(ここにコメントしてなかったので遅れましたが書きます)、切り詰められた仮データで良いと思います。
id
読み・書き(framework::server_save
, framework::saver_load
)共にその振る舞いで良いと思います。
id
ですが、起動時ロード や ファイル名を変更して別の場所に保管しておくというようなバックアップ運用 を想定すると、ファイル名の id
(引数の id
) と ファイル内の id
をチェックすることで、利用ケースが限られてしまうのではと思います。
そもそも id
をファイル内に含める必要性があったかという話もあるんですが、現状は、メタな情報としてチェックには利用しないという扱いで良いと思います。
あ、申し訳ないです。一部勘違いしていました。訂正します。
「空文字 = 起動時ロード」を想定しているということですね。
ファイル名を変更して別の場所に保管しておくというようなバックアップ運用
これはあくまで、想定される運用の話なので、実際にはどう運用されるかはこちらで決めて良い話ですので「ファイル名を変更するとloadできなくなる」という仕様で縛って良いと思います。
ですので、 https://gist.github.com/rimms/5343003/#comment-930271 の振る舞いで良いと思います。
stat の保存対象に stats_ を追加 (See. jubatus/jubatus#320)