明確なキャリア像がない新卒入社がアーキテクトになりたいと思った理由

池野直人氏(以下、池野):ではさっそく、「アーキテクトを目指す若手エンジニアのこれまで」というタイトルで発表を始めます。よろしくお願いします。

まず簡単に自己紹介します。私はサーバーサイドエンジニアの池野と申します。よろしくお願いします。簡単な経歴としては、2017年に新卒入社して、最初の2年間は「Anyca」というサービスに、その後2年間は「LCX」というサービスに関わっていました。この2つのサービスについては、本日の発表で、後ほど紹介します。また現在は、協業案件での新規開発プロジェクトにおいて、開発チームのリーダーを務めています。

本日の話についてですが、大きく分けると前半と後半の二部構成になっています。前半は、明確なキャリア像がない状態で新卒入社した自分が、その後明確なキャリア像、アーキテクトになりたいという思いを持つに至った経緯について、お話しします。

後半は、そのキャリアの実現に向け、ゲーム基盤システムである「LCX」の新規開発プロジェクトで、実際にどういった技術的な経験を積んだのかについて、お話しします。DeNAでの新卒ソフトウェアエンジニアの働き方やキャリアの積み方の一例として、具体的なイメージを持ってもらえれば幸いです。

エンドユーザーに近い部分の開発をしたい気がしていた

では、さっそく前半の話に移ります。まず、自分が新卒入社時はどういう状態だったかについてです。プロブラミングが好きだったので、ソフトウェアエンジニアになりたい、でありたいというのは、その時点から間違いありませんでした。ただし、どのようなソフトウェアエンジニアになりたいかは、この時点では明確ではありませんでした。

そんな中でも思っていたこととしては、どちらかというとエンドユーザーに近い部分の開発をしたい気がするということと、リアル寄りな、Webで完結しないサービスの開発に興味があるということでした。こういった興味を汲んでもらえて、新卒入社後は「Anyca」に配属になりました。

「Anyca」について簡単に説明します。こちらは個人間でカーシェアリングができるサービスです。当時はDeNAのオートモーティブ事業部の1サービスとして運営されていました。現在は合弁会社になり、株式会社DeNA SOMPO Mobilityにて運営されています。

「Anyca」では、サーバーサイドの開発と運用を軸にしつつ、本当に幅広くいろいろなことをやらせてもらいました。ここでは概要を列挙するにとどめますが、やったことの一例を紹介すると、サービス改善のためにデータの収集と分析。それを踏まえた企画、そして実装という一連のサイクルを回したりしていました。

あとは、ユーザーからの問い合わせに対して、カスタマーサポートチームと連携して調査や対応を行ったり。また、裏側の保険連携や会計システムの整理とリファクタリングを行ったり。さらに、他社さんとの合同のプロジェクトにおいて開発リーダーを務めるなど、本当にいろいろ幅広くやりました。ここでの経験が、キャリア像を明確にするための大きな手助けとなりました。

「Anyca」でいろいろ経験して見えてきたこととして、開発が楽しいのは相変わらずなのですが、さらに具体的にどういう時が楽しいのかが、実感を伴ってわかってきました。

自分の場合、意外と裏側のシステムの開発も楽しいという気づきがありました。例えば先ほど述べたような「Anyca」の保険連携のシステムや会計システムといった、一見裏方的な機能についても、どうすればいいものが作れるのかを試行錯誤するのが楽しいと感じました。

どのような設計にすれば、将来にわたって活用されるシンプルで柔軟なシステムが作れるのか、といったことを考えて作るのは楽しいですし、そのようにして考え抜いた設計が実際に活きたと思える瞬間があると、それもまた楽しいと感じました。

技術的に突き抜けることで、ビジネスに貢献できる

また、もう1つ経験を通じて見えてきたこととして、技術的に突き抜けることで、ビジネスに貢献できることもあるのではないか、ということです。

これは、いろいろな観点でそう思うことがありました。例えば「Anyca」のように長く運用されているシステムだと、どうしてもシステムが複雑になってしまう部分があります。

複雑になりがちなのは、往々にしてよく触られる重要機能だったり、コア部分だったりしますが、そういったビジネス的にも重要な部分への機能追加や改修に時間がかかってしまうことがあったような経験から、シンプルで良い設計のシステムがもし作れたら、それはサービスの改善速度の向上に直結すると思いました。

また、障害やバグの発生。これもなかなかサービス運用するうえで完璧には避けて通れない部分ではあると思いますが、どうしてもその対応や事後処理にも時間がかかってしまうことはあって。

そういった経験から、極力障害とかバグが起きにくいシステムをもし作れたら、その分本質的な作業の時間を増やすことにつながると思いました。

また、とある機能を新たに増やしたいという要件が出てきた際、実は機能を増やさなくても、既存機能を流用することでほぼ同じことをシンプルに実現できるといったことに気づいたような経験があって、その経験から、正しい取捨選択をすることで、開発コストってのは劇的に下げることもできるんだなというのを思いました。

こういった経験を得て、自分は技術的に高度であることによって、ビジネスに貢献するソフトウェアエンジニアになりたいと思うようになりました。

具体的には、システム全体の最適な設計を自分で考えて実装でき、また、要件に対して正しい取捨選択をして、最適な実現方法を提案できる人になりたい、と思いました。

その定義に近いのがテックリード。さらにいくとアーキテクトなのかなと思っています。このような経緯によって、自分はアーキテクトになりたいと思うようになりました。

以上が、明確なキャリア像がない状態でDeNAに新卒入社した自分が、アーキテクトになりたいという明確なキャリア像を持つに至った経緯となります。前半の話は以上で、ここから後半の話に入ります。

なぜ「LCX」へ異動したか

ここからは、実際にアーキテクトを目指して「LCX」でどういった技術的経験を積んだかについて、お話しします。

まず「LCX」への異動の経緯について、簡単にお話しします。自分はアーキテクトになるために、クラウドサービスを活用した大規模化サービスの開発運用経験や、大規模なバックエンドを自分で設計・実装するといった経験を積みたいと考えました。

なので、そういった経験を積めるプロジェクトがあったらチャレンジしてみたい、ということを当時の「Anyca」のマネージャーに相談をしたところ、理解と後押しをしてくれました。

そして、そのマネージャーに紹介してもらった別の部署のマネージャーから「『LCX』という新規プロジェクトがあるよ」という話を聞いて、内容を聞いてみると、自分が望む経験がまさに積める場だと思ったため、異動させてもらうことになりました。

曲がりなりにも「Anyca」の戦力の一部であった自分が抜けてしまうのは、チームに負担をかけてしまうことではあったと思うんですが、背中を押してくれたマネージャーとチームのメンバーには本当に感謝しています。

余談なのですが、「Anyca」の当時のマネージャーは馬場さんという方で、現在はDeNA SOMPO Mobilityにて代表取締役社長を務めています。馬場さんも新卒エンジニアとしてDeNAに入社して、「Anyca」にもエンジニアとして関わった点は自分と共通なのですが、その後ビジネスサイドに進んだ点は、自分とけっこう対照的なキャリアになっているんじゃないかなと思います。

この馬場さんも、本日のTechConで登壇しています。自分とはまた違った視点からいろいろ話をされていると思うので、興味のある方はぜひ、アーカイブ視聴してみてください。

「LCX」の概要

ではここから「LCX」の話をしていきます。まず「LCX」の概要についてです。「LCX」は一言でいうと、汎用的な機能をゲーム側システムに提供するシステムです。「LCX」が提供する機能は、ユーザー認証、課金処理、ゲーム内通貨管理、分析用データ収集など、どんなゲームでも必要となるような汎用的な機能です。ゲーム側のシステムから「LCX」を利用することで、そういった汎用的な機能を簡単にゲームに組み込めるようになっています。

また「LCX」は、iOSのAppStoreやAndroidのGoogle Play Storeなど、複数のアプリストアのAPIの差異を吸収した単一のAPIをゲーム側に提供しているため、ゲーム側システムからは、今アクセスしているユーザーがiOSなのかAndroidなのかを意識せずに、課金処理などの機能を実現できるようになっています。

「LCX」は、現在複数の運用中のゲームタイトルで利用されているほか、今後出るいくつかのゲームでも利用予定となっています。

また、「LCX」のもう1つの特徴として、中国の提携会社と共同で開発している点があります。これは、中国固有の事情に対応するためです。

中国はGoogle Play Storeが存在しない代わりに、Androidのアプリストアが多数存在しています。それらが提供するAPIはストアによってさまざまなため、「LCX」としてもそれに対応するために、開発を行う必要があります。

また、中国でゲームを出すためには、中国政府の定めた基準をクリアする必要があり、そのための機能の開発も必要です。将来的に日本で出したゲームを中国でも展開したり、逆に中国で出したゲームを日本や世界に展開するということをスムーズに行えるようにすることも、「LCX」のミッションの1つです。

そのため、先ほど述べたような中国固有の機能部分の開発を、中国の提携会社の開発チームと協力して行っています。なお、中国側の開発チームとのコミュニケーションは、slackやビデオ通話、プルリクエストのレビューなどを通じて、基本的には英語で行っています。

「LCX」で実際に経験したこと

ではここから、「LCX」で実際に経験したことについて話しに見えている図が「LCX」のシステム構成図です。「LCX」ではGCP(Google Cloud Platform)のさまざまなクラウドサービスを利用しています。

APIサーバーを動かしている「App Engine」やデータベースの「Spannar」を中心として、そのほかにもさまざまな補助的なGCPサービスによって「LCX」のシステムが構成されています。

本日は、各コンポーネントの詳細な説明は省きますが、この図で表されているように、GCPの多様なクラウドサービスを利用して開発や運用を行うような経験を積めました。

次に、「LCX」では大規模なトラフィックを捌くための設計や運用についても経験できました。ゲームのリリース時やイベント時などには、ゲーム側システムから「LCX」へのリクエストも急増し、秒間数千以上のリクエストが飛んでくることもあります。

この時「LCX」のシステムになんらかの不備があると、簡単にリクエストが詰まってしまい、レスポンスを返すのが遅くなったり、エラーになってしまったりします。そのため「LCX」では、大量で急激なトラフィックに耐え得る設計や運用を考える必要があります。

この図では、実際に大規模トラフィックを捌くためにやったことの一例について、記載しています。まず、一般には負荷試験と呼ばれる作業では、本番とは別環境に用意した「LCX」のシステムに大量のリクエストを発生させ、システムのボトルネックを探りました。

そしてボトルネックを解消するため、システムの各所にさまざまなチューニングを行いました。APIサーバーが載っているApp Engineについては、アクセスが急増した際にインスタンスを素早く増やしてスケールできるように、APIサーバーのアプリケーションの起動を高速化したり、リクエストを受ける前にあらかじめデータベースとの接続を確立しておくなど、ウォームアップ処理を行いました。

データベースのCloud Spannerについては、処理が重くなりがちな部分について、テーブルやクエリの設計を見直しました。また、メッセージングサービスであるPub/Subを利用することで、時間がかかる処理について、ゲーム側からのリクエストとは独立して非同期に処理しました。

また、実際にシステムになんらかの変化があった時もすぐに気づけるよう、レイテンシーやエラーレートなどの隠しメトリクスを可視化したり、一定条件でアラートが通知されるようにするなど、監視体制も構築しました。

このように、大量のトラフィックを捌くために、さまざまな観点から工夫をして、設計・運用をするという経験が積めました。

ソフトウェアアーキテクチャの設計

次は3つ目で、ソフトウェアアーキテクチャの設計に関する経験です。「LCX」は中国向けの対応のために少し特殊なアーキテクチャになっています。

日本での運用時は「LCX」をGCP上で動かすのですが、中国提携会社による中国での運用時は、「LCX」はAlibaba Cloud上で動かすことになっています。

そのため、実は先ほどまで見せていたあのGCP上のシステム構成図は日本での運用時の話であって、中国での運用時は、データベースから何もかもを含めて、まったく別のクラウドサービスであるAlibaba Cloudを利用することになります。

当然、クラウドサービスのAPIやクライアントライブラリも異なりますし、実装を担当するのも日本のチームと中国の提携会社チームで異なります。そういった特殊な状況でも、なるべく挙動の差分が出にくいようなアーキテクチャにする必要があります。

「LCX」では、そのために大部分のコアロジックは共通にしつつ、実装を切り替える必要がある最低限の部分のみインターフェイスとして切り出して別々に実装し、環境に応じて切り替えるような設計になっています。

こちらの図が、そのアーキテクチャを簡略化した例です。まず共通のコアロジックの一例として載せていますが、外部サーバーにHTTPリクエストを投げても応答がなかった場合、後でリトライするように非同期処理のキューにリクエストを積んでおく処理が書かれています。

この時、非同期処理のキューにリクエストを積んでおくための関数retryLaterは、インターフェイスとなっており、GCP用とAlibaba Cloud用で実装が分かれています。

それぞれの実装には、対応するクラウドサービスに単にキューイングするだけという、解釈の違いや挙動の違いが極力発生しにくい単純な処理のみが書かれるインターフェイスの切り方にしています。

このような設計にすることによって、お互いの実装やクラウドサービスの性質については気にせず、日本と中国で並行で開発できるようになっています。

また、大部分のコアロジックは共通であり、実装が分かれる部分を最小限にしているため、「LCX」としての表の向きの挙動に差異が出づらい状態を担保しています。このような設計は、一般には「クリーンアーキテクチャ」と呼ばれるものに近いのかなと思っています。

実際に複数の異なる実装が存在するという意味では、クリーンアーキテクチャの実践例としても、けっこう珍しいケースなのではないかと思っています。

このように「LCX」では、適切に抽象化されたソフトウェアアーキテクチャの設計を行う経験が積めました。

インパクトを最大化するのに最適な設計や実装

4つ目、これが最後になりますが、「LCX」の意思決定や実装はゲーム側に大きなインパクトを与えることになるため、良いインパクトを最大化するのに最適な設計や実装はどういうものかを考え抜く経験ができました。

なぜ「LCX」がゲームに大きなインパクトを与えるかというと、「LCX」がゲームの基盤となっていて、土台に位置しているためです。

「LCX」がより速くゲーム側システムにレスポンスを返すことができれば、ゲーム側システムもユーザーにより速くレスポンスを返せます。また「LCX」のAPIの出来がよく、ゲーム側の開発者から見て使いやすいものになっていれば、ゲームはより高速に開発が進みます。

「LCX」として一度リリースした機能は、さまざまなゲームから利用されることになるため、機能の破壊的変更や廃止は困難となります。こういった理由から、「LCX」では最適な設計や実装を考え抜き、最初から可能な限りベストを出す姿勢が求められます。

実際に「LCX」において設計や実装がインパクトを与えた事例について、よかったものと悪かったものについて紹介します。

まずはよかった事例についてですが、「LCX」の内部的なソフトウェアアーキテクチャ設計として、課金管理モジュールとゲーム内管理通貨モジュールというのを分離したのは、よいインパクトがありました。

課金をしてゲーム内通貨を購入する。つまり、課金処理をした後にゲーム内通貨を増やす処理をするのは一番よくある流れのため、当初は課金処理とゲーム内通貨の処理は合わせて1つの機能だと思っていたんですが、開発を進めるにつれ、それらの処理は意外と連動しないケースもあることに気づきました。

例えば、ゲーム内通貨を消費したり無償で配るような場合には、課金処理は関与しないですし、アイテムを直接課金により購入するような場合は、ゲーム内通貨の処理は関与しないことになります。

こういったことから、課金処理とゲーム内通貨処理は、実は別機能なのではないかと考え、内部的に分離して設計をし直した結果、コードの見通しがよくなり、機能改修がスムーズな状態を保つことができました。これは「LCX」において、いいほうに作用した設計の1つであると考えています。

逆に悪いほうにインパクトを与えてしまった事例についても紹介します。ゲーム内通貨の増減処理の際に、「LCX」の内部で発生するデータベースのトランザクションのロック範囲がかなり大きい設計になってしまっていたことで、イベントなどでゲームにアクセスが集中した際、トランザクションの競合を引き起こしてしまい、レイテンシーが悪化、ユーザー体験にも影響が出てしまいました。

現在はこの問題について改善が進められていますが、最初からデータベースのロック範囲や競合のリスクについて正しく考慮できていれば防げたことであるため、悔いが残る点となります。

このように「LCX」では、その時に自身の全力を尽くしても至らなかった部分に対しては、シビアにフィードバックが得られる環境だったと思います。

こういったフィードバックを得てふりかえりを行い、さらに改善を重ねることを自然に行えたので、自身の成長にも大きくつながりました。

経験を積めば目指すキャリアも変わる

以上が「LCX」での技術的経験の紹介でした。まとめると、目指したいキャリア像に近づくための経験を「LCX」で積めたと思っています。

やりたいと思っていたクラウドサービスを活用した大規模サービスの開発・運用や、大規模なバックエンドをイチから設計・実装するといった経験も積めました。

「Webサービスのバックエンドをイチから設計・実装してほしい」といわれたとして、何をどうすればいいか、だいたいの見当がつくようになったことは、自分の中でも大きな自信となっています。

振り返ってみると、新卒入社当初に思っていたこととは、今では真逆のことを自ら望んでやっていて。これはけっこう自分でも「おもしろいな」と思っています。

新卒入社時は、エンドユーザーに近い部分の開発したいとか、あとリアル寄りのWebで完結しないサービスの開発に興味あると思っていたのに、「LCX」は基盤システムであって、ユーザーからは遠い位置にありますし、ゲームシステムのさらに裏に位置するシステムなので、裏方も裏方で、基本的にはWebで完結するようなものになっています。

このように、興味・関心は、仕事をするうちに明確になったり移り変わったりするんだなというのを、本当に実感しました。そういう意味でも、入社から早い段階で「Anyca」で幅広い経験を積んだのは、すごくありがたいことだったと思っています。

そして自分は、現在「LCX」での経験を活かし、他社さんとの新規の協業案件にて開発チームのリーダーをしながら、バックエンドの設計や実装をイチから行っています。自身の目指すところであるアーキテクトに少しずつは近づけているのではないか、と思います。

ということで、本日のお話はこれで終わりになります。DeNAの新卒ソフトウェアエンジニアの働き方や、キャリアの積み方の一例として、具体的なイメージを持ってもらえれば幸いです。ありがとうございました。

司会者:池野さん、ありがとうございます。途中でやりたいことが変わるというのが、僕もそうだったんですけど、けっこう共感しているところで。やはり楽しさみたいなところがどこにあるのかが、解像度がドンドン合っていくような。

池野:そうですね。やっぱ、はい。実際働いてみると本当にそうだと思います。

Alibaba CloudのDBとCloud Spannerの違いをどこで埋めるか

司会者:それではQ&Aセッションに移りたいと思います。質問はこちらです。「Spannerの特性を踏まえたテーブル設計をしていますが、Alibaba CloudのDBはSpannerと特性が違うので、単純に適用はできないと思いますが、そこでの工夫を教えてください」と。かなり具体的な技術寄りの質問がきましたが、どうでしょうか。

池野:そうですね。これはまさにそうです。Spannerの特性は、けっこうリレーショナルデータベースには近いんですけど、ちょっと違った部分もあって。

例えば、普通のリレーショナルデータベースと違って、プライマリキー、データベースの主キーが単調増加なものを使ってしまうと、パフォーマンスが悪化してしまうみたいな特徴があったりします。

そういったものを避けるために、データベースのプライマリキーとしては、基本的には単調増加がしない、UUIDを利用していたり。それを日本側だけでなくて、中国側も含めて共通でそうして、データベースのテーブル設計やインデックスなども、基本的に同じものをなるべく使うようにしています。

特性の違う部分がありつつも、基本的にSpannerもリレーショナルデータベースの特性もだいたい持っている部分が多いので、そこまで大きな差分なくというか、共通化がうまくできています。そこまで外れる、どちらかがまったく別のことをしなきゃなんないみたいなことはなく、同じようなクエリであったり、同じようなテーブル構造でできていますね。

ただ、一応どうしても一緒にはできない時のために、クエリの一部分を別々に書けるようにしたり、別々のものを使うようにしたりしています。あとはテーブルももうまったく違うものを使えるようにするといったこと自体はできるようにしたりしていますね、はい。

司会者:なるほど。そういう例外的なところもいろいろケアしながら進めていると。

池野:そうですね。スライド中で話した「実装を分ける」というのを応用するかたちで。テーブル自体を分けるようなこともできるようにしています。

司会者:なるほど。ありがとうございます。それではお時間となりましたので、こちらで質疑応答を、並びに本セッションを終了いたします。ご視聴いただきましたみなさま、池野さん、ありがとうございました。

池野:ありがとうございます。