CA Tech Challenge アドテクコンペ~サーバーサイド&データ分析~

こんにちは、京都で学生エンジニアをやっている@pinterTaya です。

今回 CA Tech Challenge アドテクコンペ に参加しました。

インターン概要

こちらを見てもらえばわかるのですが、

www.cyberagent.co.jp

アドテクコンペ~サーバーサイド&データ分析~は、サーバーサイドエンジニアと機械学習エンジニアがチームとなって、ビッグデータを活用した広告プロダクト開発に取り組む3日間のコンペティションです。

というような内容になっています。

インターン参加までの流れ

以前書いた https://taya-intel.hateblo.jp/entry/2019/09/21/142021 の面接時に、アドテクコンペインターンを推薦されて、サーバサイドエンジニアとして参加することになりました。

 

事前

僕の状態

  • アドテクなんもわからん。
  • 広告ってどういうロジックで動いてるの?。
  • WebアプリケーションやCLIツール作る以外でサーバサイド書いたことない。
  • ScalaとかPythonとか書けん。
  • MLとどういう風に組めばええんや。
  • インフラわからん。
  • DSPってなに?
  • 別のインターンで”API余裕っしょ”になったから、単純なAPIならなんとか書ける。

的な感じでした。

アドテクコンペに向けてやったこと

  • GCPでGCEやGCRを少し触る。
  • アドテクについて調べる。(読んだ記事)

adtech.cyberagent.io

インターン当日

1日目

午前

アドテクのインプット(←めっちゃわかりやすかった)を行い、その後すぐにどのようなデータ(何かに関する実データを扱った。。。)を扱うかの説明がありました。

午後

午後が始まるとすぐに、チーム対抗の競技がスタートしました。 僕らのチームはML2人とサーバサイド2人でした。

僕らサーバサイドチームは仕様にあった技術選定やアーキテクチャ構成を考え、負荷がどれぐらいかかるか予想もつかなかったので、調べながらAuto Scalingできれるような設計にしました。(具体的な内容は書いたらダメっぽいので抽象化してます。)

  • MLのモデルに対してデータを入力するようなMainとなるサーバをPythonで書き、それをLBの下にAutoScalingできるように
  • ある特定の処理をするSubとなるサーバをGoで書き、それをLBの下ではなく、別のインスタンスとして1台だけ用意
  • DBとしてGCPのMemoryStoreを用意(GCPのMemoryStoreはRedisのこと)

ざっくりと説明するとこんな感じです。

設計を考えるのに時間がかかり、あとはGo側のサーバを書くのと、Docker周りを触るのでサーバサイドチームの1日目は終了しました。

ML2人はスーパー優秀で、学習のための前処理などでタスクを分割するのではなく、各々が違う方法で様々なアプローチで適切な結果が出るモデルを作っており、軽いモデルは作成できていました。

 

2日目

午前

サーバサイドチームはインスタンスを立てたり、ロードバランサを敷いたりなどのインフラ周りの設定をするので午前は終了しました。

午後

MemoryStoreとGoのサーバを連携できるようにし、Goのサーバをデプロイを行い、Pythonのメインを書かないとやばいって感じで終了で19時になってしまい、絶望でした。MLチームは、学習に2,3時間かかる割と重いモデルを作成し、色々アグレッシブなことができるフェーズに入っていました。

2日目の夜~3日目の朝にかけて

2日目の19時になった時点でサーバサイドチームは様々な問題を抱えていました。

  • ロードバランサがうまく動かない。
  • 十分な負荷テストしていない。
  • メインとなる部分を仕上げていない
  • etc....

とりあえずやるしかないという感じで、寝る暇もなくせっせとタスクを一つずつ終わらせていきました。

 

3日目(13時~)

お昼ご飯を食べ、コンペが開始という時間になりました。

この時間の僕らサーバサイドチームは”インスタンスをスタート段階で20台立ててるし、余裕っしょ。MemoryStoreさえ落ちなければ勝てる気がする。”という感じでした。

そして、ついにスタートのボタンが押されました。

 

スタートのボタンが押されて30s後ぐらいに、LB配下にあるヘルスチェックが通っているインスタンスを見ると

”なんと、20台のうちの3台しか生きていませんでした。。。”

「やばいやばいやばい」って感じでしたが、他のチームもそんな感じで、とりあえず落ち着いて復活させるのと、原因を突き詰めようという感じでしたが、

正直復活させるので手が一杯で、原因を突き詰めれないまま、3時間の間秒間2000リクエストに耐えるのがやっとでした。残りの1時間になり、原因を追求するとMLのモデルの中でデプロイしたことによって環境が変わったことによるWarningが出ていました。I/O周りの処理はだいぶシビアなので、それが原因でリクエストを捌ききれずにキューが溜まっていき、サーバはお亡くなりになられたのだと考えました。

「検証した時は出ていなかったのに、、、」

と思いながら、時間内に修正することはできずにオークションは終了しました。

 

 

 

1位になることはできませんでしたが、普段触ることのないアドテク関連について色々学ぶことができたので、よかったです。

 

サイバーエージェントさんありがとうございました。

 

学んだことや反省

  • Issueを切る上での粒度感とそのIssueの完了定義を明確に定めること
  • KPTをやり、それを活かすこと
  • 小さくデプロイしていくこと
  • 負荷テストが早めにできる状態を作ること

学んだことを生かしてのこれからすること

  • Issueを切る時に、粒度感を統一して完了定義を定める。
  • インターンやプロジェクトでコマめにKPTを実施する。
  • LB周りをもう一度自分でやってみる。
  • k8sちゃんと勉強して使っていく。
  • ケースバイケースだけど、負荷分散しやすいアーキテクチャ構成のテンプレ用意する(実際にやってみる)。

f:id:taya-intel:20190924031550j:plain