気軽にData Observabilityを導入できる「Soda」のチュートリアルをやってみた

今回はData ObservabilityのSaaSプラットフォーム、 Soda を触っていきます。

Data Observabilityとは、一般的なObservability(可観測性)のデータ版、と捉えていただいて差し支えありません。メトリクスとしきい値を用意し、データに対してヘルスチェックや事前検知を行うことで、データの品質保持や障害の予防に繋げることができます。

Sodaについて

Sodaは2018年にベルギーで創業された、Data Observabilityのプラットフォームを提供するSaaSカンパニーです。2021年2月のシリーズAラウンドでは、€11.5Mの資金調達に成功しています。

Soda Raises €11.5M Series A Funding to Bring Everyone Closer to Data

Sodaは製品コンセプトとして、 Automated MonitoringTesting & ValidationData FitnessCollaboration を掲げています。データの品質保全に関する業務をチームで回せるよう、運用周りの設計に力が入っているようですね。

CLIとYAMLベースの Soda SQL というクライアントと、モダンなUI/UXによって、シンプルで取り回しの良いData Observabilityを実現することができます。

Sodaでは無料でアカウントが作成できるほか、アカウント作成後 Get Started のチュートリアルがあるので、こちらに沿って製品を理解していきたいと思います。

デモ環境のセットアップ

Sodaの公式HPから Sign Up をクリックして、アカウントを作成します。

ユーザー情報などを入力しSign Upをクリックして完了です。メンバーの追加のガイドが表示されますが一旦飛ばしまして、Datasetsの画面に到着します。Get Startedをクリックして、チュートリアルを開始します。

Get Startedでは5項目手順が用意されています。まずは1から実施していきます。

  1. Set up and scan
  2. Connect and view data monitoring results
  3. Integrate with Slack
  4. See what Soda can do!
  5. Invite your team members

「1. Set up and scan」では、Soda SQLというローカルPCで使うクライアントのセットアップを行いないます。下記のドキュメントを参考に、今回ターゲットとするPostgreSQL用のSoda SQLをインストールします。

Install Soda SQL - Soda Documentation

$ pip install soda-sql-postgresql

その後、Soda SQLに関するチュートリアルを進めていきます。デモ環境のGitHubリポジトリをCloneし、「Set up manually」の手順に沿ってコンテナを立ち上げます。

$ git clone https://github.com/sodadata/tutorial-demo-project.git
$ cd tutorial-demo-project/
$ docker-compose up -d

コンテナ立ち上げ後、docker-compose logs -fで実行ログを確認してみると、デモ用のテーブルやレコードが作成されているみたいです。

続いて、リポジトリ内に用意されているワークスペース用のディレクトリに移動します。

$ cd workspace/new_york_bus_breakdowns_demo/

soda create postgresを実行し、コネクション用のYAMLファイルを2つ生成します。

$ soda create postgres
  | Soda CLI version 2.1.0b22
  | Warehouse file warehouse.yml already exists
  | Adding env vars for None to /Users/haruta.takumi/.soda/env_vars.yml
  | Review warehouse.yml by running command
  |   cat warehouse.yml
  | Review section None in ~/.soda/env_vars.yml by running command
  |   cat ~/.soda/env_vars.yml
  | Then run the soda analyze command
  | Starting new HTTPS connection (1): collect.dev.sodadata.io:443
  | https://collect.dev.sodadata.io:443 "POST /v1/traces HTTP/1.1" 200 0

warehouse.ymlは、データベースへの接続情報が定義されています。hostのみlocalhostに変えておいてください。

name: sodasql
connection:
  type: postgres
  host: localhost
  port: "5432"
  username: sodasql
  password: env_var(POSTGRES_PASSWORD)
  database: sodasql_tutorial
  schema: new_york

~/.soda/env_vars.ymlには、warehouse.ymlから参照されるパラメータが記述されています。今回はwarehouse.ymlにベタ書きしていくので、ここの変数は使用しません。

postgres:
  POSTGRES_USERNAME: Eg johndoe
  POSTGRES_PASSWORD: Eg abc123

null:
  POSTGRES_USERNAME: Eg johndoe
  POSTGRES_PASSWORD: Eg abc123

接続情報のファイルが作成できたら、soda analyzeを実行してテーブルの解析を開始します。

$ soda analyze
  | 2.1.0b22
  | Analyzing warehouse.yml ...
  | Querying warehouse for tables
  | Directory tables already exists
  | Executing SQL query: 
SELECT table_name 
FROM information_schema.tables 
WHERE lower(table_schema)='new_york'
  | SQL took 0:00:00.006497
  | Executing SQL query: 
SELECT column_name, data_type, is_nullable 
FROM information_schema.columns 
WHERE lower(table_name) = 'breakdowns' 
  AND table_catalog = 'sodasql_tutorial' 
  AND table_schema = 'new_york'
  | SQL took 0:00:00.007527
  | Executing SQL query: 
SELECT 
  COUNT(CASE WHEN "school_year" ~* '^\-?[0-9]+$' THEN 1 END) AS number_whole,

...

  | SQL took 0:00:00.015954
  | Creating tables/breakdowns.yml ...
  | Next run 'soda scan warehouse.yml tables/breakdowns.yml' to calculate measurements and run tests
  | Starting new HTTPS connection (1): collect.dev.sodadata.io:443
  | https://collect.dev.sodadata.io:443 "POST /v1/traces HTTP/1.1" 200 0
$ ls tables
breakdowns-demo.yml breakdowns.yml

解析の実行結果として、tables/breakdowns.yml が作成されました。解析したテーブルごとに、どのメトリクスやバリデーションを適用するかが記されています。

table_name: breakdowns
metrics:
  - row_count
  - missing_count
  - missing_percentage
  - values_count
  - values_percentage
  - invalid_count
  - invalid_percentage
  - valid_count
  - valid_percentage
  - avg_length
  - max_length
  - min_length
  - avg
  - sum
  - max
  - min
  - stddev
  - variance
tests:
  - row_count > 0
columns:
  school_year:
    valid_format: date_inverse
    tests:
      - invalid_percentage == 0
  bus_no:
    valid_format: number_whole
    tests:
      - invalid_percentage <= 20
  schools_serviced:
    valid_format: number_whole
    tests:
      - invalid_percentage <= 15

最後にtables/breakdowns.ymlを使用して、各メトリクスを集計してテストします。All is good. No tests failed.が表示されればスキャンは成功です。このように、YAMLに設定したメトリクス・しきい値で、ターゲットのDBを品質テストできるのがSoda SQLの特徴です。

$ soda scan warehouse.yml tables/breakdowns.yml
  | 2.1.0b22
  | Scanning tables/breakdowns.yml ...
  | Environment variable POSTGRES_PASSWORD is not set
  | There is no value specified for valid_values for column school_year
  | There is no value specified for valid_min for column school_year
  | There is no value specified for valid_max for column school_year
  | There is no value specified for valid_values for column bus_no

...

  | Test column(schools_serviced) test(invalid_percentage <= 15) passed with measurements {"expression_result": 12.095620956209562, "invalid_percentage": 12.095620956209562}
  | Executed 2 queries in 0:00:00.751460
  | Scan summary ------
  | 239 measurements computed
  | 4 tests executed
  | All is good. No tests failed.
  | Exiting with code 0
  | Starting new HTTPS connection (1): collect.dev.sodadata.io:443
  | https://collect.dev.sodadata.io:443 "POST /v1/traces HTTP/1.1" 200 0

続いて「2. Connect and view data monitoring results」に進みます。Connect to Soda Cloudのドキュメントに沿って、API Keyをwarehouse.yml~/.soda/env_vars.ymlに設定します。Sodaのコンソールから、右上プロフィール画像のアイコンをクリックし、Profileをクリックします。

API Keyのタブをクリックし、右上の+ボタンで公開鍵・秘密鍵を作成します。

作成した公開鍵と秘密鍵はウィンドウを閉じる前にコピーしておいてください。

warehouse.ymlapi_key_idapi_key_secretに、公開鍵と秘密鍵を直接書き込みます。

name: sodasql
connection:
  type: postgres
  host: localhost
  port: "5432"
  username: sodasql
  password: env_var(POSTGRES_PASSWORD)
  database: sodasql_tutorial
  schema: new_york
soda_account:
  host: cloud.soda.io
  api_key_id: <PUBLIC KEY>
  api_key_secret: <PRIVATE KEY>

この状態で再度soda scanコマンドを走らせます。

$ soda scan warehouse.yml tables/breakdowns.yml

SodaコンソールのMonitor Resultsの画面に行くと、テストの項目ごとに結果が一覧表示されています。ローカルの結果をシームレスにパブリッシュできる点で使い心地が良いですね。

続いて「3. Integrate with Slack」のステップでは、いわゆるSlack通知の機能です。Sodaのコンソール右上のアイコンからOrganization Settingsをクリックします。

Integrationsのタブをクリックし、右上の+ボタンで追加します。

Slackを選択してNext

Slack側の認証に飛ぶので許可するをクリックします。

Sodaのコンソールに戻ると、Slackのチャンネル一覧が表示されます。今回はお試しということで、#sandboxを選択しました。

以上でセットアップは完了です!さっそくUIをいじっていきましょう。

SodaのUI

Sodaのコンソールにランディングすると最初に表示されるページがDatasetsです。先ほど登録したbreakdownsテーブルが登録されている状態です。クリックして詳細を見てみます。

各カラムには、欠損値や統計量、バリデーションの結果が格納されています。この辺りのメタデータはごく基本的。

Get Startedの「4. See what Soda can do!」に記載がある通り、Sodaのメイン機能はデータのモニタリングとバリデーションです。テーブル内に不正なデータが入ってきた時に検知とアラートを行ってくれます。それぞれのMonitorは先ほどのtables/breakdowns.ymlで定義されたもので、Monitor Resultsの画面にて一覧化されています。例えば、school_yearに設定したMonitorは以下のように定義されています。

実際にSlack通知を飛ばしてみます。school_yearカラムに対して、Edit Monitorをクリックします。

通知先の一覧が表示されます。現状はアカウント作成した時のメールアドレスだけが登録されてます。検索バーをクリックしてSlackチャンネルを追加します。

とりあえず通知がどんな感じかを確認したいため、All Resultsを選択します。

ローカル端末より、soda scanを実行します。

soda scan warehouse.yml tables/breakdowns.yml

無事、Slackチャンネルにに通知が飛んできました!

この後のステップとしては、他のユーザーを招待するわけですが、招待する人もいないのでデモの検証は以上とします。

所感

CLIやYAMLといったコードベースのクライアントとUIのモダンさから、Data Observabilityの体験としてはかなりシンプルなものでした。このシンプルさにコラボレーション系の機能が加わることで、チームで地に足のついたデータ保全を回していけそうだなと感じました。Data Observability自体がかなり時代の先を行っている分野なので、これが2、3年後にはどう浸透しているか楽しみです。

本アドベントカレンダーでは、今話題のデータ関連SaaSを取り上げていきますので、引き続き乞うご期待ください!