はじめに
Amazon Managed Grafanaを使った時系列データのクエリの実装例が少なかったので記事を書いてみました。
-
以前、Grafanaは少しだけ記事にしました。
-
最近OpenSearchがニューラル検索に対応し、「リアルタイム可視化」という点でGrafanaとOpenSearchの棲み分けの方向性が明確になってきたように思います。
- https://aws.amazon.com/jp/about-aws/whats-new/2023/11/amazon-opensearch-neural-search/
- 個人的には単純なリアルタイム可視化であればGrafanaがよいのではと思います。
構成
各サービスのデータ連携は、すべてVPC内でセキュアに通信するようにしてみます。
Services | Version | note |
---|---|---|
Managed Grafana | 9.4 | in VPC |
RDS(MySQL) | 8.0.33 | in VPC |
Lambda | Python 3.10 | in VPC |
構築
RDS(MySQL)
-
詳細は省きます。
-
MySQL を RDSで構築し、VPCに足を出しています。
-
また、自宅からつなげるためパブリックアクセス可能とし、サブネットのルートテーブルにもインターネットゲートウェイが設定されています。
-
SecurityGroupは、同一VPCからのインバウンドをすべて許容しています。
-
起動後、適当なテーブルを作成しておきます。
-
idのほかに、int型のカラム(author_id)と、timestamp型のカラム(time)を作っておきます。
- ※mysqlの場合、timestamp型(「2038-01-19」まで)よりもdatetime型(「9999-12-31」まで)のほうがよいです。今回はあくまでテストなのでtimestamp型を使っています。
CREATE TABLE `posts` (
`id` int NOT NULL,
`author_id` int NOT NULL,
`time` timestamp NOT NULL,
PRIMARY KEY (`id`)
);
Lambda
まずPython3.10での関数を作成します。
IAMロールは、今回は一時的なテストなのでAdministratorAccessをつけちゃってますが、基本的にはAWSLambdaVPCAccessExecutionRole、AWSLambdaBasicExecutionRole があればよいと思います。
VPCは、先程RDSを展開したのと同じサブネットに足を出しておきます。
MySQLのコネクタをLambdaレイヤー化するのが面倒だったので、素晴らしい有志が作成した公開レイヤーを利用します。
上記サイトから「deployments」を選択し、
現在Lambdaで使える3.10系を選択し、
東京リージョンのhtmlを選択し、
mysql-connector-pythonのARN欄をコピーします。
Lambdaのレイヤーを追加し、先程のARNを入力します。
追加できました。
- Lambdaコードはこんな感じで雑に作ります。
- RDSのパスワード等は直書きしていますので、本格的に使う場合はLambda環境変数なり、SecretsManagerなりに保存してください。
import json
import mysql.connector as mydb
import time
import datetime
import random
def lambda_handler(event, context):
# コネクションの作成
conn = mydb.connect(
host='database-1.**********.ap-northeast-1.rds.amazonaws.com',
port='3306',
user='admin',
password='**********',
database='mydb'
)
print(conn.is_connected())
# カーソルの準備
cur = conn.cursor()
# レコードの生成とインサート
# idは重複しない値として、適当に現在のUNIXタイムを入れておきます。
id = int(time.time())
# author_idは、1~500までの疑似乱数を入れておきます。
author_id = random.randint(1, 500)
# timstamp型に入れる値として、現在のdatetimeを入れておきます。
dt_now = datetime.datetime.now()
# DBにインサートします。
cur.execute("INSERT INTO posts VALUES (%s,%s,%s)",(id,author_id,dt_now))
# デバッグ用コード
# Lambda上のデバッグ用に、selectの結果を標準出力しておきます。
cur.execute("select * from posts where id = '%s'",(id, ))
rows = cur.fetchall()
for row in rows:
print(row)
# コミット
conn.commit()
# 後始末
cur.close()
conn.close()
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
最後にEventBridgeで1分毎のトリガーを設定しておきます。
Managed Grafana
初期設定方法は私の以下の記事などを参考にしてください。
リンク先の「データソースと通知チャネル」は今回は設定不要です。
https://qiita.com/jnit/items/49f4954f8a7667e4a440#%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A
ワークスペースの設定
作成済みのワークスペースを選択し、VPCに足を出しておきます。
「ネットワークアクセスコントロール」で設定が可能です。
SecurityGroupは、適当に同一VPCからすべてのトラフィックを許可するSGを設定しました。
データソースの設定
まず、Grafanaのユーザが管理者権限であるか確認します。データソースの追加は管理者権限である必要があります。
マネジメントコンソールの Managed Grafanaから「認証」「ユーザーとユーザーグループの設定」を選択します。
AWS SSOなどからManaged Grafanaにログインします。
「Home」から「Data sources」を選択します。
※なお、「Administration」メニューは、Grafana上のユーザが管理者権限を持っている場合に表示されます。
RDSのドメイン名とポート名をコロンで繋げて入力し、ご自身のデータベース名やユーザ名などを入力します。
ダッシュボードの作成
「Add a new panel」を選択します。
最初はGrafanaのサンプルが表示されていますので、「Data source」から先程作成したMySQLデータソースを選択します。
プルダウンでスキーマやテーブル、カラムなども選べますが、やりやすいように「Code」をクリックします。
SQLクエリ入力欄に以下のように入力します。
SELECT
time,
author_id
FROM
mydb.posts
order by time asc;
- このSQL文はあくまで例です。
- SELECTしたカラムがグラフに反映されます。
- 時間を持つカラムは order byしておく必要があります。
- 時系列グラフにする場合は、SELECTするカラムに以下のいずれかを含めてください。
- datetime(or timestamp)型
- Unix エポックを秒単位で表す数値データ型
- 実際には、頻繁に上記のSQLクエリが発行されるので、WHERE句で直近1ヶ月分に絞ったり、適切にインデックスを設定しておくなど、DBへの負荷を減らすための考慮が必要になります。
- その他クエリの例などは以下を参考にしてください。
クエリ入力後、「Run query」を押します。するとGrafanaが自動的に時系列グラフ「Time series」として認識し、上部にグラフが表示されます。問題なければ「Apply」を選択します。
するとダッシュボードに先程のパネルが追加されます。表示範囲については、お好みの範囲に変更してください。
また、タイムゾーンがお住まいの地域に合っているか確認してください。
Grafanaの画面の更新間隔をお好みに応じて変更してください。この例では5秒に設定しています。
パネルを編集する場合は、パネルの三点リーダから「Edit」を選びます。
これで、簡易的ですがリアルタイムデータの可視化ができました。
おわりに
-
ダッシュボードの作り方について
- Grafanaは、やはりダッシュボードを作成する際のインターフェースが少しとっつきにくく、本例のようにSQL文で直接書いたほうが(私にとっては)分かりやすいです。
- 細かい使い方はAWS側の公式サイトにはあまり載っていないので、grafana本家のサイトを見る必要があります。
- Grafanaは、やはりダッシュボードを作成する際のインターフェースが少しとっつきにくく、本例のようにSQL文で直接書いたほうが(私にとっては)分かりやすいです。
-
サポートについて
- AWSが提供する Managed Grafanaには、以下の2つのレイヤーがあります。
- (1). Amazon Managed Grafana(AMG) サービスとしての動作や AMG 独自の仕様など、AMG としての観点
- (2). Grafana エンジンにおける仕様や設定など、オープンソース Grafana としての観点
- AWSサポートが担保するのは基本的に上記の(1)の範囲になり、(2)についてはベストエフォートになります。
- (2)の技術的な点で手厚いサポートが必要な場合は、Enterprise版の契約が必要になります。
- https://docs.aws.amazon.com/ja_jp/grafana/latest/userguide/upgrade-to-Grafana-Enterprise.html
-
https://aws.amazon.com/marketplace/pp/prodview-lj4ozgtqla6y4
- ベース料金が $3,500/月 となり、なかなか高額であるため、可能な限りgrafana本家のページと検証で凌ぐのがよいと思います。
- AWSが提供する Managed Grafanaには、以下の2つのレイヤーがあります。
その他参考
- grafana本家
- ドキュメントのバージョンの変更
- 今回ManagedGrafanaで利用している9.4にあわせます。
- https://grafana.com/docs/versions/?project=/docs/grafana/
- MySQLデータソースにおける時系列データの扱い方
- ドキュメントのバージョンの変更
- AWS公式
以上です。