Redashでデータを可視化する

(2017-10-23)

RedashはOSSのデータ可視化ツール。 BIツールのようにパラメータを変えながら指標を探っていくというよりは、分かっている指標を見るのに使うイメージ。 比較的機能が少ない分処理がわかりやすく、 クエリが自動生成されないため時間がかかるものを実行する前にある程度気づけるのが良いと思う。

docker-composeで立ち上げることもできるけど、 AWSの各リージョンにAMIが用意されているのでそれで立ち上げる。

sshで入って以下のようなのを必要に応じて設定する。 メールを送る場合はSESでメールアドレスをVerifyしてやるのが簡単。 GSuiteを使っている場合、OAuthのClientID、Secretを発行しドメインを登録するとそれで認証できる。

$ ssh [email protected]*****
$ sudo vi /opt/redash/.env
export REDASH_MAIL_SERVER="email-smtp.us-east-1.amazonaws.com"
export REDASH_MAIL_USE_TLS="true"
export REDASH_MAIL_USERNAME="*****"
export REDASH_MAIL_PASSWORD="*****"
export REDASH_MAIL_DEFAULT_SENDER="*****" # Email address to send from

export REDASH_GOOGLE_CLIENT_ID=""
export REDASH_GOOGLE_CLIENT_SECRET=""

$ cd /opt/redash/current
$ sudo -u redash bin/run ./manage.py org set_google_apps_domains {{domains}}
$ sudo supervisorctl restart all

HTTPS対応するのに/etc/nginx/sites-available/redashを編集する。crtとkeyの場所は変える。

upstream rd_servers {
  server 127.0.0.1:5000;
}

server {

  server_tokens off;

  listen 80 default;

  access_log /var/log/nginx/rd.access.log;

  gzip on;
  gzip_types *;
  gzip_proxied any;

  location /ping {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass       http://rd_servers;
  }
  
  location / {
    return 301 https://$host$request_uri; 
  }
}

server {
  listen 443 ssl;

  # Make sure to set paths to your certificate .pem and .key files.
  ssl on;
  ssl_certificate /path-to/cert.pem; # or crt
  ssl_certificate_key /path-to/cert.key;

  # Specifies that we don't want to use SSLv2 (insecure) or SSLv3 (exploitable)
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  # Uses the server's ciphers rather than the client's
  ssl_prefer_server_ciphers on;
  # Specifies which ciphers are okay and which are not okay. List taken from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
  ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

  access_log /var/log/nginx/redash.access.log;

  gzip on;
  gzip_types *;
  gzip_proxied any;

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass       http://rd_servers;
    proxy_redirect   off;
  }
}

諸々のデータはローカルで動いているPostgreSQLに入っている。

redash-# \d
                       List of relations
 Schema |               Name               |   Type   | Owner  
--------+----------------------------------+----------+--------
 public | access_permissions               | table    | redash
 public | access_permissions_id_seq        | sequence | redash
 public | alembic_version                  | table    | redash
 public | alert_subscriptions              | table    | redash
 public | alert_subscriptions_id_seq       | sequence | redash
 public | alerts                           | table    | redash
 public | alerts_id_seq                    | sequence | redash
 public | api_keys                         | table    | redash
 public | api_keys_id_seq                  | sequence | redash
 public | changes                          | table    | redash
 public | changes_id_seq                   | sequence | redash
 public | dashboards                       | table    | redash
 public | dashboards_id_seq                | sequence | redash
 public | data_source_groups               | table    | redash
 public | data_source_groups_id_seq        | sequence | redash
 public | data_sources                     | table    | redash
 public | data_sources_id_seq              | sequence | redash
 public | events                           | table    | redash
 public | events_id_seq                    | sequence | redash
 public | groups                           | table    | redash
 public | groups_id_seq                    | sequence | redash
 public | notification_destinations        | table    | redash
 public | notification_destinations_id_seq | sequence | redash
 public | organizations                    | table    | redash
 public | organizations_id_seq             | sequence | redash
 public | queries                          | table    | redash
 public | queries_id_seq                   | sequence | redash
 public | query_results                    | table    | redash
 public | query_results_id_seq             | sequence | redash
 public | query_snippets                   | table    | redash
 public | query_snippets_id_seq            | sequence | redash
 public | users                            | table    | redash
 public | users_id_seq                     | sequence | redash
 public | visualizations                   | table    | redash
 public | visualizations_id_seq            | sequence | redash
 public | widgets                          | table    | redash
 public | widgets_id_seq                   | sequence | redash
(37 rows)

なので他の環境に移すときはこのdumpを取ってリストアする。バックアップを取っておくと良い。

最初の画面

データソースを登録する。MySQLやRedshift、AthenaやBigQueryのほかにHive、ElasticSearchなども選べる。 今回はMySQL(Amazon RDS)を選択した。

データソースの登録

適当なデータをいれる。

const mysql = require('mysql');
const connection = mysql.createConnection({
  host     : '*****',
  user     : '*****',
  password : '*****',
  database : '*****'
});

const query = (connection, query, params) => {
  return new Promise((resolve, reject) => {
    connection.query(query, params, (error, results, fields) => {
      if (error) reject(error);
      resolve(results);
    });
  });
};

(async () => {
  connection.connect();

  await query(connection,
    `DROP TABLE IF EXISTS hoge`
  );

  await query(connection, 
    `CREATE TABLE hoge (
      id int,
      fuga_id int,
      piyo_id int,
      value int,
      created_at datetime
    )`
  );

  for (let i = 0; i < 100; i++) {
    console.log(i);
    await query(connection,
      `INSERT INTO hoge SET ?`,
      {
       id: i, 
       fuga_id: Math.floor(Math.random() * 3), 
       piyo_id: Math.floor(Math.random() * 10),
       value: Math.floor(Math.random() * 100),
       created_at: new Date(),
      }
    );
  };

  connection.end();
})();

クエリを登録する。エディタがあってフォーマットもしてくれる。 毎分や特定の時刻に実行するスケジュール機能もあるので、 重いクエリも事前に実行しておいて必要なときにすぐに見られるようにすることができる。 {{name}}のようにパラメータを入れることもできる。

クエリの登録

実行して得られたデータからChartを作る。データはCSVでダウンロードもできる。

Chart

このChartをDashboardに貼る。 パラメータがある場合は入力するフォームが出るので、クエリを書かない人に使ってもらうこともできる。

Dashbord

あとは簡単なAlertも登録することができて、 飛ばす先はSettingsのALERT DISTINATIONSに SlackのWebhookなどを設定できる。

Alert

Slackに飛ぶメッセージ