監視メトリックの数およびデータトラフィックの量が増加するにつれて、監視システムはより複雑になり、より高い時間効率を必要とする。 このトピックでは、TairTSを使用して、同時実行性の高いワークロードを処理できる詳細なモニタリングシステムを構築する方法について説明します。
TairTSの概要
TairTSは、ApsaraDB for Redis Enhanced Edition (Tair) の社内モジュールであり、リアルタイムで並行性の高いクエリと書き込みをサポートします。 TairTSを使用すると、既存の時系列データを更新または追加したり、ゴリラ圧縮アルゴリズムと特定のストレージを使用してストレージコストを大幅に削減したり、skeyのtime to live (TTL) 設定を指定して、タイムウィンドウに基づいて自動的にロールしたりできます。 詳細については、「TS」をご参照ください。
詳細モニタリングの概要
上の図は、きめ細かい監視システムのアーキテクチャを示しています。 コンソールはきめ細かいモニタリング設定をアプリケーションに送信し、アプリケーションはMQテレメトリトランスポート (MQTT) プロトコルを使用してコレクターに設定を書き込みます。 コレクターは構成データを処理し、そのデータをTairデータベースに書き込みます。
高同時実行クエリ
同時実行性の高いクエリでは、TairTSはクエリのパフォーマンスを保証し、ダウンサンプリング、属性ベースのフィルタリング、バッチクエリ、マルチレベルのフィルタリングとクエリに複数の数値関数を使用するなどのシナリオでの集計操作をサポートします。 TairTSを使用すると、単一のコマンドを使用してバッチクエリと集計を実行し、ネットワークの相互作用を減らし、ミリ秒単位で応答を受け取り、問題をタイムリーに特定できます。
同時実行性の高い書き込み
アプリケーションのサイズが大きくなると、1つのコレクターでは同時実行性の高い書き込みを処理できない場合があります。 この問題を解決するために、TairTSでは、既存の時系列データを更新または追加して、複数のコレクターへの同時書き込みの精度を確保し、メモリ使用量を削減できます。 次のコードは、データを同時に書き込む方法の例を示しています。
import com.aliyun.tair.tairts.TairTs; import com.aliyun.tair.tairts.params.ExtsAggregationParams; import com.aliyun.tair.tairts.params.ExtsAttributesParams; import com.aliyun.tair.tairts.results.ExtsSkeyResult; import redis.clients.jedis.Jedis; public class test { protected static final String HOST = "127.0.0.1"; protected static final int PORT = 6379; public static void main(String[] args) { try { Jedis jedis = new Jedis(HOST, PORT, 2000 * 100); if (!"PONG".equals(jedis.ping())) { System.exit(-1); } TairTs tairTs = new TairTs(jedis); // Use the following code if you want to work with a cluster instance: //TairTsCluster tairTsCluster = new TairTsCluster(jedisCluster); String pkey = "cpu_load"; String skey1 = "app1"; long startTs = (System.currentTimeMillis() - 100000) / 1000 * 1000; long endTs = System.currentTimeMillis() / 1000 * 1000; String startTsStr = String.valueOf(startTs); String endTsStr = String.valueOf(endTs); tairTs.extsdel(pkey, skey1); long num = 5; // Concurrently update data in Collector A. for (int i = 0; i < num; i++) { double val = i; long ts = startTs + i*1000; String tsStr = String.valueOf(ts); ExtsAttributesParams params = new ExtsAttributesParams(); params.dataEt(1000000000); String addRet = tairTs.extsrawincr(pkey, skey1, tsStr, val, params); } ExtsAggregationParams paramsAgg = new ExtsAggregationParams(); paramsAgg.maxCountSize(10); paramsAgg.aggAvg(1000); System.out.println("Updated result of Collector A:"); ExtsSkeyResult rangeByteRet = tairTs.extsrange(pkey, skey1, startTsStr, endTsStr, paramsAgg); for (int i = 0; i < num; i++) { System.out.println(" ts: " + rangeByteRet.getDataPoints().get(i).getTs() + ", value: " + rangeByteRet.getDataPoints().get(i).getDoubleValue()); } // Concurrently update data in Collector B. for (int i = 0; i < num; i++) { double val = i; long ts = startTs + i*1000; String tsStr = String.valueOf(ts); ExtsAttributesParams params = new ExtsAttributesParams(); params.dataEt(1000000000); String addRet = tairTs.extsrawincr(pkey, skey1, tsStr, val, params); } System.out.println("Updated result of Collector B:"); rangeByteRet = tairTs.extsrange(pkey, skey1, startTsStr, endTsStr, paramsAgg); for (int i = 0; i < num; i++) { System.out.println(" ts: " + rangeByteRet.getDataPoints().get(i).getTs() + ", value: " + rangeByteRet.getDataPoints().get(i).getDoubleValue()); } } catch (Exception e) { e.printStackTrace(); } } }
Results:
Updated result of Collector A: ts: 1597049266000, value: 0.0 ts: 1597049267000, value: 1.0 ts: 1597049268000, value: 2.0 ts: 1597049269000, value: 3.0 ts: 1597049270000, value: 4.0 Updated result of Collector B: ts: 1597049266000, value: 0.0 ts: 1597049267000, value: 2.0 ts: 1597049268000, value: 4.0 ts: 1597049269000, value: 6.0 ts: 1597049270000, value: 8.0