19

grails アプリケーションに StatsD データ コレクションを追加することを考えていて、既存のライブラリとコードを調べていると、スケーラブルな優れたソリューションとは何かについて少し混乱しています。質問を少し文脈に入れるために、私はオンラインゲームタイプのプロジェクトに取り組んでおり、ゲームエンジンとのユーザーのやり取りを自然に監視します。これらは、Xユーザーがウィンドウ内でやり取りを行う特定の瞬間に自然にクラスター化されます1 ~ 2 秒、10 ~ 20 秒の一時停止後に繰り返します。

これが、今日利用可能なオプションの私の分析です。

Etsy StatsD クライアントの例

https://github.com/etsy/statsd/blob/master/examples/StatsdClient.java

「おそらく機能する可能性がある最も単純なもの」の解決策として、このクラスをプロジェクトに取り込み、シングルトン インスタンスを Spring Bean としてインスタンス化し、それを直接使用することができました。しかし、grails-statsd プラグインがクライアント インスタンスのプールを作成することに気付いた後、このアプローチのスケーラビリティについて疑問に思うようになりました。

多くのスレッドが同時にイベントを送信しようとすると、doSendメソッドがボトルネックになる可能性があるようですが、私が理解しているように、UDP パケットを送信することの発火と忘却の性質により、これは迅速に発生し、巨大なオーバーヘッドを回避する必要があります。私たちは通常、ネットワーク接続に関連付けます。

grails-statsd プラグイン

https://github.com/charliek/grails-statsd/

withTimer注釈やメソッドなどの優れた機能を含む grails 用の StatsD プラグインを作成した人がいます。ただし、 への呼び出しでロケールを指定するなど、サンプル実装からのいくつかのバグ修正が実装に欠けていることがわかりますString.format。また、標準の Executor が同様の効果を達成できる場合、このためだけに apache commons-pool を引き込むこともあまり好きではありません。

java-statsd-クライアント

https://github.com/tim-group/java-statsd-client/

これは、独自の ExecutorService を維持することで非同期に動作する代替の純粋な Java ライブラリです。セットとサンプリングを含む StatsD API 全体をサポートしますが、スレッド プールとキュー サイズを構成するためのフックは提供しません。問題が発生した場合、監視などの重要ではないことについては、ヒープをいっぱいにする無限のキューを持つよりも、有限のキューと失われたイベントを好むと思います。

statsd プラグインを再生する

https://github.com/vznet/play-statsd/

現在、このコードを自分の grails プロジェクトで直接使用することはできませんが、どのように実装されているかを確認する価値はあると思いました。StatsdClient.scala一般的に、コードが非常にクリーンで読みやすいように構築されている方法が気に入っています。また、ロケールのバグがあるようですが、それ以外の機能は etsy サンプルで完全です。興味深いことに、私が理解していない scala マジックがない限り、StatsD に送信されるデータ ポイントごとに新しいソケットが作成されるようです。このアプローチはオブジェクト プールやエグゼキュータ スレッドの必要性を適切に回避しますが、非常に効率的であるとは思えません。可能な限り早くユーザーに返される要求スレッド内で DNS ルックアップを実行する可能性があります。

質問

  1. 他のすべての実装が並行性を処理するための別の戦略を実装しているように見えるという事実から判断すると、Etsy の例は本番環境で使用するには少し単純すぎると思いますか?
  2. ここでの私の分析は正しいように見えますか?
  3. java/groovy の statsd に他の人は何を使用していますか?

これまでのところ、commons-pool の依存関係を受け入れることができる限り、既存の最良のソリューションは grails プラグインのように見えますが、現在、日曜日に各実装の最良の部分を組み合わせた独自のバージョンを作成することを真剣に考えています。

4

3 に答える 3

9

java-statsd-clientの主要なコミッターとして、またこのライブラリを本番環境で使用している人物として、「ヒープをいっぱいにする無限のキューがある」という懸念を和らげたいと思います。

Etsy StatsD クライアントの例の分析で、「UDP パケットを送信する際のファイア アンド フォーゲットの性質により、これは迅速に行われ、通常ネットワーク接続に関連する巨大なオーバーヘッドを回避する必要がある」と述べたときに、ほぼそれを釘付けにしたと思います。

java-statsd-client が現在実装されている方法では、送信メッセージの大きなキューの構築に対する制約は、ファイア アンド フォーゲット UDP パケット送信の速度であると理解しています。私はこの分野の専門家ではありませんが、これがブロックされて無限のキューが構築される可能性がある方法については知りません。

最初に評価を行ったとき、java-statsd-client には未解決の問題がいくつかありました (たとえば、ロケール/文字エンコーディングのあいまいさ、およびサンプリング サポートの欠如)、これらは最近解決されました。残っているのは、ヒープがいっぱいになる本当のリスクがあるかどうかという問題です。この問題についてコミュニティから意見を聞きたいと思っています。また、問題があるというコンセンサスが得られた場合は、ライブラリに制限キューを導入することを喜んで検討したいと思います。

于 2014-07-28T15:39:14.463 に答える
1

これで1週間寝た後、既存のgrails StatsDプラグインを使用しようと思います。これの論理的根拠は、同時実行を処理するために Executor を使用して同様の効果を達成することはできますが、オブジェクト プールを使用しなくても、これは依然として単一のクライアント/ソケット インスタンスにバインドされ、理論的にはアプリケーションの明らかなボトルネックになるということです。したがって、とにかくプールが必要な場合は、他の誰かがすべてのハードワークを行ったプールを使用することもできます:)

于 2013-06-27T06:56:03.317 に答える
0

純粋な Java StatsDクライアントを同様に検索しているときにSLF4J 経由で StatsDに出会い、それをJava StatsD Clientと比較しましたが、これにはいくつかの問題がありました。ソースを読んだだけで、問題に関連するこの内訳を思いつきました。

編集:以下の表は、元の問題の多くが対処された java-statsd-client のバージョン 3.0.1 用に更新されました。

                          | | java-statsd-クライアント | statsd-over-slf4j
—————————————————————————+—————————————————————— ——————————————————————
メッセージはサンプリングをサポートします | はい | はい
—————————————————————————+—————————————————————— ——————————————————————
実際に行われたサンプリング | いいえ、発信者に任せます | はい、java.util.Random を使用
—————————————————————————+—————————————————————— ——————————————————————
ノンブロッキング実装ワーカー | 単一のデーモン スレッド | 単一のデーモン スレッド
—————————————————————————+—————————————————————— ——————————————————————
ノンブロッキング実装キュー | 無制限 | 呼び出し元指定の境界
—————————————————————————+—————————————————————— ——————————————————————
String.format ロケール | なし* | Locale.US
—————————————————————————+—————————————————————— ——————————————————————
メッセージバイトの文字セット | UTF-8** | デフォルト、オーバーライド可能

* ローカライズは適用されません
** これは StatsD が読み取る文字セットです
于 2014-05-07T22:22:29.443 に答える