位置データから正確な情報を計算せよ!<AdTech Challenge>
皆さんおはこんばにちは!
久々のブログ更新になってしまいましたw普段から技術的なことを書こうと思ってるのですが中々手が回らなくて。。。
言い訳はさておき、またまたサイバーエージェントさんの主催のイベントに参加してきましたのでそのことをブログに書きたいと思います!
参加したイベントはAdTech Challengeと言うもので、名前の通りアドテク系の内容になっています。
www.cyberagent.co.jp
今回は送られてくる位置データを元にそのデバイスが何処にいたかなどを計算し解答を返すAPIを3人1組+社員エンジニア1人のチームで作るイベントでした。
初めてアドテク系の開発を経験したので非常に色々な経験が出来ていい勉強になりました!毎回思うのですが、なんでサイバーエージェントのハッカソンとかイベントってこんなに楽しいのでしょう??w
ぜひ色んな学生にチャレンジして欲しいですねw
では、実際にどんな技術を使ったのかとかアーキテクチャとかの説明に行きたいと思います〜!
技術選定
どんな技術を選んだかを紹介したいと思います。使用する言語についてはみんなが使いたいものってことで良かったのですが、DBの選定で少し悩みました。まずは使用した言語について見ていきたいと思います。
使用した言語
Golang
普段からGoで開発をしているわけではないですが、使ってみたいということでGoを選びましたw(技術選定になってるのか??ww)
Gin
GoのフレームワークのGinも導入しました。エンドポイントの作成とか基本的な設定とかをする必要がなくなるのかなと思ったのと学習コストが比較的に低そうだったので導入を決めました。
データベース
DBに関しては何を使うべきなのかを悩みました。DBを選ぶ条件としてはQPS2000に耐えられるのかどうかというところでした。(そもそもスタートの時点でQPS2000がすごいのかどうかすらわかっていなかったですw)
とりあえず、その疑問を解決すべく調べたり実験したりして(この後書きます)、結局チームメンバーが使い慣れていたCloudSQLにすることになりました。
CloudSQL(MySQL)
今回のお題の情報量(QPS2000)であればMySQLで十分対応出来るということで選びました。
しっかりとベンチマークを確認して、本当にだめなのか、何がだめなのかの確信を持てるまでしっかりと調べることは大切なのだなと改めて思いました。
インフラ
自分はインフラがめっぽう弱くて、今後の課題であるとずっと思っているのですが未だに克服出来ていません。。
今回はチームに1人、アドテクエンジニアの人が参加しているのでその人にインフラの構成とかはほとんどおまかせしていました。
Google Container Engine(Kubernetes)
今回のデプロイ環境はGCPでした。その中からGCEを選びKubernetes Clusterでnodeのコントロールをする??様に設計していました。そして、Kubernetes ClusterとCloudSQLが通信する感じですね。たぶん。。。
アーキテクチャ
さて、実際に自分たちが作ったアーキテクチャの紹介をしていきたいと思います。
作るアーキテクチャはQPS2000で2時間くらい情報が流れてくるからその情報をDBに全て格納できること、リアルタイムで情報を検索して100ms以内にその解答を検索して返すことの2つを実現させるようなアーキテクチャが求められていました。
今回一番勉強になったところがこのアーキテクチャを考えるところです。主にはDBをなににするかというところの話が多くなってくるとは思いますが、どうやってアーキテクチャを決めたかなどのエピソードも書いていこうかなと思います!
どんなアーキテクチャがいいんだろう??
今回はアドテク。QPS2000。さぞ立派なアーキテクチャが必要で、しっかりと設計しないと死ぬ。。。そんな予感がありました。
最初から立派なアーキテクチャを考えようと頭をひねろうとしていたのですが、そもそもアーキテクチャを決めようにも判断基準の情報が少なすぎて何も決められない状況でした。
そもそもQPS2000って何?すごいの?おいしいの?
自分たちのチームもQPS2000というのを聞いて、周りのチームと同様にMySQLじゃ無理なんじゃね?という話になっていました。そのことから、周りのチームではBigqueryとかBigtableを使って性能のいいDBを使ったほうがいいという流れからそっちを採用していたのですが、僕らではそもそもなぜMySQLではだめなのかの判断ができずにいました。
そこでまずは単純に送られてきたデータをそのままDBにぶち込むという至極単純なアーキテクチャで試しにQPS2000を体感してみようということになりましたw
その時のアーキテクチャは本当にそのままです。w
このアーキテクチャで試すと案の定、死にましたwそれを確認するためのアーキテクチャだったので良かったのですが、そもそも死んだボトルネックが何なのかは確認する必要がありました。
そこで、そもそもMySQLがQPS2000に耐えられるのかをベンチマークを読んで確認すると、QPS20000くらいまでは普通に大丈夫だよ的なことが書かれていたのでQPS2000はボトルネックにはならないという結論が出て、MySQLでいいじゃんという結論になりました。
では、なにがボトルネックになっているのでしょうか?
Insert文が走りすぎてる説
答えを言うと原因はこれでした。QPS2000ということは2000回Insert文が走っているので、それがボトルネックになっていました。
そこで、Bufferを使ってInsert文が 走る回数をコントロールしてあげればデータを全て漏れなく格納できるのではということで、bufferを作って試してみました。新しいアーキテクチャもかなり単純で、先程作ったものにbufferを噛ませているだけになっています。
結果は、、、全部の情報を格納することが出来ました!!
ということで、自分たちのアーキテクチャは凄くシンプルな物にまとまりましたw
ちなみに、検索速度に関してはINDEXを貼るなどをして検索速度を上げることで十分対応できるのでその点もクリア出来ていました。
結果発表
最終プレゼンを終えて、ちょっと気持ちが抜けてふわふわしてたらチームの社員さんと2日間の振り返りを行って終った感と脱力感に浸ってましたがすぐに結果発表の時間になりましたw
今回は全体でチームA〜チームGの7チームで得点を競い合いました。ちなみに私はチームGです。
3位から発表され優勝はダラダラダラダラダラダラ、、、チームB!!!
プレゼンの時にアーキテクチャとかめちゃくちゃしっかりしてて、使用している技術に関する理解も深く相当すげぇと思ってましたがやはりこのチームが優勝でした!さすがの一言ですね。自分も精進せねばと改めて感じました。
今回は順位以外に審査員特別賞があるらしい、、
ダラダラダラダラダラダラ、、、チームG!!!!
キタァ!!!ということで、審査員特別賞をいただきました!!めちゃくちゃ開発を頑張ってくれたチームのメンバーにめちゃくちゃ感謝です!!kyoto hackでは勝てなかったので今回は賞をいただけてめちゃ嬉しかったですw
商品は銀のAbemaくんですw割りと重量感がありますw
何が評価されたのか?
さて、何が評価されたのでしょうか?
それは、2日間で作るアプリでQPS2000というお題に対して、なぜMySQLで大丈夫でしっかりと各技術を理解した上でアーキテクチャを設計し、結果非常にシンプルなアーキテクチャでデータの格納や検索を実現させているという点でした。
プレゼンのときは他チームのアーキテクチャなどを見てやばいなという話をメンバーとしていましたが、そもそもQPS2000がどのくらいでMySQLではだめなのかどうかをしっかりと検証しているチームはチームGくらいで、QPS2000という新しいものを体感して把握したりしてボトルネックを把握した上でアーキテクチャの設計をしたりしているのもチームGだけでした。(私の知る限りでは)
このことからしっかりと知らないことに対してはしっかりと検証して問題を把握し切ることが非常に大切であるし、そういった所はしっかりと評価されるので改めて重要な能力なのだなと改めて感じました。
まとめ
今回は色んなことを学ぶことが出来ました。QPSなど普段は触れない用語なども触れることが出来ましたし、そもそもなんとなくで決めるのではなくしっかりとボトルネックになっているものを把握して、しっかりと根拠を持って技術選定することの大切さを改めて感じました。当たり前ですが、当たり前なことが大切であるということに改めて気づかせてもらいました。
また、チームで一つの問題に取り組んで、みんなで議論し合いながら開発することの楽しさも改めて感じました。チームGのみんなありがとうございました!!
今回もめちゃくちゃ優秀な学生エンジニアが沢山参戦していて、改めて自分がとても贅沢な環境にいることを感じました。いずれ何処かでみんなと再会してエンジニアとして色んな話をする時が来たりしたらいいなぁなんておっさんみたいなことを考えたりしていますw
最高の環境を経験出来るので、他の学生にもぜひサイバーエージェントさんのインターンやハッカソンに参加してほしいですね!
参加者のみんな、お疲れ様でした!
最高の開発環境でやらせていただいたサイバーエージェントのみなさんも本当にお世話になりました!adtech studioに遊びに行きます!w
最後まで読んでいただきありがとうございましたm(__)m