データベースドキュメント管理システム dmemo のご案内

こんにちは、みんなのウェディングに出向中の小室 (id:hogelog) です。

今回はクックパッドとみんなのウェディングで利用しているデータベースドキュメント管理システム dmemo を紹介します。

https://github.com/hogelog/dmemo

f:id:hogelog:20160808041022p:plain

dmemo を作成し導入した経緯

私は2016年3月頃からみんなのウェディングで Redshift, bricolage, embulk, re:dash 等を利用したデータ分析基盤の構築を進めています。 (みんなのウェディングのデータ分析基盤の現状 - みんなのウェディングエンジニアリングブログ)

社内の誰でも扱えるデータベース、データの集約・計算・加工、ダッシュボードの作成、クエリの共有などは上記ブログ記事でも書いたように Redshift, bricolage, embulk, re:dash 等を組み合わせることで実現できました。ですがそれだけでは DWH を社内の誰でも簡単に扱える状態とは言えません。たくさんのデータがあっても意味がわからなければ役にはたたないからです。

ソースコードを読み解くことでしかデータの仕様を理解できない環境では一部のエンジニアと周辺の人しか高度な分析をおこなえません。データの仕様のドキュメント化も進めていましたが、なかなか整備しきれるものではありません。

しかし実際のところデータベースに存在するスキーマ・テーブル・カラムなどのスキーマ情報はプログラムで自動的に取得できる情報です。スキーマ情報からはわからない「このテーブルはなんのためのテーブルなのか」「このカラムが取りうる値はなんなのか」といった情報のみを人が管理していけば良い、そんなツールを目指して作ったのが dmemo です。

dmemo の仕組み

dmemo は DBとして PostgreSQL を利用するごく標準的な構成の Rails アプリケーションです。

  • 接続可能データソース(データベーススキーマ情報の取得元)
    • Redshift
    • PostgreSQL
    • MySQL
  • Google OAuth 2.0 認証
  • バッチ実行によるデータソースとの同期処理

Dockerfile, Docker Imageも提供しているため、多くの環境ではDocker経由で稼働させるのが簡単でしょう。

ユーザ認証

ユーザ認証は Google OAuth 2.0 認証のみ提供しています。

接続先データソースなどの編集は Admin ユーザのみに許可されていますが、最初の Admin ユーザは DB を直接編集するか rake タスクから作成する必要があります。

$ ./bin/rake admin:activate EMAIL=konbu.komuro@gmail.com
 or
$ docker run --env-file .env.docker hogelog/dmemo ./bin/docker_admin_activate.sh konbu.komuro@gmail.com

データソースとの同期処理

dmemo はデータソースとなるデータベースのスキーマ・テーブル・カラムなどのスキーマ情報は半ば自動的に取得します。

Admin ユーザならば dmemo の Web 画面上からも実行できるのですが、基本的にはバッチ処理による同期を推奨します。

$ ./bin/rails r 'SynchronizeDataSources.run'
  or
$ docker run --rm --env-file .env.docker -t hogelog/dmemo ./bin/rails r 'SynchronizeDataSources.run'

みんなのウェディングとクックパッドでは上記処理を日次で実行し、実データと dmemo を同期させています。

Markdown による記述と履歴の保持

肝心のデータの仕様についてはデータベース・スキーマ・テーブル・カラムそれぞれに Markdown で説明を記述できるようになっています。データの現在の正しい仕様について誰でも恐れず更新していってほしいため、記述内容については差分を保持しています。*1

f:id:hogelog:20160808064011p:plain

辞書機能

データベースの説明にはドメイン固有の言葉がたくさん出てきます。

例えばクックパッドで文脈無しで「ユーザID」と言えば「main データベースの users テーブルの id カラム」のことです。このような説明を記述しておくため辞書機能を実装しました。

説明文の中に記述したテーブル名と辞書項目については自動的にリンクされるため、説明文における重複した記述を避けることができます。

HTML::Pipeline

余談ですが dmemo では Markdown 処理部分に HTML::Pipeline を利用しています。HTML::Pipeline は HTML を入力として Filter を通し HTML を出力するためのライブラリであり Markdown から HTML の変換も Filter として提供されています。HTML 構造を理解して処理するため文脈に応じた拡張文法の実装が容易であり dmemo のテーブル名・辞書項目の自動リンク機能も Filter の一つとして実装されています。

注意点

現在の dmemo は社内で設置し特定の Google Apps ドメインのユーザのみアクセスできる状態での動作を想定していおり、 Markdown 記述機能に関して一切の制限をかけていません。script タグなどもそのまま記述できるため、インターネットから不特定ユーザからアクセスできる状態で設置すると危険です。

OSS として開発したことによるメリット

実のところ dmemo はみんなのウェディングの DWH に感じた課題から、余暇にちょっとずつ開発していたソフトでした。2016年6月頃にはある程度の完成度に至り「意外とこれは本当に便利そうだし会社でも導入した方が良さそうだな」と感じていたのですが、まだ完成度に不安があったのと、日々の業務に追われみんなのウェディング社内には導入していませんでした。

そんな頃にふとクックパッドで DWH 基盤を構築している id:InoHiro id:mineroaoki もクックパッドのデータベースの仕様ドキュメント化に同様の課題を抱えていると聞き dmemo を紹介したところ、id:mineroaokiの「いいじゃないすか、そういうのが欲しかったんすよ」という一声により、あっという間にクックパッド社内に導入されてしまいました。*2

導入され運用が始まると手元で開発していた時には気づけなかった様々なフィードバックが届きます。例えば当初の dmemo はデータソースとの同期はオンラインでおこなう作りでしたが、 Redshift などに大量のテーブルが存在する場合同期処理の間アクセスができなくなる、デプロイの度にキャッシュが消えて特定巨大テーブルへのアクセスがタイムアウトするなど運用が辛いものでした。テーブル名の自動リンク、辞書機能などもまったく発想になかった機能もフィードバックから実装に至りました。

OSS として広くフィードバックを受けながら開発しているというにはまだちょっと狭いかもしれませんが、とりあえず会社の枠は超えた改善が実現できました。

まとめ

クックパッドとみんなのウェディングでは dmemo を利用しデータベースの暗黙知を組織内で共有し、誰でも簡単に使えるデータ分析基盤の構築を進めています。

クックパッドでは id:mineroaoki を中心としたプロフェッショナルなチームにより世界一使われている料理とレシピのサイトのデータ分析基盤が構築されており、みんなのウェディングでは id:hogelog id:takai_naoto らによりもう少し小規模なデータとチームでスピード感を持ってデータ分析基盤を構築しています。

クックパッド、みんなのウェディングどちらでも興味のある方は是非お声掛け下さい。実際に運用している dmemo の画面を見てみたいとか、そんなカジュアルな見学もいつでも歓迎しています。もちろん本格的な採用情報への応募もお待ちしております。

*1:日付つき但し書きが大量に書かれた仕様書、よく見かけますけど読むのは辛いですね

*2:実際のところクックパッド社内にも導入させてやろうという目論見のもと開発していましたし、紹介しました。業務でバリバリに使われるOSSを個人で開発したかったので、狙い目だったのです

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/