0

メトリクスを MySQL DB に保存し、RRDtool を使用して時系列グラフを描画する監視アプリがあります。DB のテーブルには、タイムスタンプ、RRDKeyID、および値の 3 つの列があります。次のようなデータを含むテーブルがあります。

ts1 | user2 | some_value
ts1 | user4 | some_value
ts1 | user5 | some_value
ts1 | user7 | some_value
ts2 | user1 | some_value
ts2 | user2 | some_value
ts2 | user3 | some_value
ts2 | user5 | some_value
ts2 | user8 | some_value
ts3 | user3 | some_value
ts3 | user4 | some_value
ts3 | user5 | some_value
ts3 | user7 | some_value
...

データは 1 分間隔で収集され、ユーザー (ご存じのとおり) はシステムに自由に接続してメトリックを生成するため、任意の時点でシステム内のユーザー数が合計よりも少なくなります。ユーザーの総数は約 1,000 人で、オンラインには常に数百人が存在します。つまり、メトリック テーブルには同じタイムスタンプを持つ行が数百行あることになります。グラフを生成するとき、キャンバスのサイズが小さすぎる、カラーパレットが限られている、凡例が長すぎるなどの理由でグラフが読めなくなるため、すべてのユーザーのシリーズを表示したくありません。メトリック値による上位 10 人のユーザーが個別に表示され、他のすべてのユーザーは 1 つの黒い領域に集約されます。これは私がそれを行う方法です:

:1: テーブルからトップ 10 を取得します。

select RRDKeyID, avg(value) as avg
from metric_table
where ts between 't1' and 't2'
group by RRDKeyID
order by avg desc
limit 10

:2: 次に、Perl で、すべてのユーザー (RRDKeyID) が独自の DEF を持つグラフを描画する RRDtool コマンドを生成しますが、SQL クエリ結果からのユーザーの DEF のみが直接プロットされ、残りはすべて集計されます。

CDEF:others=0,user11,ADDNAN,user12,ADDNAN,user13,ADDNAN,...,userN

そして"AREA:others#000000:OTHERS:STACK"グラフに表示されます。

現在、DB スキーマの変更により RRDtool が D3.js に置き換えられるアプリの次のバージョンに取り組んでいるため、top10 + その他のデータを生成する別の方法が必要です。データセットが非常に大きく、処理に多くの時間とCPUがかかる可能性があるため、生データをクライアントに送信してクライアント側で処理したくないので、サーバー側で処理したい. 次の形式で必要な結果を取得できる可能性があると思います。

 ts   | user   | value 
------+--------+-------
 t1   | u1     | v 
 t1+1 | u1     | v 
 t1+2 | u1     | v 
...
 t2   | u1     | v 
 t1   | u2     | v 
...
 t2   | u2     | v 
 t1   | u3     | v 
...
 t2   | u3     | v 
...
...
 t1   | u10    | v 
...
 t2   | u10    | v 
 t1   | others | v 
...
 t2   | others | v 

特定の時間範囲でユーザー名 (RRDKeyIDs) と avg(value) を選択するサブクエリがあるネストされたクエリを使用して、一度に (順序は重要ではありません)、最上位のクエリはユーザー名の結果を出力します。サブクエリの結果で見つかるか、他のものに追加します。この考えをSQLで表現する方法が正確にわからないので、誰かが解決策を提案してくれるとありがたいです.

4

2 に答える 2