Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

アカツキゲームスのインターンに参加して

はじめに

初めまして、アカツキゲームスのクライアントサイドのインターンに参加させていただいた斎藤と申します。

開発には2021/10/4~2021/10/27の期間、参加させていただいたきました。取り組んだことや感想などについて書いていこうと思います。

  • はじめに
  • 自己紹介
  • 行ったこと
    • 放送部の一括既読機能
    • 放送部の通知数と未読の数が異なっている件の対応
    • スカウトCMのテンポ改善
    • Extraボイス入手時に何を手に入れたかわからない問題の改善
      • 仕様決定ミーティング
  • 振り返り
    • 学び
      • 設計
      • 責任
      • コミュニケーション
      • 組織構造
      • 自分のやりたいこと
      • 足りないもの
  • まとめ

自己紹介

自分は、広島大学の修士1年で分散処理についての研究を行なっています。

趣味はゲーム&ゲーム制作です。サークル活動や個人などでUnityを使ってゲーム制作を行なっています。

趣味や研究での開発は行ったことはあるのですが、バイトなどの経験はなく業務での開発は今回が初体験でした。

行ったこと

自分は『八月のシンデレラナイン』(以下ハチナイ)の開発に参加しました。以下行ったタスクについて説明していきます。

放送部の一括既読機能

ハチナイには放送部というハチナイ関連のYouTubeのコンテンツや漫画などを紹介する機能があるのですが、そこに一括既読機能をつけたいというものでした。

放送部に類似した機能にお知らせという機能があり、そちらにはすでに一括既読機能がついているため、そちらの機能をこちらにも実装したいという需要です。

f:id:Aojilu08:20211027110941p:plain

f:id:Aojilu08:20211027110925p:plain

続きを読む

AWS上の fluentd から BigQuery への認証に Workload Identity を利用する

この記事では、AWS の EC2 や ECS 上で動作する fluentd から Workload Identity を利用してBigQueryにログを送る方法を紹介します。

背景

AWS から BigQuery にアクセスする際、従来はサービスアカウントキーを利用して認証を行なっていました。しかし、サービスアカウントキーは厳重な管理が必要です。これに対して、Workload Identity を利用すれば、管理が必要なキー自体をなくすことができ、運用の手間を軽減することができます。

先日 googleauth gem 1.5 がリリースされ、Ruby からも AWS からのWorkload Identity による認証をすることが可能になりました。
rubygems.org

早速これを利用して、AWS上のEC2やECSで動作する fluentd から BigQuery にデータ送信する際の認証方法を Workload Identity にしてみます。

続きを読む

アカツキゲームスのサーバーサイドインターンに参加しました。

こんにちは。この度、2021/8/23~2021/9/3の2週間、アカツキゲームスの就業型インターンに参加しました。

このインターンでは、『八月のシンデレラナイン』のサーバーサイドでの業務に携わりました。

自己紹介

地方国立大学の修士2年生です。

普段は文字列を研究しており、C++やRustと戯れています。

インターンで取り組んだこと

今回のインターンでは、サーバーサイドエンジニアとして、以下のタスクに取り組みました。

管理サイトの機能追加

不具合の調査対応でユーザの情報を閲覧したり編集したりする場合は、エンジニアが作業をする必要がありました。そこで、管理サイトでできるようにしました。これにより、エンジニアでなくても対応できるようになりました。

AWSのメンテナンス情報をSlackで通知

AWSでは、稀にメンテナンスにより、インスタンスの再起動などが起こります。このようなイベントは、以下の方法で連絡がきます。

  • メンテナンスが予定されたよ!と、イベントが発行される
  • メールによって通知される

しかし、メールでの通知は、必ず行われる保証はありません。

そこで、メンテナンスに関するイベントがきた場合にSlackで通知することで、メンテナンス情報を把握しやすくしました。

構造としては、EC2やRDSなどのリソースについて、CloudWatch Events でメンテナンス情報に関するイベントをキャッチし、LambdaからそれらのイベントをSlackへ通知するようにしました。

NewRelicの導入

NewRelicとは、サーバーやインフラのパフォーマンスを分析するためのツールです。以前は導入をしていたのですが、一時的に動作が止まっていたので、開発環境で動作するようにしました。NewRelicではAPIのレスポンスタイムや、CPUの使用率、メモリの使用量などパフォーマンスを分析するためのデータを確認することができます。これにより、どのAPIが遅いのかを調査することができました。

API 高速化

NewRelic導入により、レスポンスが遅いAPIが見つかりました。そこで、高速化できないか調査を進めていきました。NewRelicではtransaction毎に、どのようなリソースへのアクセスがあったのか、また、そのリソースからのレスポンスタイムなどの詳細を確認することができます。この中で、クライアントへ返すjsonのレンダリング処理を行なっている、jbuilderが遅いことが判明しました。

jbuilderでの処理を高速化することを大まかな方針とし、どの処理がボトルネックとなっているかを確認していきました。

partialの改善

jbuilderでは、jsonでのレンダリング処理を外部ファイルから呼び出すpartialという機能があります。本APIではこのpartialを利用していたのですが、こちらは、レコードが大規模である場合に低速になります。そこで、partialの利用を回避し、実装してみました。

結果として、効果がみられませんでした。

 

N+1の改善

NewRelicでさらに調査を進めていくと、レンダリング処理の中で、DBへのアクセスが頻繁に行われていることが判明しました。これは、N+1であるような挙動をしていたので、テーブルを直接参照している処理がないか調査をしました。

すると、preloadされたテーブルではなく、直接テーブルを参照している箇所を発見したので、この処理を改善しました。

しかし、この改善においても、全体のレスポンスタイムは大きな改善とはなりませんでした。

 

時間切れ

ここまで調査した段階で、インターン期間の終了が近づいてきました。そのため、このタスクについては、サーバエンジニアチームに引き継いで調査を続けていただくことにしました。情報の引き継ぎを円滑にするために、今まで調査した内容をまとめて、Issueとして残すことにしました。APIが遅い原因は、さまざまな要素が絡まり、一筋縄ではいかないことを改めて認識しました。

まとめ

今回のインターンでは、サーバーのタスクだけでなく、AWSでのインフラに関するタスクも行うことができました。また、実際に稼働しているゲームの開発に関わることができて、とても刺激的でした。

また、アカツキゲームスの文化として発言の心理的障壁がとても小さいことを実感しました。メンターの方々のサポートも手厚く、質問に対する答えも、その答えへの辿り着く方法を教えてくださるので、課題の解決方法として学んでいくことができました。

2週間という短い期間でしたが、濃厚な時間を過ごすことができました。ありがとうございました!

Akatsuki Games Summer Internship 2021 で大規模サービスの開発に参加しました

はじめに

はじめまして、長谷川と申します。

2021/10/4 から 2021/10/29 の4週間、株式会社アカツキゲームスの『八月のシンデレラナイン』(以後ハチナイ)の開発を行うチームにサーバーサイドエンジニアとして参加させていただきました。

普段は趣味やアルバイトでWebとモバイルのアプリ開発をしたり、大学院で交通流や人流の解析の研究をしています。

 

インターン参加まで

アカツキゲームスのことはサポーターズの逆求人イベントで知ったのですが、アカツキゲームスのエンジニアはとにかく楽しそうにものづくりしてるよ〜と人事の方が話されており、興味を持ちました。

選考では主に今までの経験について聞かれ、特に友人と作ったプロダクトの開発をする時に考えていたことについて話したのがウケが良かった気がします。Railsを触るのはかなり久しぶり(&そもそも経験不足)だったので、参加が決定してから他の企業でRailsを使う短期インターンやハッカソンに参加しながら、事前準備をしてインターンに臨みました。

 

取り組んだこと

 

今回のインターンには(授業や研究で途中抜けしながら)4週間参加させていただき、主に以下の4つのタスクに取り組みました。

・管理者ツールの機能追加(Day2~Day3)

・マスターデータのバリデーション

・新規機能開発

・チャプター情報一覧取得APIのレスポンスを高速化

 

上の3つまでは軽く触れる程度にして、今回のインターン期間の約半分をかけて取り組んだ「チャプター情報一覧取得APIの高速化」について詳しく書いていこうと思います。

管理者画面の機能追加

この管理者ツールでアイテムの付与をできるようにする、というのが一つ目のタスクでした。管理者ツールは主に非エンジニアの職能の方が使うのですが、通常ユーザーに対してアイテムを付与するというのは強力な機能なので、手違いが起きないように運用フローを整えてもらう必要がありました。この部分でエンジニア以外の方とコミュニケーションを取ったのですが、こういう体験は技術とはあまり関係がないながら業務以外では体験しづらいのでいい経験になったなと思います。

 

マスターデータのバリデーション

(ハチナイにおける)マスターデータとは、選手の能力やショップの交換レートなどのユーザーの操作によって変化しないデータのことです。これと対になる概念として、獲得した経験値や所持しているアイテムなどのユーザーデータがあります。

ハチナイでは、このマスターデータに対して不正な値をもった選手や、イベントが発生しないようにバリデーションをかけています。不具合を未然に防ぐだけでなく発生した不具合が再度発生しないようにするのもマスターデータのバリデーションの役割です。今回のタスクでは過去に起こった不具合の原因を調査し、その不具合が起きないようにするためにバリデーションを追加しました。不具合の原因の調査は、1つ目のタスクと同じようにエンジニア以外の方とコミュニケーションをとりながら進めていったのですが、コードだけからは読み取れない運用ルールなどを知ることができて、コミュニケーションの大切さを学ぶことができました。

 

新規機能開発

2つ目のタスクが終わった時に「新規機能開発に興味ありますか?」とメンターの方に聞かれ「楽しそう!やりたいです!」と答えると、メンターの方が実際に業務で進めている新規機能の開発の一部分を任せてもらえることになりました。(新規機能については、公開されていない情報をかなり含むので詳細に触れることはできませんが、)テーブル定義、実装方針検討、エンドポイントの決定、API作成、テストを書く、など新規機能開発の一連のフローを経験できました。4つのタスクの中では最もユーザーにとってわかりやすいタスクだったので、自分が開発に参加した機能が実際にリリースされるのが楽しみです。

 

チャプター情報一覧取得APIのレスポンスを高速化

これが一番時間をかけて頑張った、かつ成果を出せたと思っているタスクです。このAPIはメイン画面から、試合ボタンを押した時などに叩かれるチャプター情報の一覧を返却します。実際のゲーム画面で言うと、例えば

 

f:id:t_hase_aktsk:20211101083039p:plain

から試合ボタンを押して

f:id:t_hase_aktsk:20211101083045p:plain

へ遷移するときに叩かれているAPIです。確かに言われてみれば、プレイしていても結構遅い。と言うわけで、まずは速度計測から始めました。僕の環境でのレスポンスタイムの計測結果が以下でした。

Completed 200 OK in 3957ms (Views: 2452.5ms | ActiveRecord: 251.4ms)

約4000ms。。。!早くしなくちゃ!と思い早速改善に取り組みました。

ViewsとActiveRecord以外の部分で1300msくらいかかってるのは流石に遅すぎない。。?Controller層の処理が怪しそうと思いそのあたりの処理の速度を測定するとビンゴ!チャプターに関連するアソシエーションを取得するpreloadが大量に連なっている所がとても重くなっていました。(僕はpreloadはN+1を解決するためにするんだから早くするためのモンだと思ってましたが、ハチナイくらいのサービスになるとレコードの量がすごいので、気軽にpreloadすると重くなってしまうんだな。。)その中でも特に遅い部分を調査していると、クリアスターの有無を計算する所が重くなっているようでした。ここはマスターデータだけで計算できる部分だったのでキャッシュに持たせるのが有効そうだと考え、早速実装してみると

Completed 200 OK in 2659ms (Views: 1866.2ms | ActiveRecord: 229.5ms)

といきなり30%ほど改善できました!

この時点まだインターンの残り期間が1週間あったので、さらに高速化したい!とさらに調査を進めました。

 

というわけで、遅い処理を特定するためにログを見ていると怪しい箇所をいくつか発見。bulletでは検知できない明示的でないN+1が発生しています。

ここのN+1を解消すると

Completed 200 OK in 2330ms (Views: 1739.6ms | ActiveRecord: 73.0ms)

と少し早くなりました。

また、遅い処理で改善できそうな部分を見ていくと、キャッシュをwriteした後は使われないアソシエーションがpreloadされているのを発見したのでそこのpreloadを削除。ここでインターンの残り期間がほとんどなくなっていたので、PRを短時間できちんと出せるような細々した改善点を探すためにログが汚くなっているところを見ていくと、同じようなN+1や無駄なキャッシュのreadを発見しました。これらもなんとか期間内に解消して少しだけ速度改善。これらは速度改善という点で見ればあまり結果は出なかったですが、ログは綺麗な方が気持ちが良いので達成感はありました。

最終的には

Completed 200 OK in 1871ms (Views: 1554.7ms | ActiveRecord: 28.8ms)

というレスポンスタイムになり、最初の4000msと比べると50パーセント以上の改善になりました!

 

業務を終えて&感想

成果発表

これにてインターンとしての業務は終わり、最後に成果発表会を行いました。

成果発表会では今までお世話になった方々からFBをいただけるのですが、直接は話していなくてもslackで僕のtimesチャンネルを見て、気にかけてくださっていた社員さんたちからも温かいコメントをいただいて、思っていたよりたくさんの方に見守られてこのインターンを走り切れたのだなと温かい気持ちになりました。また、「速度改善というタスクは新規機能開発などと違い、ユーザーに分かりやすいFBをもらえるようなものではないけど、サービスにとってすごく価値があることだからチームの私たちからたくさん感謝を伝えたい」というようなことを言っていただき、嬉しかったし、仕事の価値を認め合える空気があるというのがすごくいい環境だなと思いました。

感想

このインターンでは、人生で初めて大規模な開発に関われたり、色んな職能の方とランチしたりミーティングしたりなど、すごく良い経験をすることができたなと思います。またコードを書くばかりがエンジニアの仕事ではなく、エンジニア以外の職能の方とのコミュニケーション、仕様検討、原因調査などもエンジニアの大切な仕事であることを学べたのはすごく良かったなと思います。

また、メンターの方は自走を促すけど、困ったことがあればすぐに相談に乗ってくださり、僕にとって安心して挑戦できる&成長できる環境を整えてくださいました。この場を借りて改めて感謝を伝えたいです。本当にありがとうございました!

 

 

 

アカツキゲームスのインターンでAPI高速化と新規機能開発に取り組みました

こんにちは! 2021/8/10〜2021/8/27の3週間にわたってアカツキゲームスのサマーインターンに参加させていただきました、細谷と申します。

今回のインターンで取り組んだことや学んだことについてまとめます。

自己紹介

東北大学大学院 情報科学研究科に在学中の修士1年です。研究ではコンピュータビジョンや機械学習を扱っており、趣味でWebフロントエンド・バックエンドを幅広く触っています。

よく書く言語はTypeScript、Python、Golangで、最近は新規Webサービスの開発をしている関係でソフトウェア設計などの学習をしています。

インターンで取り組んだこと

今回私は、『八月のシンデレラナイン』(以後ハチナイ)というゲームの開発チームにサーバーサイドエンジニアとして参加しました。

ハチナイのサーバーサイドは主にRuby on Railsを用いて開発されています。私はRailsでの開発経験がなく、ある程度の予習が必要とされました。そのため、経験があり言語として近い性質を持つPythonとの共通点を捉えつつ、ActiveRecordなどのRails特有の知識を一通り学習してからインターンに臨みました。

APIの高速化

最初に取り組んだのは、「購買部」内にあるアイテム変換機能に関するタスクでした。ここではナインスターや各種変換コインを用いてアイテムを入手することができますが、その際に発生する「現在販売中のアイテム」を取得する処理が重く、アイテム変換への画面遷移が少し遅いという問題がありました。

この処理は具体的には、「どのアイテムを用いて交換できるか(カテゴリ)」という情報と、「各アイテムを何と交換できるか」という情報を取得する2種類のAPIが用いられています。そのため、N個のカテゴリ全てに対してそれぞれで交換できるアイテムを取得すると、全体ではN+1回のAPI呼び出しが行われることになり、無駄が多い状態になってしまっていました。

設計としてはいわゆるRESTfulなAPIでしたが、これらで取得できる情報を1つにまとめることで端末とのやりとりやデータベースへのアクセス回数が減り処理が高速になると考えられます。そこで、既存のAPIとは別に、「アイテム交換で現在販売中のアイテム」全てを取得できるAPIを作成しました。

改善の結果

呼び出す必要のあるAPIを1つにまとめた結果、負荷試験環境において約3.5倍の処理高速化に成功しました。この改善によって、アイテム変換機能への遷移が高速になることが期待されます。

スキルの入れ替えに関する新規機能開発

2021年8月現在の仕様では、各選手ごとに習得できるスキルの個数に上限があり、別のスキルを習得したい場合は既存のスキルのどれかと入れ替えるようになっています。この際、付け替えによって外したスキルを再度習得させたいときに、新しく習得する場合と同様にアイテムを消費する必要があります。これは特に、UR選手で投手と野手を切り替えたい際に不便を強いる形となっています。

そこで、「過去に習得したことのあるスキルを任意に入れ替えることができる」ようにスキルの習得に関する仕様の変更が提案されていました。この実装として、選手のスキルごとに「過去に習得したことがあるか」を新たに保存するようにし、したことがあればアイテム消費なしでスキルを入れ替えることができるようにしました。

チーム内でのやりとり

このタスクは同時期にクライアントサイドのインターンで参加していた方と協力して実装しました。また、仕様の変更に関わる部分であったため、詳細な仕様を確認するためプランナーの方ともやりとりを繰り返しました。結果としては、選手育成の画面にてスキルを入れ替える機能を実装し、クライアントサイドとの結合テストまで行うことができました。

※画面は開発中のものであり、実際の仕様とは異なる場合があります

インターン期間内で得られたこと

運営中のゲームタイトルの開発に携わる、ということ

実際にチームのエンジニアの一員として、ハチナイの開発に携われたのは非常に貴重な体験だったと思います。ゲームの体験を壊さないためにも、既存機能の改修には特に慎重になる必要があり、そのような考慮はこれまでの個人開発では得られなかったことだと思います。また、プランナーの方やクライアントエンジニアの方とのやりとりの間で認識の齟齬が生まれないようにうまく言語化することも開発を進める中で得られたことでした。

チームの一員として動く

開発に携わる間にメンバー、一人一人に信頼が置かれているのとともに、チームやプロダクトのために責任感を持って動いているのだと感じる機会が多かったです。

3週間という短い間でしたが、手厚いサポートに支えられ、成長できる機会をたくさんいただくことができました。ありがとうございました。