Skip to content

Instantly share code, notes, and snippets.

@rimms
Last active December 29, 2015 14:59
Show Gist options
  • Save rimms/7687985 to your computer and use it in GitHub Desktop.
Save rimms/7687985 to your computer and use it in GitHub Desktop.
get_status拡張

get_status 取得情報追加 (案)

概要

追加項目分類

分類 想定用途
プロセス情報
* オペレーションの確認 (起動時の条件確認)
* プロセスの稼働情報
* 起動ユーザー
* pid など
システム情報
* メトリクス収集
* システム時刻 など
アプリケーション情報
* アプリケーションの確認
* バージョン など
稼働情報
* オペレーションの確認 (起動時の条件確認)
* 起動引数 など

追加項目一覧 (案)

プロセス情報

  • 起動時間(秒) uptime
    • プロセスが起動してからの秒数
    • 想定用途
      • プロセスの稼働情報 (どれくらい稼働しているのかを確認する)
      • オペレーションの確認 (いつ起動したかを後々確認する)
    • 補足
      • ps コマンドで確認可能な値であるが、複数のマシンをまたがっての確認は操作コストが高いため、提供を行う
      • redis でも提供
  • 起動時刻(エポック秒) start_time
    • プロセスが起動した際のエポック秒
    • 想定用途
      • uptime と同じ用途で利用する
    • 補足
      • ps コマンドで確認可能な値であるが、複数のマシンをまたがっての確認は操作コストが高いため、提供を行う
      • 用途から考えると、 uptime のみでも十分であるかもしれないが、 uptime の算出のために内部的に保持する値でもあるため、提供する
  • 起動ユーザー user
    • 動作しているプロセスのユーザー名
    • 想定用途
      • オペレーションの確認 (どのユーザーで実行したかを後々確認する)
    • 補足
      • ps コマンドで確認可能な値であるが、複数のマシンをまたがっての確認は操作コストが高いため、提供を行う
  • プロセスID pid
    • 動作しているプロセスのPID
    • 想定用途
      • Jubatus の場合、 IP_PORT がメンバシップを示す一意な情報であるため、本情報で何かを管理するようなケースはあまり想定されないが、プロセスを示す一意な情報という意味で、プロセス情報として一般的であり、取得するための実装コストも高くないため、提供する
    • 補足
      • ps コマンドで確認可能な値であるが、複数のマシンをまたがっての確認は操作コストが高いため、提供する
  • プログラムパス program_path
    • 動作しているプログラムのパス
    • 想定用途
      • オペレーションの確認 (どのプログラムを実行したかを後々確認する)
    • 補足
      • ps コマンドで確認可能な値であるが、複数のマシンをまたがって確認は操作コストが高いため、提供する
      • 現行の PROGNAME は、本エントリにより置き換わることを想定

システム情報

  • エポック秒 clock_time

    • get_status 受付時のシステム時刻(エポック秒)

    • 想定用途

      • メトリクス収集

        • get_status を複数回実行することにより、以下の様な形で単位時間あたりの処理数を把握することが可能 (性能を見るのではなく、システム組み込み時の使用状況を確認することが目的)

          QPS = (after_count - before_count) / (after_clock_time - before_clock_time)
          
      • 補足

        • kumofs では、上記方法で QPS を表示
        • クライアント側で取得することでも想定する用途を満たせるが、前述の uptime 算出のため内部的に保持することとなるため、提供する

アプリケーション情報

  • サーバープロセスの種類 type
    • classifier, recommender のような機械学習エンジンの種類
    • 想定用途
      • 機械学習エンジンの識別子として、各種外部ツールでハンドルすることを想定
    • 補足
      • PROGNAME, program_path でも識別可能であるが、機械学習エンジンを判断する最も短い単語(識別子)として提供する

稼働情報

現行で出力されているものからの差分のみを記載

Jubatus Proxy でも同様に 起動引数 の値を提供する

  • 稼働モード mode
    • 「スタンドアローンモード」か「分散モード」のいずれかの稼働モード
    • 想定用途
      • あまり想定はしづらいが、オペレーションの確認 (どのモードを実行したかを後々確認する)
    • 補足
      • is_standalone の bool 値 ではなく、人間が分かる値(文字列)として返却する
      • 「standalone mode」「multinode mode」のいずれかとする
      • 現行の is_standalone は、本エントリにより置き換わることを想定
  • ログ出力ディレクトリ logdir
    • 想定用途
      • オペレーションの確認 (どのディレクトリを指定して実行したかを後々確認する)
    • 補足
      • 起動引数で省略された場合は標準エラーへの出力する動きであるため、「/dev/stderr」 を返却する
  • ログレベル loglevel
    • 想定用途
      • オペレーションの確認 (どのレベルを指定して実行したかを後々確認する)
    • 補足
      • loglevel の int 値 ではなく、人間が分かる値(文字列)として返却する
  • 設定ファイルへのパス configpath
    • 想定用途
      • オペレーションの確認 (どのファイルを指定して実行したかを後々確認する)
    • 補足
      • ファイル名だけでは、実行時のファイルを特定できないので、相対パスを絶対パスへ変換する
      • 分散モードの場合は、ZooKeeper 上のノードパスを出力する
  • 最終 save 時刻 last_saved
    • 最後に save を実行した時刻 (エポック秒)
    • 想定用途
      • オペレーションの確認 (最後のモデル保存時刻を後々確認する)
  • 最終 save ファイル last_saved_path
    • 最後に save したファイルのパス
    • 想定用途
      • オペレーションの確認 (最後にモデルを保存したときのファイル名を後々確認する)
    • 補足
      • ファイル名 もしくは RPC引数の id だけでも良いが、 datadir を含めた絶対パスで提供し、 scp 等で移動を行いたいユーザーのコストを下げる
  • 最終 load 時刻 last_loaded
    • 最後に load を実行した時刻 (エポック秒)
    • 想定用途
      • オペレーションの確認 (最後のモデル読み込み時刻を後々確認する)
    • 補足
      • 起動時読み込みの場合も値を更新する
  • 最終 load ファイル last_loaded_path
    • 最後に load したファイルのパス
    • 想定用途
      • オペレーションの確認 (最後にモデルを読み込んだときのファイル名を後々確認する)
    • 補足
      • ファイル名 もしくは RPC引数の id だけでも良いが、 last_saved_path と統一し、 datadir を含めた絶対パスで提供る
      • 起動時読み込みの場合も値を更新する

その他 補足

  • レイテンシー、スループット など時間効率性の観点の値は、システム全体として確認すべきものとの立場から、現時点では、クライアントアプリケーション側を通じた一気通貫での性能監視を実施することを想定する
    • また、 Jubatus 側でクエリ毎のこれらの情報(レイテンシー、スループット)を保持するのは、性能面、リソース消費の面で高コストである

プロセス個別の追加情報

Jubatus Server

mixer

  • 想定用途
    • MIX の状況確認 (回数、前回の実行時刻)
    • mixer については、稼働状況 (どの 戦略 で起動したか) の確認
  • 補足
    • 分散構成で稼働時のみ出力する
    • 現行の linear_mixer. というプレフィックスは、 mixer が追加されることで mixer. のみに変更する。
戦略 取得情報 説明
linear mixer MIX 戦略を示す文字列 「linear_mixer」
mixer.count
MIX 回数
現行の countupdate_count に相当するので、値を変更
mixer.last_mixed
MIX の最終実行時間 (エポック秒)
現行の tick_time という key から適切な名前に変更
push系 mixer MIX 戦略を示す文字列 「random_mixer」など
mixer.count
MIX 回数
現行の countupdate_count に相当するので、値を変更
mixer.last_mixed
MIX の最終実行時間 (エポック秒)
現行の tick_time という key から適切な名前に変更
  • 仮実装では、起動引数の mixer を出力しているが、将来的には storage と同様に mixerクラス から返却するようにすると良い。(デフォルトの戦略が機械学習エンジンごとに変わる可能性があるため)

Jubatus Proxy

  • Proxy のへのリクエスト数 request_count

    • 想定用途

      • メトリクス情報

        • get_status を複数回実行することにより、以下の様な形で単位時間あたりの処理数を把握することが可能 (性能を見るのではなく、システム組み込み時の使用状況を確認することが目的)

          QPS = (after_request_count - before_request_count) / (after_clock_time - before_clock_time)
          
  • Proxy でのリクエスト転送数 forward_count

    • 想定用途
      • メトリクス情報 ( request_count と同様)

検討

スタンドアロンモード時に以下の分散モードオプション/情報を、返却するか否か。

  • zookeeper
  • name
  • mixer
  • join
  • interval_sec
  • interval_count
  • zookeeper_timeout
  • interconnect_timeout
  • use_cht
  • メリット
    • 処理分岐を作りこまなくて良い
  • デメリット
    • 不要な情報(空文字、プログラム上のでデフォルト値)が返却される
    • マニュアル(Website)に明示できていれば混乱は招かないと考える
  • 結論
    • 不要な情報が返却されることで混乱をきたさないよう、スタンドアロンモード時には分散モードの情報は返却しない。
      • 特に、 interval_count のようにプログラム上デフォルト値を持っているものについては、混乱を招く可能性があることを判断の基準とする。

TBD

  • Jubatus Server の更新リクエスト数( update_count )は JW_LOCK の数なので、IDL の @update アノテーションの RPCメソッド すべてでカウントアップされるので、メソッド単位等で粒度を細かくしたい。
    • メソッド単位にして、 Jubatus Server の分析リクエスト数( analyze_count )も欲しい。
  • 機械学習エンジンごとの個別要素 も見直しが必要。

仮実装

Jubatus Proxy

{'xx.xx.xx.xx_9199': {'PROGNAME': 'jubaclassifier_proxy',
                      'RSS': '3684',
                      'SHR': '3048',
                      'VERSION': '0.5.0',
                      'VIRT': '1228044',
                      'clock_time': '1385618434',
                      'forward_count': '3',
                      'interconnect_timeout': '10',
                      'logdir': '/dev/stderr',
                      'loglevel': 'INFO',
                      'pid': '31556',
                      'program_path': '/home/rimms/local/bin/jubaclassifier_proxy',
                      'request_count': '2',
                      'session_pool_expire': '60',
                      'session_pool_size': '0',
                      'start_time': '1385618430',
                      'threadnum': '16',
                      'timeout': '10',
                      'uptime': '4.00225',
                      'user': 'rimms',
                      'zookeeper': 'localhost:2181',
                      'zookeeper_timeout': '10'}}

Jubatus Server

分散構成

{'xx.xx.xx.xx_9188': {'PROGNAME': 'jubaclassifier',
                      'RSS': '6056',
                      'SHR': '5016',
                      'VERSION': '0.5.0',
                      'VIRT': '464240',
                      'clock_time': '1386137444',
                      'configpath': '/jubatus/config/classifier/mytest',
                      'datadir': '/tmp',
                      'diff_size': '0',
                      'interconnect_timeout': '10',
                      'interval_count': '512',
                      'interval_sec': '16',
                      'is_standalone': '0',
                      'join': 'false',
                      'last_loaded': '1386137444',
                      'last_loaded_path': '/tmp/xx.xx.xx.xx_9188_jubatus_test.jubatus',
                      'last_saved': '1386137444',
                      'last_saved_path': '/tmp/xx.xx.xx.xx_9188_jubatus_test.jubatus',
                      'logdir': '/dev/stderr',
                      'loglevel': 'INFO',
                      'mixer': 'linear_mixer',
                      'mixer.count': '3',
                      'mixer.last_mixed': '1386137443',
                      'mode': 'multinode mode',
                      'name': 'mytest',
                      'num_classes': '0',
                      'num_features': '0',
                      'pid': '7281',
                      'program_path': '/home/rimms/local/bin/jubaclassifier',
                      'start_time': '1386137395',
                      'storage': 'local_storage_mixture',
                      'threadnum': '2',
                      'timeout': '10',
                      'type': 'classifier',
                      'update_count': '2',
                      'uptime': '49.4929',
                      'use_cht': 'false',
                      'user': 'rimms',
                      'zookeeper': 'localhost:2181',
                      'zookeeper_timeout': '10'}}

スタンドアロン構成

{'xx.xx.xx.xx_9199': {'PROGNAME': 'jubaclassifier',
                      'RSS': '5472',
                      'SHR': '4668',
                      'VERSION': '0.5.0',
                      'VIRT': '243300',
                      'clock_time': '1386137534',
                      'configpath': '/home/rimms/work/github/rimms/jubatus/config/classifier/nherd.json',
                      'datadir': '/tmp',
                      'is_standalone': '1',
                      'last_loaded': '1386137534',
                      'last_loaded_path': '/tmp/xx.xx.xx.xx_9199_jubatus_test.jubatus',
                      'last_saved': '1386137534',
                      'last_saved_path': '/tmp/xx.xx.xx.xx_9199_jubatus_test.jubatus',
                      'logdir': '/dev/stderr',
                      'loglevel': 'INFO',
                      'mode': 'standalone mode',
                      'num_classes': '0',
                      'num_features': '0',
                      'pid': '7533',
                      'program_path': '/home/rimms/local/bin/jubaclassifier',
                      'start_time': '1386137531',
                      'storage': 'local_storage',
                      'threadnum': '2',
                      'timeout': '10',
                      'type': 'classifier',
                      'update_count': '2',
                      'uptime': '2.98811',
                      'user': 'rimms'}}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pprint import pprint
import msgpackrpc
from jubatus.classifier.client import Classifier
def get_proxy_status(host, port):
address = msgpackrpc.Address(host, port)
client = msgpackrpc.Client(address, timeout=10.0)
return client.call("get_proxy_status")
if __name__ == '__main__':
classifier = Classifier('localhost', 9199, 'mytest', 10.0)
print "--- start: proxy ---"
pprint(get_proxy_status('localhost' , 9199))
print "--- start: server ---"
pprint(classifier.get_status()) # Broadcast Proxy
print "--- after get_status: proxy ---"
# request count++, forward_count += number of node
pprint(get_proxy_status('localhost' , 9199))
classifier.save('test') # Broadcast Proxy
print "--- after save: proxy ---"
# request count++, forward_count += number of node
pprint(get_proxy_status('localhost' , 9199))
print "--- after save: server ---"
pprint(classifier.get_status()) # Broadcast Proxy
classifier.load('test') # Broadcast Proxy
print "--- after load: server ---"
pprint(classifier.get_status()) # Broadcast Proxy
classifier.get_config() # Random Proxy
# request count++, forward_count++
pprint(get_proxy_status('localhost' , 9199))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment