Skip to content

Instantly share code, notes, and snippets.

@kmaehashi
Last active December 14, 2015 05:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmaehashi/5036511 to your computer and use it in GitHub Desktop.
Save kmaehashi/5036511 to your computer and use it in GitHub Desktop.
Jubatus RPC 関連の課題整理

RPC 関連の課題整理

  • Jubatus サーバのタイムアウト機能を使用したくないユーザ (--timeout 0) の救済方法を検討する

  • Jubatus サーバのタイムアウト機能を使用したいユーザの救済方法を検討する

    • サーバから timeout で自動切断(サーバから TCP FIN パケット送信)された後に RPC メソッドを呼んだ際に RPC エラーが起きるのが不親切 (C++/Python/Ruby のみ)
    • 解決策の案(松): サーバから受け取った FIN リクエストを正しくハンドリングするように修正 (msgpack-rpc ライブラリを修正)
      • msgpack-rpc-java はこうなっている (イベントループ周りっぱなし)
    • 解決策の案(梅): FIN は無視して、次回送信時のエラー回復処理に任せる (次の「タイムアウト・リトライなど、RPC のあるべき姿を検討する」で議論)
  • タイムアウト・リトライなど、RPC のあるべき姿を検討する

    • この gist で議論

RPC のあるべき姿

  • クライアント AP に対して、RPC 層は、ローカルメソッドを呼んでいるのと同じように振る舞いたい。
  • しかし、RPC 特有の異常状態は通知できなければならない。

MessagePack-RPC ライブラリはトランスポート非依存を目指した設計になっていることに留意する必要がある。

クライアント側で生じうる異常状態

  • トランスポート層 (* TCP などコネクション型トランスポートを前提に置いている)
    • 接続確立失敗
    • 送信中にエラー
      • サーバから切断
      • クライアント内部のエラー (バッファ溢れ等)
    • 非応答 (Jubatus ビジー)
    • 受信中にエラー
      • サーバから切断
      • クライアント内部のエラー (バッファ溢れ等)
  • MessagePack 層
    • アンマーシャル時のエラー (不正フォーマット)
  • MessagePack-RPC 層
    • 存在しないメソッド名 (RPC Error 1)
    • 引数型/引数の数が不一致 (RPC Error 2)
  • アプリケーション層
    • Jubatus サーバが投げる例外

クライアントの各異常状態ハンドリング(案)

外部から与えたいパラメタは [] で示す。

  • トランスポート層のエラー
    • 接続確立失敗
      • [接続リトライ回数] x ([接続タイムアウト時間] + [接続リトライ間隔]) だけ自動リトライし、超過したらクライアントにエラーを通知
    • 送信中にエラー
      • サーバから切断
        • クライアントにすぐにエラーを通知
      • クライアント内部のエラー (バッファ溢れ等)
        • 自動リトライ (write() が成功するまで繰り返すなど。 [送信リトライ回数], [送信リトライ間隔] を設ける) し、超過したらクライアントにエラーを通知
    • 応答待ち
      • [処理タイムアウト時間] だけ待ち、超過したらクライアントにエラーを通知 (Jubatus ビジー)
    • 受信中にエラー
      • クライアントにすぐにエラーを通知?
  • MessagePack 層のエラー
    • クライアントにエラーを通知
  • MessagePack-RPC 層のエラー
    • クライアントにエラーを通知
      • Jubatus クライアントと msgpack-rpc をつなぐ中間レイヤを用意して対処
  • アプリケーション層のエラー
    • クライアントにエラーを通知
      • Jubatus クライアントと msgpack-rpc をつなぐ中間レイヤを用意して対処

参考になりそうな他プロダクト

  • Apache Thrift
  • Apache Avro
@y-oda-oni-juba
Copy link

生じうる異常状態
送信中に接続断

[追加] サーバからの接続断 ( 例えば write() が EPIPE 返すなど ) に加え、クライアント内部のエラー ( ENOBUFS など ) もありうるという話だったかと。

各異常状態をどうハンドリングすべきか
送信中に接続断

write() 失敗時のリトライは、一度接続を切断してからのほうが安全だと思われます。

各異常状態をどうハンドリングすべきか

アプリケーションに報告するエラー(例外)の種別も共通化したいです

@suma
Copy link

suma commented Mar 1, 2013

これらの文書の主体は"RPCクライアント"を省略して書いている、と想定して問題ありませんか?

受信中にエラー

クライアントにすぐにエラーを通知
サーバ内のトランザクションは完了していることが保証されているので、自動リトライすべきでない

RPCではトランザクションの完了ということは保証できません。
RPCは、 サーバ内で処理が 実行されたか(実行中か、実行待ちか), 実行して、エラーが発生したか・正しく完了したか はクライアントがサーバから実行結果(レスポンス)を受け取るまで確認できないからです。

@kmaehashi
Copy link
Author

はい、RPC クライアントに関する議論です。

RPCではトランザクションの完了ということは保証できません。

ご指摘の通りでした。書きたかったのは、「サーバは、サーバ内の処理が完了(トランザクションの完遂ないしロールバック)後に応答を開始するので、1 byte でも読めればサーバ側で処理が進行中であることはない)」(※現状の実装の話)でした。

メソッド単位で @update, @analyze のアノテーションが付いているので、@analyze 要求が冪等な操作であることを前提にリトライの挙動を分けるのも面白いですね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment