MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

MicroAdのデータ基盤

こんにちは。インフラエンジニアの@kanga333です。 最近マイクロアドではデータ基盤を刷新しました。 今回はデータ基盤の刷新に至る背景と新基盤での設計ポイントについてざっくり書いていきたいと思います。

刷新に至る背景

マイクロアドを長年支えてきた既存データ基盤は長年の改修の結果、色々な課題を抱えていました。

データの転送がNFS, Fluentd, Kafkaなど機能毎に色々な方法で行われており、共通基盤的な部分にもかかわらず共通化ができていませんでした。 Hadoopクラスタはサービス毎に立ち上がっていました。クラスタのバージョンは更新できておらず、運用コストが膨らんでいました。 クラスタが分散しているので、データサイエンティストが新しい環境にデータを集める際に、どこににデータがあるのか各担当者にヒアリングする必要がありました。 そして、そこに第一回の記事でも触れているようにDWHのスケールの限界を迎えているような状況でした。

そこで、データ基盤を刷新しようという話になりました。

アーキテクチャ全容

構成の検討を重ねた結果、以下のようなシンプルな構成に刷新することになりました。

f:id:kangaat:20180523201952p:plain

刷新後のアーキテクチャでは全てのログをJSON化してKafka経由で一つのHadoopクラスタに集める構成としました。 くわしくは後述しますが、シンプルで変更しやすくスケールしやすいデータ基盤となることを意識して設計しています。 新構成は現在、無事に稼働しており毎日数TB規模のデータが蓄積されていっています。

以後は各構成のポイントについてです。

全てのログのJSON化する

刷新に合わせて、アプリケーションのログを全てTSVからJSONに変更する方針としました。

ログは重要な情報元で、システムの変更しやすさが大事なのと同じように、ログのスキーマの変更しやすさも重要です。 JSONにした理由は自己記述型でネストなどの非正規的な表現ができるためです。

自己記述型のフォーマットでは各フィールドの名前がログ自身に記述されています。 JSONに対応したミドルウェアは大概、ログをパースしてフィールドを自動認識してくれる機能を持っています。 このためパイプライン上のミドルウェアでスキーマ情報を持たなくて済むようになり、ログのスキーマ変更時の影響を抑える事ができます。

またJSONは配列やMAPなどの非正規的なデータ構造を表現できるため、HadoopなどのJOINが重い大量データを処理するエンジンとの相性が良いです。

これらの理由でログをJSON化する方針としました。

全てのログをKafkaに集約する

サーバで生成されたアプリケーションのログは全てFluentdを介してKafkaに送る構成にしました。 Kafkaはクラスタとして動作するソフトウェアであるため既存の転送経路と比較して耐障害性や拡張性を高めることができました。 また、Kafkaによりデータの送信側と受信側の依存を分離することができました。その具体的なメリットは以下になります。

送信側はデータを取得しているHadoopクラスタが動いてようが停止していようが気にせずログを送り続けることができるので、クラスタのメンテナンスが容易になりました。

f:id:kangaat:20180523202054p:plain

パイプラインを分岐させることが容易なので、本番クラスタと開発クラスタで同じデータを利用する構成にすることができるようになりました。

f:id:kangaat:20180523202127p:plain

データのパイプラインで別の処理を加える事が簡単になりました。 先日の松宮の記事はその一例です。 ログ全体を横断してセッション情報を付与した後、Hadoopに取り込むなどのパイプラインを実現しています。

f:id:kangaat:20180523202215p:plain

HadoopクラスタはClouderaManagerで管理する

Hadoopクラスタの構築方法をPuppetを使った方法から、ClouderaManagerという管理ツールを使う方法に変更しました。 複雑なクラスタのオペレーションをWebコンソールから管理できるようになったため、構築やアップグレードが非常に楽になりました。 監視もオールインワンなのも嬉しいポイントです。 新クラスタでは検証段階から数えてすでに4度のアップデートを実施しており、現在も最新バージョンに追従していっています。

ジョブ実行にDigdagとDockerを利用

データパイプラインの刷新とは直接は関係ないのですが、合わせてバッチ実行基盤をDigdagとDockerを使う構成に変更しました。 以前の構成ではJenkinsとcronが主流で、Jenkinsはgitで管理しづらく、cronは再実行に手動オペレーションが必要だったりなど、複数の課題がありました。

DigdagのDockerコンテナでワークフローを実行する機能を使って、全てのワークフローをDockerコンテナ内部で実行しています。 Digdagにはsession_timeというリトライ時でもジョブの実行予定時間を保持できる概念があるので、べき等なバッチ処理が書きやすいのが良いです。 べき等な処理とコンテナによるホストに依存しないバッチ実行によって、オンプレ環境でも弾力性のあるバッチ基盤とすることができました。

f:id:kangaat:20180523202202p:plain

また、バッチの順序や実行環境を記したワークフロー、実際のバッチ実行のスクリプト、実行環境の構成を記述するDockerfile、とバッチ実行に必要な全ての情報をコードとして1つのリポジトリで管理できるようになったため、バッチの見通しをよくすることができました。

最後に

以上ざっくりとしたデータ基盤刷新の紹介でした。他にも色々考慮したことはあるのですが、今後共有していけたらなと思っています。

刷新によって、最初に上げていた課題は解消しつつあるのですが、まだまだ良くしなければいけないと思っているポイントはたくさんあります。 移行時の残課題、新たに見えた課題、クラウドとのハイブリットなどより良い構成の検討、などなど。

マイクロアドではより良いデータプラットフォームを作りたいエンジニアを募集しています。 https://www.green-japan.com/job/57418?case=tlogin&lid=n_other_jobs