Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

社員全員が利用できるWebダッシュボードを Azureで作ってみた話

社員全員が利用できるWebダッシュボードを Azureで作ってみた話

YAEGASHI Takeshi

July 18, 2021
Tweet

More Decks by YAEGASHI Takeshi

Other Decks in Technology

Transcript

  1. ⾃⼰紹介 ⼋重樫 剛史 Takeshi Yaegashi § 株式会社バンダイナムコスタジオ所属 § Linux・Unix・OSS・Go ⾔語が好きなエンジニア

    § 組み込みシステム開発、ゲームサーバ開発、 開発環境のクラウドシフトなどの業務に従事 § July Tech Festa 登壇は 3 回⽬ 主な活動場所 ホームページ・ブログ https://l0w.dev GitHub https://github.com/yaegashi GitLab https://gitlab.com/yaegashi Twitter https://twitter.com/hogegashi
  2. #今さら聞けないIT技術 § Azure のデータ分析や Web アプリのサービスを活⽤して、 多⼈数が利⽤するカジュアルなダッシュボードを⼿軽に作ってみた話をします § 今さら聞けないキーワード -

    Redash, Grafana - Prometheus, Prometheus exporter - Azure Pipelines, Azure App Service, Azure Data Lake Storage, Azure Synapse Analytics, Azure SQL Database, Azure Database for PostgreSQL - SSH Tunneling, autossh, runit
  3. Azure コストの可視化 § 約 1 年前の話の続き「Goで作って配布する Azureコマンドラインユーティリティ」 § Azure Cost

    Management REST API を扱う azbill という CLI を Go ⾔語で作り Azure の利⽤実績・コストが JSON や CSV でエクスポートできるようになった § しかし、従業員全員 が⼿軽にアクセスで きる可視化⼿段はま だなかった
  4. SaaS によるダッシュボードの検討 § Azure でダッシュボードが作れる SaaS といえば Power BI だが…

    - Power BI Desktop による個⼈的なデータ解析・ダッシュボード作成は無料 - Power BI Service でダッシュボードを全インターネットに公開するのも無料 - しかし、組織内に閉じたダッシュボードの公開をしようとするとライセンスが必要 - Power BI Pro → 1,090 円/ユーザー/⽉ - 従業員 1,000 ⼈全員に提供しようと思ったら相当な出費になってしまう § SaaS 利⽤はあきらめてセルフホストでダッシュボードを構築する⽅針に転換
  5. Azure で OSS のダッシュボードを動かしてみる § Redash - Python による実装 -

    DB・キャッシュ・ワーカーなど複数のサーバで構成される - Azure AD (SAML) によるユーザー認証に対応 - 今回は Linux VM で構築 (Docker Compose を利⽤) § Grafana - Go ⾔語による実装 - シングルコンテナで動作し扱いやすい - Azure AD (OpenID Connect) によるユーザー認証とアクセス認可に対応 - 今回は Azure App Service の Linux Custom Container で構築
  6. データ処理部分を考える § ⽅針 - 1⽇1回、Azure Pipelines で azbill CLI を実⾏し、前⽇までの利⽤実績データを得て、

    Azure Data Lake にアップロードする - Azure Data Lake の更新をトリガとして Azure Synapse Analytics でデータを集計し、 ダッシュボードのデータソースとなる DB を更新する § Data Lake 内のデータ形式は圧縮 JSONL - JSONL → ⾏区切りの JSON オブジェクトの集合 - 集計⽉ごとに GZIP 圧縮した JSONL ファイルを Data Lake に格納する
  7. Azure Pipelines による azbill バッチジョブ実⾏ § Azure DevOps の CI/CD

    サービスで毎朝 azbill コマンドを動かす - 実⾏時間 1,800 円/⽉の無料枠、Azure Data Lake へのファイルアップロードが簡単にできる
  8. Azure Synapse Analytics & Azure Data Factory § Azure Synapse

    Analytics → Azure のビッグデータ分析サービス - Google BigQuery や Amazon Athena などと競合する § Synapse Analytics Severless SQL Pool - Data Lake に格納した⼤量の⽣データを外部テーブルとして SQL クエリで直接集計できる - 固定料⾦なし、SQL クエリが処理したデータ量にだけ課⾦される (US West 2 で 560円/TB) - 毎⽉ 10TB の無料枠が付与されるプロモーション中 (7/31 まで) § Synapse Workspace - SQL クエリ・変換・外部DB書き込みを含むパイプラインが実⾏可能 (Data Factory の機能) - Synapse Studio Web サイト上で SQL クエリやパイプラインの開発・デバッグができる - ワークスペースの情報は JSON で記録され Git による管理・コラボができる
  9. データソース⽤ DB § ダッシュボードでのユーザーのクエリに対応できる DB § 数 100 万レコード程度を対象に、次のパラメータの条件で⾼速に集計できる -

    集計期間 - Azure サブスクリプション - Azure 製品 (仮想マシン、ストレージ、ネットワーク帯域、etc.) § 様々な選択肢からの選定基準 - Azure のマネージドサービスである - Azure Data Factory の出⼒先になることができる - Redash や Grafana のデータソースになることができる - コストが安く、データや利⽤者が増えたら簡単にスケールアップできる
  10. データソース⽤ DB の選定 § Azure Cosmos DB, Azure SQL Database

    のサーバレスプラン - 固定料⾦なし、クエリした分だけで課⾦される DB - とても魅⼒的だが、ユーザーがインタラクティブにクエリを⾏う ダッシュボードには不向きなので採⽤せず § Azure SQL Database Single Database - DTU という性能指標で料⾦が変わる MS SQL - US West 2: Basic プラン B (5 DTU) → 548 円/⽉〜 § Azure Database for PostgreSQL - Grafana の管理 DB をデータソース DB にも流⽤ - US West 2: 1 vCore / 2 GiB → 2,279円/⽉〜
  11. Azure コスト JSON データ 1 件の例 { "id": "/providers/Microsoft.Billing/billingAccounts/********/billingPeriods/20210701/providers/Microsoft.Consumption/usageDetails/470c7926-bb15-22be-0443-4c72f5b4f02 "kind":

    "legacy", "name": "470c7926-bb15-22be-0443-4c72f5b4f029", "properties": { "accountName": "[email protected]", "accountOwnerId": "[email protected]", "billingAccountId": "********", "billingAccountName": "株式会社バンダイナムコスタジオ", "billingCurrency": "JPY", "billingPeriodEndDate": "2021-07-31T00:00:00Z", "billingPeriodStartDate": "2021-07-01T00:00:00Z", "billingProfileId": "********", "billingProfileName": "株式会社バンダイナムコスタジオ", "chargeType": "Usage", "consumedService": "MICROSOFT.DATAFACTORY", "cost": "5.52941176470588", "date": "2021-07-14T00:00:00Z", "effectivePrice": "27.6470588235295", "frequency": "UsageBased", "invoiceSection": "BandaiNamco", "isAzureCreditEligible": true, "meterDetails": { "meterCategory": "Azure Data Factory v2", "meterName": "Cloud Data Movement", "meterSubCategory": "", "unitOfMeasure": "10 Hours" }, "meterId": "9d6f5dbf-90a1-46bc-85b7-e9c3f92bae35", "offerId": "MS-AZR-0017P", "partNumber": "AAD-19265", "product": "Azure Data Factory v2 - Cloud - Data Movement", "publisherType": "Azure", "quantity": "0.2", "resourceGroup": "G1DASHBOARD", "resourceId": "/SUBSCRIPTIONS/********-****-****-****-**************/RESOURCEGROUPS/G1DASHBOARD/PROVIDERS/MICROSOFT.DATAFACTORY/FACTORIES/BANADXDASHBOARD1ADF", "resourceLocation": "japaneast", "resourceName": "BANADXDASHBOARD1ADF", "subscriptionId": "********-****-****-****-**************", "subscriptionName": "BanaDXG1", この1件の意味 2021-07-01 に BanaDXG1 サブスクリプションで Azure Data Factory v2 を 10 Hours × 0.2 使って 5.52941176470588 円の課⾦が発⽣した ちなみに単価は 27.6470588235295 円
  12. Data Lake ファイルに対する SQL クエリの例 SELECT period, date, subscription, product,

    SUM(CASE chargeType WHEN 'Usage' THEN quantity ELSE 0 END) AS quantity, SUM(CASE chargeType WHEN 'Usage' THEN unitPrice*quantity ELSE 0 END) AS referenceCost, SUM(CASE chargeType WHEN 'Purchase' THEN cost ELSE 0 END) AS purchaseCost, SUM(CASE chargeType WHEN 'Usage' THEN cost ELSE 0 END) AS usageCost FROM OPENROWSET( BULK 'banadev-billing/*.json.gz', DATA_SOURCE = 'banadxdashboard1', FORMAT='CSV', FIELDTERMINATOR='0x0b', FIELDQUOTE='0x0b' ) WITH (doc NVARCHAR(MAX)) AS rows CROSS APPLY OPENJSON(doc) WITH ( chargeType NVARCHAR(MAX) '$.properties.chargeType', period DATE '$.properties.billingPeriodStartDate', date DATE '$.properties.date', subscription NVARCHAR(MAX) '$.properties.subscriptionName', product NVARCHAR(MAX) '$.properties.product', unitPrice DECIMAL(28, 10) '$.properties.unitPrice', quantity DECIMAL(28, 10) '$.properties.quantity', cost DECIMAL(28, 10) '$.properties.cost' ) GROUP BY period, date, subscription, product ORDER BY period, date, subscription, product このSQLクエリの意味 Data Lake banadxdashboard1 の banadev-billing/*.json.gz ファイルに含ま れる1件1件の JSON オブジェクトから必要 な要素を取り出してテーブルに変換する
  13. Azure コスト可視化ダッシュボードのまとめ § Azure でセルフホストなダッシュボード Web アプリを構築してみた - SaaS である

    Power BI Pro に必要なライセンス料に⽐べると格安で実現できた - Azure AD により社員だけが全員ゼロトラストにアクセス可能という要件も実現できた - 1,000 ⼈のアクセス実績はまだないが PaaS 採⽤によりスケールアップは容易 (多分) § Azure Synapse Analytics がとても便利だった - ビッグデータとか⾃分には縁がないと思っていたが、まったくビッグでないデータでも⼗ 分に便利で格安に使えるサービスであることがわかった - Google BigQuery だけがビッグデータ解析サービスじゃないんだなということもわかった - 7 ⽉末まで 10TB が無料になるプロモーション期間なのでぜひ試してみてください
  14. Unity Licensing Server の可視化 § JTF2021w「Azure DevOps で実現するUnity アプリのハイパフォーマンス CI/CD」

    § ライセンスサーバの REST API で取得できるライセンス利⽤状況を可視化したい
  15. Prometheus によるデータ収集、エクスポータの⾃作 § Prometheus - このような REST API を定期的に監視して時系列メトリクスを作るのに適している -

    監視するサービスごとにエクスポータと呼ばれるサーバを作る必要がある § uls_exporter - Unity Licensing Server ⽤の Prometheus エクスポータ - Go ⾔語であればライブラリを使って簡単に開発できる - 後⽇公開予定
  16. Unity Licensing Server ダッシュボードのアーキテクチャ § ライセンスサーバの近くで Prometheus を実⾏する Linux VM

    を設置する § App Service の Grafana コンテナで autossh を動かして SSH トンネルを確⽴する
  17. Grafana コンテナの改造 § 公式の Grafana コンテナを改造して autossh を追加する - Alpine

    Linux なので runit と autossh を追加 - grafana と autossh を runit サービスとして 起動するスクリプトを⽤意 § 本当はこのような改造はしたくないが… - Azure App Service なら VNet 統合機能でプライベートネットワークにアクセスしたい → Unity Licensing Server が別サブスクリプション・別テナントにあり費⽤的に断念 - サイドカーコンテナ、複数コンテナ (Docker Compose) で autossh コンテナを追加したい → App Service はサイドカーコンテナには対応していない → App Service の Docker Compose は開発・デバッグが困難で実⽤的でない FROM grafana/grafana USER root RUN apk update && apk add runit autossh COPY service /etc/service ENTRYPOINT ["runsvdir", "-P", "/etc/service"]
  18. Grafana REST API data source plugin による情報取得 § Prometheus だけでなく

    Unity Licensing Server にも直接アクセスして情報が取得できる
  19. Unity Licensing Server 可視化ダッシュボードのまとめ § Redash, Grafana による社内ダッシュボードが構築できたので、 年始からの懸案であった Unity

    Licensing Server の状況表⽰をやってみました § 今後いろいろな状態やメトリクスを社内で公開できるようにします § uls_exporter などのコードは今後公開していきたいと思います