開発エンジニアからデータエンジニアへ
千葉祐大氏(以下、千葉):Sansan株式会社の千葉からは「Sansan DSOC を支える名刺データ分析基盤」の構築、運用上の困ったことなどについて発表します。
まず自己紹介をします。3年前にSansanにジョインして、現在はデータエンジニアの仕事をしている千葉祐大です。データエンジニアをやるのはSansanが初めてで、それまでは、データサイエンティストや開発エンジニアといった方面の仕事をしていました。
もともと分析基盤がないなか、クライアントからデータをお預かりし、自分で基盤を構築してデータを乗せ、分析した結果を渡す。この経験を活かして、今のデータエンジニアの仕事をやっています。
僕の紹介はこれぐらいにして、次は、会社の紹介に移ります。
ミッションは「出会いからイノベーションを生み出す」
弊社はSansan株式会社と言いまして、主にクラウド名刺管理サービスの企画・開発・販売を行っています。「出会いからイノベーションを生み出す」をミッションに活動しています。プロダクトとしては2つ。法人向けのクラウド名刺管理サービス「Sansan」と、名刺アプリ「Eight」を展開しています。
「Sansan」に関しては、所属している会社が契約していないと利用できませんが、「Eight」に関しては、個人向けのスマートフォンのアプリとして提供しています。「名刺管理したい」という希望があれば気軽に使えるサービスとなっているので、興味があればダウンロードしてみてください。
社内の組織体系は、「Sansan」はSansan事業部が主に開発にあたり、「Eight」はEight事業部が開発しています。このサービスの軸となる名刺のデータ化に関しては別の部署が受け持っていて、それが私の所属しているデータ統括部門のDSOCです。
こちらの部門にはデータ化のオペレーターを管理する部署や、データ化のシステムを作っている人たち。あとはデータ自体を分析してくれている人も所属していて、データエンジニアもDSOCに所属しています。
DSOCは、主に2つの軸で活動しています。DATAとRESEARCHです。詳しくはデータを作ることと、どう活かしていくかということです。
名刺の交換からはじまる出会いには、イノベーションを起こす可能性が詰まっていると思っています。その出会いのデータベースをいかにうまく作っていくかが私たちのミッションであり、やるべきこととして捉えています。
ここまでが弊社の説明だったのですが、まだちょっと前置きがあります。DSOCで扱っているデータについてです。このあと名刺の分析基盤について話しますが、そこのデータについて前置きさせてください。基本的には「Eight」のユーザーからお預かりしたデータを、利用規約に定めた範囲で則り、サービス向上のために活用しています。
具体的に言いますと、「Eight」などのプロダクトへの新機能とか既存機能の改善を目的として名刺データを活用しています。そして分析に利用・公開するデータは、すべて「Eight」に限定しています。これらのデータに関しては、すべて統計処理または匿名化処理を実施した上でWeb利用しています。この3つを念頭においた上で、以降の説明をしていきます。
名刺データ分析基盤について
ここから分析基盤について話します。弊社が分析基盤と呼んでいるのは名刺のデータ分析基盤のことです。これはさっき話したDSOCに所属しているR&D(研究部門)。この人たちが名刺の研究や分析、プロダクトの新機能開発など、ユーザーへのサービス向上のために使っています。
名刺データを分析しやすいように整形・加工して、ユースケースごとに分けて構築したデータベース。それと関連データ、処理基盤全体を指しています。名刺データ分析基盤は、役割ごとに2つに分けています。
ストリーミングでほぼリアルタイム……ニアリアルと呼んでいますが、このニアリアルで同期されるデータベース。そして、それらのデータを週次で書き出して分析しやすいような形で、保存してSQLベースで分析できるウィークリーの同期データベース。この2つのデータベースに分けて役割・用途ごとに保存して使っています。
分析基盤構築前の問題
最初は分析チームも小規模だったのですが、徐々にチームも大きくなっていって、分析用のクエリが増えていく中で、さまざまな課題が出てきました。
大きなところで言うと、利用時の影響を考慮する必要があるといったところです。そもそも別の用途で作ったデータベースなので、分析する人がデータベースの負荷を考えながら、使うみたいなところがありました。利用時の心理的障壁が大きいという問題です。
そもそもの使用目的は分析用途のデータベースではないので、何かしらアプリケーションに影響が出たり、切り出しとかをするときにコストが掛かってしまいました。あとはアプリケーション用に最低限のリソースを組んでいるデータベースだったので、大規模な集計クエリなどが分析の基準に満たさず、集計が遅いといった事態にもなりました。
そういった問題を抱えつつ、データの利用方法も多種多様になり、それらに対応に追いつけなくなりました。具体的には利用者の増大によって大規模な集計や取得のクエリが増加したためです。アプリケーション用のデータベースなのでテーブルの構成が分析目的では使いにくかったり、カラムなどにアプリケーションの状態を管理するための数値などが入っています。
そういった結果を受け、新しい分析基盤を作ろうという方向に向かっていきます。
複数のデータベースをまとめた分析基盤
僕がデータエンジニアとして入社してから、まず周りを制御して分析基盤を構築していく中で要件をいくつか整理しました。基本的には主にデータ活用部門のR&D等がデータをストレスなく利用するための基盤を作るといった流れです。
具体的にはSQLで取得とか集計が可能であること。そして高速なデータ取得が可能、できればRDBMS並みがいい。そしてその分析基盤自体の人や金銭の運用コストを最小限にしたいといった希望がありました。
ある意味、相反するものが含まれている中で要件を整理しつつ、1ヶ月ぐらい上司と「どういう構成にするか」と相談しました。最終的に、1個のデータベースというかアーキテクチャで実現するのは難しそうだという結論になりました。
要望をすべて満たすために複数のデータベースをまとめて1つの基盤にしていこう、という方向で話がまとまり、その構想で構築したのが次の名刺分析基盤です。ニアリアルの同期データベースとウィークリーの同期データベース。この2つを分析基盤として構築しました。
データベースの設計理念
役割としては、利用者が用途ごとに使い分けられて、基本的にはマネージドサービスを利用して運用コストが低くなるような基盤を実現しています。このニアリアル同期データベースは、基本的にはデータ取得を目的としていて、またデータは随時更新。データが発生してから更新までのタイムラグが少ないような仕組みにして、基本的にはストリーミングでデータを同期します。
これを満たせるデータベースとして、DynamoDBを採用しました。データを指定しての取得や全取得するような用途で構築。ただ、DynamoDBだけだとSQLなどの分析では使いづらいので、SQLベースで集計できるようにウィークリーの同期データベースも一緒に作りました。
もともとはデイリーで更新していましたが、そこまで需要がないので、現在は週次更新になっています。ウィークリーでデータをエクスポートして取り込むことで、実現した基盤です。データはS3に置きSQLで集計するために、クエリエンジンにはAthenaを採用しています。
ニアリアルの同期を実現
次は、ニアリアルの同期データベースの細かいアーキテクチャの話です。基本的にはKinesisやLambda、そしてDynamoDBの3つを使ってニアリアルな同期を実現しています。このデータソースと書いてあるのは、もともとのデータソース元のアプリケーションの領域です。もともとアプリケーション側のRDSがあって、そちらでの更新に応じて都度こちらにデータを発生ベースで投げてもらっています。
KinesisはKinesis Streams(※Kinesis Data Streams)にデータを投げてもらって、シャードをいくつか分けていて、シャードごとに同じIDのデータが入ることで、同じID同士の時系列の処理は担保している形になっています。ストリームごとにLambdaが取り出されて、その取り出された順にDynamoDBにデータが入っていく仕組みです。
ここで省略していますけど、DynamoDBにデータが入ってからも、DynamoDB Streams経由でトリガーされるLambdaがあり、処理がなされます。ここでは、データが入ったタイミングでデータに分析に有用な各種パラメーターを付与するためのAPIを叩いて、もう1回保存し直します。ここまでは、基本的にはほぼニアリアルタイムで、発生から保存までなるべく短いスパンでできるような仕組みとしています。
ウィクリー同期の実現方法
次はウィークリーで、GlueやLambda、S3、Athenaなどを利用して実現しています。基本的にはStep FunctionsをCloudWatch Eventで定期的に起動します。そこからLambdaを制御して、GlueやData Pipelineでデータを抽出・整形・保存します。
当時はStep FunctionsでGlueを直接制御できなかったので、Lambdaを介した設計になっています。順序は、まずはStep Functionsが週次でトリガーされてLambdaが起動。そのLambdaがData Pipeline、これは裏でEMRを複数立ち上げてデータをエクスポートしてくれるもので、ニアリアルの同期基盤のデータを取得してS3に保存しています。
こちらのS3に保存して分析できるようにする関係で、差分を更新しないで毎週全件取得して、全件保存し直しの作業をやっています。DynamoDBの読み込みユニット数をだいたい4万ぐらいにあげて、全データを短時間でエクスポートしています。S3にはData PipelineからJSONの形式で保存しています。
この保存されたJSONに対して、Glueで読みだして適宜変換。ここではJSONで呼び出したあとで分析しやすい形式や属性に付与してS3に保存し直します。このときにParquetの形式かつsnappyで圧縮して、保存しています。
そのときに同時に作成、データの日付(年・月・日)でパーティショニングをしているので、なるべく列思考のParquetを使うなど、なるべくAthenaにクエリをコスト掛けないような仕組みになっています。
それらの結果は、すべてGlueのクローラを使ってスキーマ情報を作成してAthenaで読めるようにしています。実際に分析をする人たちは、AthenaのUIやAPI越しにSQLを叩いてデータを集計・取得する形です。データの可視化に関して、一部のデータの集計などはBIツールのTableauで行っていますが、基本的にはR&DはPythonやRなどのプログラムで可視化するケースが多いです。
あとはRedshiftのSpectrum側からもデータが見られるようになっています。Glueのカタログに登録されるので、外部のテーブルをSpectrum側に作ってあげれば、自然と見られるようになっているので、一部の人はそちらを経由して使っている人もいるようです。
構築・運用後の効果
こういったものを構築した結果、運用後の効果はありました。基本的にはR&Dを始めとした分析担当の業務を効率化できました。
今まで分析に関して心理的な障壁やSQLベースでできず、データを取得してローカルで集計していたものが、SQLですべて取得から集計ができるようになり、作業の効率化ができました。
もともと不必要なデータが混ざっている状態から、必要なものだけを使った分析が可能になりました。しかし、分析基盤を作ってだいたい1年半から2年ぐらい経過したため、いくつかの運用時の問題も見えてきました。ここからはその問題についてお話しします。
運用時の問題と今後の課題
DynamoDBのときまでは、重複が起きない仕組みでした。しかしそれ以降のデータについては、全件抜いて書き出すときに、Data Pipelineを使っていると、そのData Pipelineのデータ取得方法が、データを上から順に並べていく形となります。そのため、その途中でデータが更新されてしまうと、前のデータと後のデータが重複して取得されてしまいました。あとは新しい変化があったときに取得されてしまう問題もありました。
同じIDなのに違うカラム、データで保存されたり、長く運用していると、一部のカラムの傾向が変化してしまう。その変化の監視が一切できてなかったので、そういったところを察知して事前に変化を検知する仕組みを作ったりもしました。
そして次の問題として、もともとR&Dの利用を想定していたんですけど、知らないうちに利用者が増えていたということもありました。
いつの間にかそのデータ分析者だけでなくて、アプリケーション側でデバッグ的にデータを使うということも増えました。そういった人たちが知らないうちにスキーマ変更を行ったりして、後に「このスキーマ変わったんですか?」って聞かれたりして、「利用していたんですね」みたいなやり取りもありました。
利用者の特定や、どこまで使われているのかの把握が難しく、現在も改善を進めています。
あとはデータの増大に関してコストが溢れてきています。これは主にDynamoDBに掛かっていて、データの保存より書き込みや読み出しが原因です。それらに想定よりもたくさんクエリが来て、増大しているといった形です。
これらのすべてに関係していますが、だんだん運用のコストも増大してきて、人を増やそうと考えています。そこでSansanでは、データエンジニアを絶賛募集しています。
公式のリクルートのサイトにも掲載しているので、もし今回の話やデータエンジニア自体、Sansanについて興味があればぜひ声をかけてください。何かしらレスポンスができると思うので、お願い致します。
最後になりますが、@SansanTechというTwitterのアカウントも運用しています。こちらはSansanのブログの更新情報、本日のDevelopers Nightといった勉強会の告知や技術回りを支援するようなアカウントになっています。もしよかったらフォローしてもらえるとうれしいです。
最後は宣伝ばかりになりましたが、僕の発表は以上になります。ご清聴ありがとうございました。