4年ほどデータエンジニアをしてみて、いろいろ振り返りつつ実際に経験してみて得られた所感や知見を上長から許可もいただいたので雑多に記事にまとめてみます。
注意書き
- ゲーム業界の話です。web業界では色々話が変わってくるところも多いかもしれませんし、同じ業界でも会社によって様々だと思います。
- ここに書いたことが他の環境ではうまくいかないケースも多々あると思います。異論も色々あると思います。状況に合わせたイレギュラーなことも結構やっています。一つの事例程度としてお考えください。
- ポエム成分を含むかもしれません。
集計やETLの全ての処理は冪等性を極力担保する
集計やらETLの対応はツールやサービスのGUIだったり、自前でPythonなどのコードやSQLを書いたりと様々だと思いますが、すべての処理で冪等性が担保できているということが大事です(任意の過去のデータも含め、何度集計などを流しても同じ集計結果になる状態)。
冪等性参考 : 冪等性とは「同じ操作を何度繰り返しても、同じ結果が得られる性質」のこと
基本的には後述するように念入りにチェックなどをするものの、多くの対応をしていると一部にミスが見つかったりも発生しうるものになります。
また、何らかの影響で日々の集計などが一部の処理が通らないといったケースが発生することも、頻繁にはありませんが数か月に1回くらいは発生しています。
そういった場合に過去の日付に対して処理を流しなおしが必要になることもあれば、直近のデータに対して処理を流し直す必要が出てきたりします。
そのようなケースが発生したときに、ごく一部でも冪等性が担保されていないところがあると大分しんどいことになりえます(大半の処理は冪等性が担保されるのが一般的ですが、ごく一部定期処理の中に担保されていないものが混じっているケースなど)。
しっかり気を付けていても大量に処理があると「え、そこで引っかかるの?」といったことも発生しますし、ログ側の都合で巻き込まれる形で流し直しになりうるケースも起こり得ます。
なので処理を書く際には「障害は起きるもの」として対応し、「過去の処理を流し直す場合どのくらいで対応できるだろうか?」といったことを意識しておくといいと思います。
日々のチェックの処理を面倒臭がらずに仕込んでおくと後が楽
データ基盤だと、大半のケースでは時系列的なデータを持つことが大半だと思います。
毎日多くのデータが蓄積されていきます。うちはデータ基盤は各プロジェクト横断的に対応しているので、新しい社内のプロジェクトがリリースされたら増加ペースが早くなります。
古いプロジェクトが終了した場合でも過去の分析をしたい・・・という要望を考えると終了プロジェクトのデータも消さずに残す形で運用していきます。
結果としては非常に長期の期間のデータを扱う必要が出てきます。ゲーム業界だとスマホゲームとかだと開発3年、運用5年といった長期にプロジェクトがなるケースも珍しくは無くなってきました(開発費の高騰などの影響も含め)。
そういった状況で、集計などの処理が「後々になってからミスが見つかった」みたいなケースが発生すると、結構対応が面倒なことになります。
特に追加した処理を反映してからミスに気づくのが数か月後とか、年単位で経過していると大分対応に時間が持っていかれるケースがあります(特に利用頻度が低いデータだと、目に見えづらいことも絡んで気づくのが遅れたりします)。
そういったケースをなるべく減らして楽をするために、チェック用のスクリプトなどはしっかりさせておくと後々の負担がぐぐっと減ります。
弊社のデータ基盤の場合、集計処理やETLの多くをPythonとデータサイエンス方面のライブラリに頼っています(ETLなどでBigQueryやAthenaでのSQLを大量に書くといったことは少な目)が、基本的にはほぼほぼの行カバレッジを確保する形で集計処理などに対する単体テストは書いています。
SQLやら外部サービスなどを使う場合でも、ミスしていないかのチェック用にスクリプトを書いたりは大切かなと思います。
また、デイリーなどで「集計結果大丈夫だよね?」といったことを確認するための様々なチェック処理が流れるようにしています。
他にも「送っていただいているログ側が何だかおかしいぞ?」といったことのチェックも色々入れたりもしています(なんらか引っかかったらチャットに通知し、早い段階でプロジェクト側に連絡をしたり等ができるようにしています。データソースで問題がありそうであればプロジェクト側の方が気づくよりも先に気づけるくらいが理想)。
加えて集計後のものに対する検算対応であったり、プロジェクトのドメイン知識が浅かったりもするので「この集計結果、違和感ないでしょうか?」みたいなことをプロジェクトに張り付いている分析担当の方に確認していただいたりなど、多重にチェックを入れたりもしていました(プロジェクト固有の数値の感覚は、プロジェクト側の方の方が鋭かったりもするため)。
若干チェックに力を入れすぎ・・・と感じられるかもしれませんが、前述のように長期間経過してからミスに気づくと結構地獄です。
また、修正を入れるときも各プロジェクトへの説明が必要になったり、今までの意思決定が誤った数字によるものになってしまう恐れもあります。
そういったリスクを加味すると、チェックは「やりすぎ」くらいが結局長期的には楽になったりします。なんだかんだそれくらいチェックしていてもミスするときはミスしますが、データ基盤の仕事を始めたころのチェックが甘い時と比べれば大分負担が減っています。
速度は大事
いくらチェックなどを頑張っていても、ミスやエラーなどが発生するときは発生します。
また、途中で追加の要望をいただいたりすることも結構あります。
そのようなケースで数か月、場合によっては年単位の処理の流し直しが発生することも結構あります(特に要望系は障害などと比べると結構多く発生しますし、会社への貢献という面でいうとなるべく要望に対応すべきとは考えています。差し込みタスクとなってしんどい時もありますが)。
流し直しが必要になった時に、冪等性などが担保されていても処理速度が遅いと辛いことになります。
仮に1日分で必要な処理が1分くらいで終わるとしても、1か月分で約30分、1年分で約6時間。
3年分とかの依頼が来ると結構辛いです(一方で案外そういった年単位の依頼は来たりします)。
なるべく楽をするためにも一日分の処理をなるべく速くしたいところです。
データレイクやDWHなどは速いものを利用する(BigQueryなりS3なりで)、パーティションの利用などはきっちりとやる、PythonスクリプトやSQLなどで遅くならないように注意する、事前に細かく速度を計測しておく、知らないうちにログが大きくなっているデータセットでパフォーマンス的に問題を抱えていないかなどを継続的にチェックする、アラートの仕組みを整えておくなど、配慮すべき点は様々です。
年経過でPython界隈も色々改善しているライブラリが出てきたりもしていますので、そういった新しいものに少しずつ切り替えていくといったことをすることもあります(PandasやNumPyを良く使っていたコードの箇所で、DaskやVaexを検討するなど)。
諸々の処理のコードなどの保守性も意識する
※注記 : プロダクション環境のスクリプトなどの話となります。例えばJupyterのノートブックなどもそうですが、色々試行錯誤したいタイミングでテストだ、Lintだ、docstringだ・・・と(使い捨てのノートブックなどで)気にするのは非効率なケースも多く、そういったものは以降の節では含みません。
- notebookはあくまでもアドホックな「らくがき帳」「試行錯誤するためのサンドボックス」である*12
- 「よっしゃこれはイケるぞ!」ってなった段階でちゃんとしたプロダクトのコード(テストコードを含める)に落とし込むべき
データ分析者たちのコードレビュー #とは - 散らかったJupyter notebookを片付けるかどうするか問題を考える
集計やETLの処理などは日々増えていきます。弊社の場合、集計以外の内製・補助的なツール部分・施策やRCTの実行など諸々を全て含めるとデータ基盤のプロジェクトがこの記事を書いている時点でファーストコミットから7年目、10000弱のコミット、Pythonのdocstringやテストなども含めたスクリプトが約36万行ありました。
ゲーム業界の各プロジェクトが長期戦がデフォルトな件・且つ弊社の場合データ基盤が各プロジェクト横断的に担当しているため、社内の中でも大分長期プロジェクトになっています(多くのベンチャーが10年未満で無くなることを考えると、1つのプロジェクトで7年って大分長く感じます・・・)。
そうなってくると人の異動なども勿論発生しますし、半年前のスクリプトなどは自分が書いたものでも記憶が曖昧になってきたりもします。他の人からみても自分が後で読み返しても、瞬時に内容を把握できる読みやすいスクリプトやSQLなどである必要があります。
長時間かければ読めるという状態だと、スクリプトやらが膨大になってくると作業効率的に辛くなってきます。なるべく瞬時に理解できるという状態が理想です。
特にデータエンジニアという職種は会社の規模にもよりますが、通常のゲームクライアントのエンジニアさんやweb業界でのフロントエンジニアさん、サーバー・インフラエンジニアさん達と比べると少人数になりがちです。
数人といったケースや、場合によってはベンチャーなどで人数が少ないフェーズでは1人、もしくは専任のデータエンジニアが0人でサーバーサイドの方が兼任というケースも結構あるかもしれません。なるべく人数が少なくても効率良く仕事をさばけるようにすることが大切です。
読みやすいコードにするため、Pythonのスクリプトであればdocstringをしっかりと書く・1つの関数で循環的複雑度(or認知的複雑度)などが高くならないようにしたり行数を短くしたりして、テストなどが書きやすいものを多くする・各種Lintを利用する・型アノテーションを利用する・他の方の事前のレビューを挟むといったことが挙げられます。
データセット(データレイクやDWHなど)であればメタデータをしっかり保守するという点も含みます。
普通のプロジェクトで必要になるものに似たようなものが多めですが、集計やETLのコードでも長く保守するものは同様にコードを綺麗に読みやすくするためのものは可能であれば導入しておくといいと思います。
弊社のケースであれば、以下のようにやっています。
docstring
基本的に全てのコードに対してNumPyスタイルのdocstringを書く形で進めています。
この辺りの書き方は自分でも以前記事にしているので、同僚の方にそちらを確認いただいたりしています。
[Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル)
また、「うっかり書き忘れていた」「コード書き換えていたらうっかり引数などのdocstringがずれていた」といったケースも結構発生します。Pythonスクリプトでテストを基本的に書く形で保守している都合、気軽に変更がデプロイできるのでコードの頻繁な変更も入ったりしており、その分docstringとコードの内実がずれたりが発生しがちです。
この辺りは人の目だとミスを見落としたりしがちなので、本番反映される前にCI的にdocstringのLintを通してからデプロイされていく形で運用しています。
NumPyスタイルのdocstringのLintは要件に合うものが見つからなかったため自作しています。
NumPyスタイルのdocstringをチェックしてくれるLintを作りました。
プロジェクトの途中からこのLintを入れたのですが、docstringの記事を自分で書いておきながらLintをプロジェクトのスクリプトに反映したら自分で書いたコードでも結構Lintに引っかかる点が見つかりました。人の目に頼らずにLintを通る環境にしておくことが大事です(自戒)。
また、複数人で作業する際にもLint任せでdocstringの不足やずれなどのチェックがレビューで不要になったのでその辺りも負担が減って良かったなと思っています。
循環的複雑度(or 認知的複雑度)や行数について
ifやらtry-exceptやらforやらがたくさん入れ子になっていたり、1つの関数やメソッドがとても長いと読むのが大変ですしテストを書くのもハードモードになってきます。
スクリプトだけでなく、他人が読んだり引き継いだりするのが無理ゲーに感じられる複雑なSQLも同様です。
そういったスクリプトを避けるために、循環的複雑度(cyclomatic complexity)という指標があります。
循環的複雑度とは、ソフトウェア測定法の一種である。Thomas McCabe が開発したもので、プログラムの複雑度を測るのに使われる。プログラムのソースコードから、線形的に独立した経路の数を直接数える。
循環的複雑度 - Wikipedia
以下の記事が循環的複雑度について分かりやすくまとめていらっしゃいます。
記事にある通りifやらforやらが関数内などで増えていけばその分読むのが辛く、テストなども書きづらくなってきます。体感的には関数1つで複雑度5以下、docstringなどを除いた行数40行以内くらいのものが大半になっていると快適だなぁと感じています。
ただし、テストの書きやすさに関してはprivateのものに対してもテストを書くか / 書かないかによっても変わってきます(publicのものにだけテストを書く場合はprivateのものを細かく関数分割してもあまりメリットが少ないなど)。
privateのものにテストを書くかどうかは、privateのものにテストが書きやすい言語かどうかなども絡んできますし、プロジェクトごとの選択次第でどちらが正解というものでもないと思っています。
Pythonの場合はprivateの場合は関数名やメソッド名の先頭にアンダースコアを付けるだけの運用(Pylanceなどでprivateのものに対してチェックの挙動が変わったりはするものの、実際には外部からはアクセスができます)となるため、テストモジュール側からもprivateのものへのアクセスはでき簡単にテストは書けるので書く形で運用しています。
複雑度の低いprivateのものに細かくテストを書くことで、個々のテストの関数がシンプルになりますし、問題が出た時に問題箇所の特定が素早くできるなどのメリットは享受できています。この辺りはプロジェクトに応じてベストなやり方を選択ください。
弊社プロジェクトの現状ですと明確にLintで縛ったりはしていませんが、ぱっと見で複雑度が高そうであれば直したりレビューでコメントしたりといった形で運用しています(近いうちにLintの導入を検討する、といったissueは登録されている段階)。
Lintなどで運用する場合には循環的複雑度をチェックしてくれるflake8のプラグインなどもあります。
また、JupyterLabなどであればLanguage Server Protocol用の拡張機能などで組み込まれていたりもします。
- Language Server Protocol integration for Jupyter(Lab)
- ついにJupyterLabの入力補完??Tab押さずに補完してくれるjupyterlab-lspを試してみた
また、循環的複雑度よりかはもっと新しいもので、認知的複雑度(cognitive complexity)という指標も存在します。
Cognitive Complexity でコードの複雑さを定量的に計測しよう
たとえば、
if ... :
if ... :
if ...:
for ... :
...
といったコードと
if ... :
return
if ... :
return
if ... :
return
for ... :
...
みたいなコードでは、循環的複雑度では複雑度が同じですが、人からすると前者の方が読みづらいコードになります。認知的複雑度だと人にとっての感覚に近い形で複雑度がカウントされるので、前者の方が数値が高くなります。
flake8の拡張機能のものも含めて、ライブラリはいくつかPyPI(pip)に登録されています。
各種Lint
弊社のプロジェクトの場合、ETLやら集計などのを扱うPythonスクリプトに関してはコードを綺麗にしたりスタイル統一のために以下のLintを導入しており、一通りのLintを通ってから本番にスクリプトが反映される形で運用しています。
- autoflake -> 使われていないimportやローカル変数などの自動削除
- autopep8 -> 修正ができる範囲での自動のPEP8を準拠する形へのスクリプト変換
- isort -> PEP8に準じる形でのimportの整形
- flake8 -> autoflake、autopep8、isortを通しても引っかかるPEP8の点のチェック
- numdoclint -> 前述のdocstringチェック用
Blackなど含め、他にも色々Lintは世の中にありますのでプロジェクトに合わせて好きなものを選択いただければいいと思います。
PEP8に関しては以前記事を書いているので、そちらを同僚の方に共有したりしています。
[Pythonコーディング規約]PEP8を読み解く](https://qiita.com/simonritchie/items/bb06a7521ae6560738a7)
Lintでどのように更新されたり引っかかったりするのかを日々見ていると、「規約的にどのように書くべきなのか」「このルール間違って認識していた」といったことに気づけて勉強になります。
また、コードスタイルが強制的に統一されていくので、複数人で作業しても似たようなコードになってきて他人のコードでも読みやすくなります(人による癖などが減り、プロジェクト全体で統一感が増します)。
Lintに任せられるところはチェックを省けるので、コードレビューなどでの負担も減ります。
途中からLintを加えていくのもアリ
既にスクリプトなどが稼働中の場合、途中からLintを入れるのに抵抗がある・・・といったケースもあるかもしれません。
弊社のプロジェクトでも、私は途中からプロジェクトに参加しましたが、当時はLintが導入されていませんでした。
各種Lintは途中から入れたのですが、以下のように入れていきました。
- モジュール(スクリプトファイル)単位で、各Lintで有効にするものを設定できるようにします。
- テストの追加が終わっているモジュールに対して、問題が無さそうであればLintを有効にする設定を追加します。
- Lint有効化の設定がされたモジュールのLint反映結果がテストを通ることを確認します。
- テストが無いモジュールに関してはLintの追加を後回しにします。
- ※現在はほぼほぼのテストカバレッジが確保されていますが、当時はテストが無いモジュールもかなり存在していました。
- ※テストが無いモジュールに関しては、Lint有効化よりも先にテストを追加する方を優先します。
こうすることで日々少しずつLint設定が有効化されたモジュールが増えていく形となり、一気にLint反映・・・とならない(小出しに変更が細かくデプロイされていく)ですし、テストを通っているので一層安心して進めることができます。
また、小出しにLintを導入できる形にしたので、新しいLintの追加なども気持ち的なハードルが下がり、複数のLintの導入に繋がっています。
加えて、日々各Lintの有効化されているモジュール数のカバレッジを通知するようにしたり、各Lintで有効化されていないモジュールはどれなのかがすぐに確認できるようにしていました。
少しずつLintのカバレッジが高くなっていく推移を毎日眺めつつ過ごすのも、闇雲に進めるよりも進捗が分かりやすくて気持ち的にプラスに働いた気がします。
型アノテーション
Pythonなどが静的型付け言語ではないので、型を書かなくても動きますが、やはり型情報を書いてリアルタイムにチェックなどが走っていると、事前にミスに結構気づくことができます。
もしPythonなどを結構使われている場合には、積極的に利用するとより堅牢・保守しやすいスクリプトになります。
このあたりの型アノテーションは以前記事を書いたり、他の方が書かれていたりするので引用やリンクだけ貼っておきます。
Python は、動的型付けを備えているから楽しいという部分もあるかもしれませんが、全体を見通しにくくなる場合があります。
...
静的型チェックの鍵は、規模です。プロジェクトが大きくなればなるほど、静的型チェックの必要性を感じるようになります(最終的には必須になります)。
...
型チェッカーは大小問わず多くのバグを見つけます。「None」 値などの特別な条件の処理が忘れられているような場合が、よくある例です。
Python の型チェックが 400 万行に到達するまで
- Pythonではじまる、型のある世界
- 入力補完を充実させ、より堅牢なPythonコードのための型アノテーションとPyright入門
- [Python]PylanceのVS Code拡張機能をさっそく使ってみた。
- Pythonで型を極める【Python 3.9対応】
なお、最近の3.9や3.10のPythonバージョンでも色々型アノテーション関係のアップデートが入っています。もしアップデートが現実的な場合には新しいPythonバージョンの方が色々便利だと思います。
データセットのメタデータ
データレイクやDWHなどのデータに対するメタデータ(テーブル説明やらカラム説明やら、データ更新タイミング、補正の入ったタイミングの情報など)の資料の保守は大切です。
普段の作業で資料がないと結構データの把握で時間がかかってしんどいですし、データを誤解して集計をミスするといったリスクも高まります。
新たにアサインされた方のキャッチアップのしやすさ的にも、しっかりログなどに更新が入ったタイミングで資料をアップデートしていくことが大切です。
メタデータの資料が無いと謎のテーブルがたくさん量産されている、削除していいのか判断が難しい、ディスクコスト的に無駄が多い・・・といったことも発生するかもしれません(集計用の中間テーブルなどで)。
この辺りはクラウドサービス側でも用意されていたりもしますし、うまいこと保守できればやりやすい形でいいと思います。ただし共有サーバーにエクセルで資料を置くといった対応は保守されなくなるケースが経験的に多めです(n=4くらい)。
エクセルでの保守が厳しそうであれば、「更新が楽」「開くのに時間がかからない」「ファイルが乱立しない」「検索のUXが良い」「できたらバージョン管理して欲しい」辺りを意識しつつ良さそうなサービスやツールなどを選択するといいと思います。
ごく短時間で更新が終わらせられるといった点が、ちゃんと保守されるかどうかに絡んでくるので検索してすぐ見つかる・すぐ開けるといった点も大事です。
弊社の場合、会社の都合でGCPのBigQueryではなくAWS環境を使っています(その辺りは後々触れます)。
Athenaなども利用しつつ、同じデータソースでS3をマウントしたりしてPython(PandasやらDaskなど)でも直接扱えるようにしています(SQLだけでなくPythonを使って色々できると楽なので)。
また、データの扱いもDjangoのORM的に扱え(内部でDaskなどを使いつつ)、モデルを追加する(DWH的なところにテーブルを追加する際など)には「メタデータを追加しないとモデルが定義できない」形にしてあります(且つ、モデルを追加するとAthena側でのテーブル生成やパーティション更新などが自動でされるようにしてあります)。
モデルを指定するとメタデータのマークダウンが出力できるようにもしてあり、これによってDWH環境にテーブルを追加する際にメタデータの追加を忘れるといったことが無い形で運用ができています。
プロジェクトごとの個別のデータ基盤にするべきか?社内横断的なデータ基盤にするべきか?の話
プロジェクトごとに個別にデータ基盤やらBIなどの環境を組むか、もしくは独立したデータ基盤のチームが担当して、各プロジェクト共通の基盤にするべきか?というトピックが話に出ることがあります。
これに関しては様々な意見があるでしょうし、私もいまだに正解がどちらなのか分かっていません。弊社だと横断的に共通基盤で対応しており、個別に作るケースを経験したことがありませんので参考程度となりますが、個人の主観によるメリット・デメリットに触れておきます。
共通基盤にする場合のメリット
ぱっと思いつくもので以下のようなメリットがあります。
- 2個目以降のプロジェクトの対応が楽
- 人やプロジェクトによる些細な集計の違いによるズレが起きづらい
- 他のプロジェクトのログで、まだ試していないものの傾向が調べられる
- 人のプロジェクト異動の際の学習コストを抑えられる
それぞれ細かく触れていきます。
2個目以降のプロジェクトの対応が楽
弊社の場合ゲーム業界なので、各プロジェクトで共通で確認が必要なKPIというものが色々存在します。
それらの集計のコードは各プロジェクトで共通で回してあり、可視化なども含め共通コードで処理されています。
そのため新規プロジェクトの対応依頼が来たときにはデータレイクなどに送っていただいているログを参照してETLを行い、各プロジェクト共通のフォーマットのテーブルを追加するだけで様々なKPIの可視化まで含めたダッシュボードやその他のBIツール上の機能の対応が終わります。楽です。
特にゲーム業界だとリリース直後に広告などを頑張ったりする都合、リリーススケジュールがずらすのが難しかったりするものの、一方でデータレイクのデータ対応が結構リリースギリギリになったりもするケースがあるのでリリース前にさくっと対応が終わるというのは大切です。
また、既に他のプロジェクトで経験を積んだメンバーが他プロジェクトも担当することになるので、「どんなKPIが必要なのか」「どんな作業が必要なのか」「どんなことに気を付ける必要があるのか(リセマラユーザーやらbotやら不正ユーザーやら)」といった点で経験値が溜まっているというメリットもあります。
人やプロジェクトによる些細な集計の違いによるズレが起きづらい
集計などをする方が各プロジェクトで別だと、ちょっとした集計の差やログの差で結果が結構ずれてしまいます。
例えばAプロジェクトではリセマラやbotの判定を〇〇する形でやっているけど、Bプロジェクトでは××の形で集計している、といった類のものです。
密にコミュニケーションを取らないと人によってKPIの細かい定義の差が発生することもあります。
また、密にコミュニケーションを取っていても〇〇のフィルタリングを入れるタイミングがAさんとBさんで微妙に違ったため数値が合わない・・・といったことも発生したりで、ちょっとしたSQLやスクリプトの内容の差でずれたりもします。
このズレは世間が思っている以上に発生しやすく、ぴったり合わせるのは大分骨の折れる作業になります(特に複雑な集計になるほど)。
また、ズレていると会社としての意思決定のミスにも繋がりかねません。
(例 : AプロジェクトはROASの数値が良かったのでAプロジェクトに広告費を多く使ったものの、実はAプロジェクトの方が有利な集計内容になっていて本当はBプロジェクトの方が広告回収効率が良かった等)
ズレた時に「なんでずれているの?」と各所から質問が来たりもしますがその説明も結構負担になります。
データエンジニアリソースが不足しがちなことを考えると、この辺りのコミュニケーションコストの負担はなるべく抑えてるためにも、大部分の集計コードやSQLなどは各プロジェクトで共通化できるとズレが少なくできて楽です。
人のプロジェクト異動の際の学習コストを抑えられる
これはまあ・・・会社でツールやサービスを統一すればいい話ではありますが、一方で日頃新しくイケてそうなツールやサービスなどがどんどん生まれているのも事実です。
「新しいプロジェクトでは〇〇を使ってみよう」という話が出るのも良くあることですし、そういった新しいものを積極的に試すことも大切だと思います。
一方で日々忙しくしているブロデューサーの方やプランナーの方からすると、ツールの使い方の勉強時間はなるべく抑えて企画などを考えるのに注力したい・・・という意見もあるかもしれません。
各プロジェクトであまりに使うツールやサービスがばらばらになりすぎると、異動時のキャッチアップが少し大変かもしれません。
共通基盤・共通ツールだとその辺りの学習コストが抑えられますし、過去のプロジェクトでのツール上での設定や記述なども使いまわしたりもすることができます。
ただし古いものを使い続けることになりがちなので、この節の内容に関しては光と闇の両面がありそうです。
他のプロジェクトのログで、まだ試していないものの傾向が調べられる
共通の基盤・同じフォーマットのログデータなどを揃えておくと、リリース前のプロジェクトや未リリースの施策などで、別のリリース済みのプロジェクトの内容や施策結果がどうだったかなどを他部署の方が分析したりといった利用もすることができます。
実際にAプロジェクトの方がBプロジェクトの数値を見たり分析をしたりといったことは弊社でも見受けられます。
すぐに複数プロジェクトで比較したりもできるため、例えば役員の方が横断的に比較したいといったときにさくっと切り替えが出来るなどのメリットもあります。
共通基盤にする場合のデメリット
デメリットの方は以下のものがぱっと思いつきました。こちらもそれぞれ詳しく触れていきます。
- 技術が固定化されがちで、新しい言語やライブラリへのアップデートが大変 / 新しいサービスの利用がやりづらい
- プロジェクトが増えてくると、少人数のチームで回すのが大変になってきそう
技術が固定化されがちで、新しい言語やライブラリへのアップデートが大変 / 新しいサービスの利用がやりづらい
新しいプロジェクトでは過去のしがらみが少ないので新しい技術やサービスなどを試してみる・・・という選択肢が取りやすくなります。
また、プロジェクトの終了に伴い基盤も停止させたりする場合には保守の負担も減ります。
一方で共通基盤とすると、年数経過でデータ量・データの種類・スクリプトやSQL・可視化結果などがどんどん増えていきます。
弊社もたくさんのPythonスクリプトがありますが、動いているそれらを維持したまま新しいバージョンにしたり、古いデータ環境を切り落としてもっと優れて安いものに引っ越ししたり・・・といったことは必要になったりします。中々骨の折れる作業です。
そういった移行作業などの際に前述したテストをしっかり書いているかどうかが結構響いてきます(というよりもテストが無い場合・もしくはカバレッジが低い場合移行が出来る気がしません)。
稼働中のものになるべく障害やダウンタイム的な影響を出さずに切り替えや切り落としなどを進めていく上では、ストラングラーパターン的な対応をしたりしていますが、新規プロジェクトで新しいサービスの利用を進めるケースよりも負担が大きいことは間違いありません。
結果的には共通基盤にすることで基盤の寿命が長くなり、古い部分が結構出てきてしまったり、新しくする人的リソースが確保できなくなる(そこまで手が回らない)可能性は出てきます。
便利そうなツールやサービスは新しいものがどんどん出てきていますし、同じクラウドでも新しいサービスが日々出てきています(特にAWSはサービス多すぎ感が強い)。
もしくはプロジェクトの海外展開で、中国展開が必要だけどGCPの中国リージョンが無いからAWSにしようとか、逆に今後はGCPの便利な機能を使ってGCPメインにしていこうとか、Office関係と連携を楽にするためにAzureメインにしようといったようなクラウド自体の引っ越しも起こり得るかもしれません。
BigQueryだけGCP、他AWSみたいな選択は多いと思いますが、会社の管理面などの都合でマルチクラウドではなくAWS/GCPどれかに統一しようとかそういった選択をする会社もあると思います。
これらを加味すると、切り替えや新しいものの利用が気軽にできないというのはデメリットに感じます。
プロジェクトが増えてくると、少人数のチームで回すのが大変になってきそう
複数プロジェクトを横断的に対応していると、質問や要望などで多方面からチャットが飛んできます。
各プロジェクトのプロデューサー・ディレクター・プランナーの方々からの質問や要望であったり、マーケの方からのものだったり、役員の方からの質問や依頼だったり、各プロジェクトのエンジニアさんとのやりとりだったりと様々です。
プロジェクトが増えてもデータエンジニアが増えればまあ何とかなるかもしれませんが(あまりに人数が多くなったらチーム分けたりは必要になるかもしれませんが)、基本的にはプロジェクトが増えたタイミングでデータエンジニアが増えたり・・・はしないことが多いと思います。基本的には今の人的リソースで何とかするといったケースが多いと思います。
また、プロジェクトが増えなくても日々データが積みあがって増えていったり、集計のスクリプトが増えていったりもします。
今の所私はほとんど残業せずに、有給などもしっかり取る形で過ごせていますが、今後のプロジェクト増などで状況が変わってくる可能性もあります。負担が各プロジェクトに分散せずに、共通基盤部分に集中していってしまうというのは一応デメリットではあるかもしれません。
使い方研修をしなくても色々な人に使ってもらえるUIを目指す
話は変わってUIなどの話です。元々デザインの学校を出てデザイナーのお仕事をしたり、ゲームのクライアントエンジニアをしていて「演出こだわるの楽しい!」といった経歴なので、弊社の場合BIツール部分が内製になっておりUIや見せ方にこだわるのは楽しい作業です(ちなみに同僚の方も元ゲームクライアントの方でセンスが凄いという・・・)。
BIツールが使いづらいUIだと中々社内の利用率が上がってくれません。研修などをして使い方を覚えていただく・・・というのも良いのですが、入社や退職などによる人の異動もあり頻繁に研修を入れるというのも、人数の少ないデータエンジニアで回そうとすると大変です。
UI面では以下のような点を意識しています。
大事な各プロジェクト共通の様々なKPIのダッシュボードはページを開くだけで理解・利用できるようにする
なんだかんだ重要なKPIダッシュボードは開くだけで大半を理解できて利用できる状態が理想です。
なんでもかんでも詰め込めばいいというものでもありませんし(大事なデータが見えづらくなる等の面で)、逆に足りなくて俯瞰しづらいといった状況も良くありません。
皆さん日々忙しくお仕事されているので、1ページで色々大切な数字や可視化部分が過不足なく俯瞰できることが大切です。
このダッシュボードは利用率が高く、職種も様々な方がアクセスしています(役員・プロデューサー・ディレクター・プランナー・マーケ・エンジニア・デザインナー・バックオフィスの方など)。
探索的にデータを深堀りしたり分析したりされている方も勿論いらっしゃいますが、利用率的にはここがやはり大きいのでしっかり力を割くべきところでもあります。
分かりやすく、見えやすいデザインのUIにしたり、統一感のある配色にしたりなどこだわりたいところです。また、定性的な感覚になってしまいますがあまりにデザインが古臭すぎてもよくない気がする(ユーザーからしたら、このツールは技術力的に信用できるのか・・?と感じられてしまったり)のでその辺りも初心者っぽい作りに見えないようにある程度はしっかりしておきたいところです。
非デザイナーの方でも、ノンデザイナーズ・デザインブックといった昔からあるロングセラー本も含め色々本が出ていますしそういった領域を学んでみても面白いかもしれません。
また、会社によってはカラーユニバーサルデザイン的に可視化の配色をこだわったりも有益かもしれません。
この辺りはGoogleの方が書かれたStorytelling with Data: A Data Visualization Guide for Business Professionalsとかのベストセラー本なども参考になるかもしれません(ちなみにノンデザイナーズ・デザインブックに出てくるような内容はこちらにも出てきます)。
国内だと先日バズっていたGoodpatchさんの決算資料に対する記事の【パワポ研の決算資料探訪①】Goodpatch社の決算説明資料はシンプルが故に美しいなども良くできていて素敵で参考になりました。
複雑な機能でもなるべく分かりやすくするように頑張る
ダッシュボードだけでは勿論不足していて、データを深堀りしていったりが必要な方々もいらっしゃいます。
そういった方のために、SQLやスクリプトを書かなくてもGUI操作だけで色々条件を変えて集計したり自動でマスタ連携してくれたり、さくっと可視化したりが出来るようにしてあります。
Metabaseのクエリビルダー的なものに少し傾向が近いかもしれません。
OSSのデータ可視化ツール「Metabase」が超使いやすい
一方で、ページを開けば使えるダッシュボードとは異なり設定のUIはどうしても多くなってしまうので、ユーザーにとっては使いづらくなってしまいがちです。
そのため、なるべく使い方研修やらを入れなくても使えるように、各UIにマウスオーバーするとヘルプを表示してくれたり、詳細なヘルプも各UIパーツの右上のアイコンをクリックすれば表示できるといったように「なるべくヘルプを身近な存在にする」という点は意識しています。
別ページで長々とヘルプのページを追加する・・・というのも悪くはないのですが、検索で探したり他のページに遷移したりに時間がかかるのも良くありませんし、大抵の場合皆さんご自身の仕事を忙しく担当されているので、ヘルプが遠いと大抵のケースで読まれません。
ヘルプが読まれないと質問がデータエンジニアに飛んできて良くありません。その辺りはなるべく親切に・・・というところは心がけています(まだまだ改善点は残っていますが・・・)。
また、年数経過で、様々な要望などに対応していった結果UI要素が増えていって初見のときの難しさなどを招いたりもするので、BIツールの各機能の利用状況などを確認して使われていない機能の切り落としを行ってシンプルにするという対応も大切です(分析基盤自体の分析と改善を行ったり等)。
日本語のUIは意外と馬鹿にできない
会社にもよりますが、BIツールのUIが日本語で、お知らせやヘルプもしっかりと日本語で確認できるといったことは社内の利用率を上げる上で大切かもと思っています。
エンジニアとして仕事をしていると「UI別に英語でもいいよね」と感じてしまいがちですが、非エンジニアの方がユーザーとなるため、ユーザーフレンドリーという面でいうとできたら日本語UIのものだと利用率の改善的にいいかなという印象ではあります(英語でよく分からないUIがあると敬遠されがちになったり等)。
各部署の方が英語に抵抗の無い方である会社であれば特に意識する必要はありませんが、そうでは無い場合は日本語対応しているツールやサービスを検討するというのもいいかもしれません。
なるべく社内の利用者の方の要望をスピード感を持って反映していく
BIツール部分などを内製している都合、機能やデータなどに対して要望をいただくことも結構あります。
差し込みタスクになったりするのでしんどい時もありますが、そういった要望を出してくださる方は結構ヘビーユーザーになってくれたりするのでなるべく要望に答え、スピーディーに対応していきたいところです(数か月後に対応などだと遅すぎで、施策などのためにすぐ欲しいといったケースも結構あります)。
外部のOSSやらサービスだと中々すぐに変更を加えたり要望を受け入れてもらったりは難しいケースも多いと思いますが、この辺りが素早く対応できるのは内製の強みではありますし楽しさでもあります。
ライトなものであれば要望をいただいてから数時間で、コードを書いてLintやテストなどが通るのを確認して本番反映・・・とできることもあります。
弊社も例に漏れずごく少人数のデータエンジニアのチームで回していますが、細かくアップデートで1日平均3デプロイくらいはしているのでペース的には悪くはないかなという感じではあります。
この辺りのデグレなどを抑えつつ長期プロジェクトでスピード感を落とさないためにもテストやLintの仕組みの有無が響いてきます。
SQLをユーザーの多くの方に学んでもらうのは正解か分かっていない
データの民主化、素晴らしい事だと思います。各社員がSQLを書いて分析するというのも素敵に思います。クックパッドさんみたいにデザイナーも分析するといったケースや、ワークマンさんの各社員が分析のスキルを身に付けるというのもいい話に思います。
他にも、社内の方からも「プランナーがSQLなどで分析できるようになってスキルアップすることは良いことだ」という話も聞いて、そういったところは特に反対意見も違和感もありません。
一方で、全員がSQLを書けて分析が出来るものを目指す・・・というのも100%正しいとも限らない・・・という所感も最近しています。
きっかけはとある社内のディレクターの方がおっしゃっていた「退職や異動などでSQLやスクリプトを引き継ぐのが厳しいので今後はGUI完結で進めていきたい」というものになります。
たしかに普段からSQLやらスクリプトやらを書いている私でも複雑なSQLやスクリプトなどを引継ぎで渡されてしまうとちょっと辛いと感じることもありますし、普段SQLを書かれていない方からすると引継ぎなどが大変そう・・・というのは想像できます。
そういったことを加味して「BIツールはGUIで自動化など含めなるべく完結できるようにしようか・・・」という気持ちが強くなっています。
エクセルで複雑で謎のスクリプトなどが組まれていて、作った方は退職済みだけど触らないといけない・・・とかに似たようなケースと言えるかもしれません。
以下の記事も参考になります。
みんなSQLが書けることを自慢している会社もあるけれど、本当にそれでいいのだろうか
データの民主化が悪と言うつもりはなくて、「何となく良さそうだから中途半端に手を出す」というのがあまり良くない結果になるかも、という印象です。
データの民主化を進めるにしても、
- ちゃんと業務時間でしっかり研修を(場合によっては復習として繰り替えし)やる余裕がある会社
- 保守の難しい謎のSQLが大量生産されないようにしたり、集計ミスを減らすためにSQLレビューのプロセスなどを整備する
- 会社の評価や昇進などの面で、SQLや分析などのものを組み込む
辺りがしっかりとしているといいかなぁと思っています。環境やら制度やらが整っていないと、Redash環境とかを整備しても中々社内利用が進まないかもとは社内で話しています。
エクセルなどの非構造化データをETLなどで扱うのは結構辛い
仕事の大半の扱うデータに関しては処理しやすい構造化データです。
一方で、社内でコントロールがしにくい契約先の企業から送られてくるレポートなどがエクセルなどのフォーマットになっているケースがありました。
一応PythonなどでもエクセルやらPDF操作用のライブラリも色々ありますが、実際やってみると大分しんどかったです。
というのも、会社ごとにフォーマットがばらばらで、同じ会社からのエクセルレポートでもフォーマットやファイル名・シート名がばらばらだったり、データが開始する箇所がばらばらだったり・・・と、やってみると分岐される条件が膨大になりました(且つ、すでに年単位でエクセルファイルが大量に溜まっていたりが発覚したりと・・・)。
結局、手を出したはいいもののかなりの労力が必要になりましたしETL対応している間に契約が終了になったりと、辛い経験だけで終わりました。
非構造化データのETLなどは安請負せずに相当な覚悟を持って受けるべきだなと反省しました。
基盤の利用状況のアクセスログを取っているとモチベに繋がる
データ基盤自体が他のプロジェクトのログを使って分析する環境ではありますが、分析基盤自体の社内の方の利用状況などもログを取って色々見てみるとプラスになることがあります。例えば以下のようなメリットが挙げられます。
- どの機能がよく使われているのかが分かるので、注力すべき点が分かる。
- 逆にどの機能があまり使われておらず、切り落としてUIをシンプルにできそうかが分かる。
- 利用者の増加や色々な部署の方が使ってくれたりしているのが分かり、闇雲にデータ基盤やデータ整備の仕事をしているよりもモチベが維持しやすい。
基盤やBIツール環境も整えて終わりではなく、ログを見て常に改善のサイクルを回していけたらいいなと思います(気合を入れてダッシュボードなどを用意しても、全然利用されないと辛いですし)。
施策とかにまで手を出せるといいかもしれない
データエンジニアリングの領域では無い気もするのですが、以前の上司の方が色々部署間の調整をしてくださったり改善の指摘をしてくださったり、同僚の方がAWSでの連携などを対応してくださったりして、分析基盤から社内のプロジェクトに対して施策が実行できるようにしたりも比較的最近のアップデートとして入ったりしました。
アプリ側のアップデート無しで「RCT(ABテスト)での施策実行」 → 「ログ蓄積」 → 「MCMCなども使った効果の色々な可視化」といった一連のものを基盤環境で完結できるようにしてみたりしたのですが、結構試験的なものでしたが案外アリだなという印象を受けました。
RCT実施の前には連絡を入れたり社内プロジェクト側の方に確認と許可をいただいたりは必要ですが、多くの領域をコントロールできるようになると機動力高く対応できたりして快適に思います。
これが複数部署絡んで部署間の調整がたくさん必要になったり、アプリ側のアップデートが必要にすると敬遠されてしまったり(皆さん忙しいですし)と大変です。
且つ、最終的にはRCT的に明確に数値改善の効果が出たりもした(何度も何度も調整したり変えたりは必要になりましたが)ので、数値が出ると後々の説得などをするのもやりやすいかなぁと。
外部の部署のメンバーが分析などをしても「分析・提案したけど施策や実験まで中々落とし込んでもらえない」「分析が無駄になってしまった」みたいなケースは結構あると思っていまして、逆にプロジェクト内の方だと「エンジニアリングにあまり詳しくない」とか「分析にそこまで精通していない」といったケースもあると思います。
そういった面でも施策まで全部セットでコントロール下におけるというのは今後も少しずつやっていきたいところです。
古いシステムへの敬意を
社内の分析基盤関係のプロジェクトが7年目とかになっていますが、それだけの年数があると、初期のころのものなどが結構長期的に悪影響を出したりといったケースも結構あります。
私の方も途中からの参加・引き継ぎだったので結構苦い思いもしています。前任の方が部署にいない状態で、一人情シスならぬ一人データエンジニアで対応しないといけないといったケースを体験して、ブラックボックス化しているものも苦労しつつも色々触ってきました(今は幸い、凄腕の同僚の方に恵まれています)。
しかしながらこれだけ長いこと(社内の中でもトップレベルに長いのではという印象)使われてきたというのは素晴らしいことですし、「如何にしてなるべく安全に改善していくか」といったところなども含めとても勉強になっています(中々できない経験だなと)。
どうか先人を否定しないようにしてください。その開発者は無茶ぶりされながらも奮闘した新人だったかもしれませんし、その頃には今となっては周知のベストプラクティスが存在しなかったのかもしれません。何より「役に立たないコードより、役に立つクソコード」は一つの真実です。
ブラックボックス化したデータ基盤を作りなおすことを決意した貴方へ
ここまで長期に続いてることに敬意を表しつつ、たくさん問題があるということは改善し放題です。諸々を新しくしたりより良くできたりすると中々嬉しいですし楽しいので、案外そこまで悲観しなくてもいいのかもしれません。
※比較的ポジティブにお仕事ができているのは、技術とコードのところや仕事の進め方などの選択はほぼほぼ裁量があるという環境なのも大きいかもしれません。
データエンジニアの仕事を担当してみて、大分成長できた気はする
データエンジニアチーム、社内の中では少人数のチームになりがちです。少人数だと自分で色々な分野を扱わないといけなくなります。
弊社の場合エンジニアでも申請すればCreative Cloudなどは使わせてくれるのと、BIツール部分などは内製していたりするので、デザインツールを扱って自分達でデザインカンプを作ったりお洒落にしたりまでしている(これはこれで楽しい)ので、その辺りまで含めれると大分広い技術を扱っている気がします。書きだすと今の所以下のような感じでしょうか。
- Linux関係(CentOS・Ubuntu)
- Python関係
- Python界隈のライブラリ(NumPy・Pandas・Dask・matplotlib・Jupyter・scikit-learn・PyMC・Django・たまにディープラーニング方面のものなど)
- webサーバー関係(Nginx・gunicornなど)
- Docker関係
- クラウド関係(AWSメイン・稀にGCP。S3・EC2・Athena・Aurora(移行検討中)・Firehose・etc)
- DB関係(RDS・NoSQL)
- HTML・CSS・jsなどのフロント関係(古いのでTypeScript移行検討中)。D3.jsなども。
- CI/CD周りのツール群
- 監視系のツール群
- Adobeを中心としたデザインツール
担当するまではゲームのクライアントエンジニアなどをしていてサーバーサイドやらインフラ周りなどは別のエンジニアさんが担当してくださっていたので、一人データエンジニア担当になった時には「Linux聞いたことはあるけど(言葉通りに)ナニモワカラナイ」「Django?なにそれ美味しいの?」状態でした。
※当時はDjangoの和書もほとんどないタイミングでした。
人間、必要に駆られるととても成長できるような気がしていて、デザイナーからエンジニアのお仕事をし始めたころもそうですが結構知らないことが多い領域に飛び込んでみるのもたまにはいいなと思いました。
気が付いたらPython関係は大分詳しくなった気もしますし、Qiita関係もたくさん勉強でアウトプットしてこれた気もします。
自分で色々な技術を触れるというだけでなく、独立部隊としての側面が強く技術選択なども自分達に裁量が結構あります。
他にも朝の始業前に諸々の膨大なデータに対して大量の処理をなるべく落ちずに安定して流れきっている必要があったりと、パフォーマンスやプチSRE的な(あくまでライトな範囲ですが)ところも必要になったりもします。
データエンジニアリングだけでなく、ビジネス的な知見もある程度身に付いたり、データサイエンス方面もある程度勉強する機会に恵まれたりもしています。
この辺りはデータ界隈で有名なゆずたそさんも記事にしていらっしゃいますが、私も同感なところもあり色々技術的にチャレンジができたり勉強すべきところが山ほどあるというのは楽しいし合っているかもなぁとは思っています。
趣味開発ではなかなか接する機会のない規模のデータを捌くことになります。 ISUCONでのパフォーマンスチューニングや、アドテク・動画配信の基盤担当者に近いモチベーションかもしれません。
「多少作りが悪くても動けば良し」というわけにはいきません。 それゆえか少数精鋭チームで技術力の高い人たちが集まっているように思います。
データ基盤エンジニアの面白さ
地味で泥臭い面も多々あり向き不向きはあると思いますが、個人的にはデータ基盤のお仕事も中々いいなぁという所感です。
長期の開発・保守を担当してみて
頻繁に転職したり新しいプロジェクトに異動させてもらったりも(実際に過去に異動などを何度か経験してみて)学べることは色々あると思います。
一方で、長期的にプロジェクトをどんどん良くして、Developer Experienceを高めていくというのも面白いなぁとここ最近感じています。
少人数のチームということもあり、良くない実装や保守しづらいものを追加してしまうとそのままダイレクトに自分に帰ってきます。
和田卓人さんのスライドでも触れられているように、長期プロジェクトで深くまで携わって改善や機能追加などを対応していくという選択もアリなのかなと。
今後考えていること
データの民主化をして複雑なSQLやスクリプトが量産されると保守がつらい(それに、非エンジニアの方の学習コストを抑えたいという声も聞いたりしているのでGUIベースでなるべく完結できるようにしたい)一方で、分析の柔軟性も確保したい(ただし現状のGUIベースだと結構辛い)ので、将来的にUnrealEngineのブループリント的なビジュアルスクリプティングで柔軟且つ設定が分かりやすくシンプルなものの機能を追加したいな・・・と考えています。
ブループリント例 :
AzureMLのようなものが近いかもしれません。
AzureMLは機械学習をこれから勉強する人にとって最高の環境だった
余談
勢いに任せて色々書きましたが、色々賛否両論あると思います。自身の知識も経験も足りておらず、いまだに色々試行錯誤している感じは否めないのであくまで参考程度にお願いします。