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

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

AWS FireLens の生成する INPUT 設定をカスタマイズしてログ欠損を回避

  • はじめに
  • FireLens の構成
    • awsfirelens ログドライバー
    • FluentBit・Fluentd の config 生成機能
  • ログ損失の回避策の課題
  • init を利用した INPUT の設定のカスタマイズによる解決策
  • おわりに
  • カスタム init のソースコード

はじめに

AWS FireLens は、Amazon ECS で動作するコンテナが出力するログを、FluentBit または Fluentd を使って柔軟にルーティングするための仕組みです。特に、タスク定義のみでログルーティングの設定が可能なため、構成管理をシンプルにできる点が特徴となっています。
しかし、大量のログを欠損なく扱うために設定の調整を行おうと思っても、現状の機能では一筋縄ではいかないことがあります。
この記事では FireLens の利便性を活かしたまま調整を可能にする方法をご紹介します。

FireLens の構成

FireLens は以下の2つの要素から構成されているといえます。

  • awsfirelens ログドライバー
  • FluentBit・Fluentd の config 生成機能

FireLens の構成
続きを読む

BigQueryで不要なカラムを削除してコストを削減する方法

はじめに

こんにちは。アカツキゲームスの河野です。

弊社では、ゲームの運用においてプレイヤーのプレイ履歴などをBigQueryに保管しております。 またこのデータを用いることで、不具合の発見やよりプレイヤーが楽しめる企画や機能開発に役立てております。

一方で、長く運用していく中でこのような保存コストの問題にあたっていくことがあります。

  • 特定のカラムのデータが活用されなくなっている
  • にも関わらず容量が何TB、何十TB…と溜まって毎月の保存コストが高くかかってしまっているため、費用対効果が全く見合ってない

BigQueryの場合、テーブルごとデータを削除するのは容易ですが、大量のデータの入ったテーブルの特定のカラムだけを削除したいときの対処方法が、これから紹介する手順のように実は複雑になることがあります。

新規に作成される際はこのような悩みに当たらないよう、要件や想定利用量に応じて意図的にテーブルを分けることもオススメします。

※ 以下の情報は2024年9月現在の情報を基にしています。実行は2023年〜2024年前半ごろに実行したため、その後内部の挙動や性能が変わっている可能性もございます。

使えなかった手順:ALTER TABLE DROP COLUMN を使用する

BigQueryにはカラムを削除する「ALTER TABLE DROP COLUMN」ステートメントが用意されています。

大容量のテーブルでもほとんどダウンタイム無く利用できましたが、ドキュメント上では「カラムが削除されてもストレージが解放されることを保障するものではない」旨が書かれています。

Data definition language (DDL) statements in GoogleSQL  |  BigQuery  |  Google Cloud

Since DROP COLUMN is not a data cleanup operation, there is no guaranteed time window within which the data will be deleted.

私たちも実行後数ヶ月ほど待ってみましたが、見かけ上はカラムが削除されていてもストレージは解放されませんでした。

また待っている間も削除されたはずのカラムへのストレージコストが継続して請求されてしまっている状況でしたため、待つのを諦めて他の手順を利用することにいたしました。

実際に実行した手順

代わりに私たちのプロジェクトでは、「SELECT * EXCEPT クエリを用いてテーブルを上書きする」という操作を利用することにしました。 先程のドキュメントにも1番目の方法として紹介されています。

There are two options for immediately reclaiming storage:

・Overwrite a table with a SELECT * EXCEPT query.

・Export the data to Cloud Storage, delete the unwanted columns, and then load the data into a new table with the correct schema.

手順1:該当テーブルへのレコードの挿入を停止する。

私たちが試した結果ではテーブルの上書きが発生している期間中に挿入されたレコードについては、上書きされた後には反映されていませんでした。

そのためメンテナンスに入れるもしくは挿入予定のデータを一時的に別の場所に退避するなど、リプレイス対象のテーブルへのレコードの挿入を止める必要があります。

手順2:BigQueryのスロットを予約する。

確実に大容量のテーブルを作り直すためには、「スロット予約」を用いてBigQueryの計算資源を確保する必要があります。

通常のクエリ実行では予約がなくてもオンデマンドで計算資源が自動的に確保されていますが、大容量のテーブルの上書きではかなりの計算資源を利用するため、充分かつ安定的な確保ができない場合は下記のようなエラーが途中で発生してしまい、やり直しになる可能性が高いです。

Resources exceeded during query execution: Your project or organization exceeded the maximum disk and memory limit available for shuffle operations. Consider provisioning more slots, reducing query concurrency, or using more efficient logic in this job.

そのため下記のドキュメントに従ってスロット予約を実行します。なおスロット予約の容量については、リプレイス後のテーブル容量にもよりますが、なるべく確実に実行する観点では上限まで予約することをお勧めいたします。

スロット予約の操作方法

スロット予約の上限

なお料金については、例えばUSリージョンで10,000スロットの予約の場合、1時間につき $0.04 × 10000 = $400 利用料がかかります。

スロット予約の料金

また実行にかかった時間についてですが、私たちのプロジェクトで実行した実績としては「リプレイス後」の「論理バイト数」でそれぞれ

約 7TB の場合 → 9分(スロット予約無くても実行可)

約 150TB の場合 → 4時間

でした。 事前の正確な予測は難しいですが、容量によっては相当な時間と金額がかかることになります。

手順3:タイムトラベルの保持期間を確認する。

BigQueryには、一定の期間は容易にデータを変更前に復元することが可能になるという、タイムトラベル機能があります。

タイムトラベルについての詳細

これはテーブルを上書きした場合であっても復元可能であるため、万一の失敗時にも安心です。

ただし一つ問題になるのがストレージ料金です。

タイムトラベル期間については2〜7日間の範囲で設定できますが、タイムトラベル期間中 + フェイルセーフ期間中(7日間)は引き続き削除されたデータに対しても保存コストがかかります。テーブルの上書きを実行したあとも、引き続き9〜14日分は料金がかかり続けることになることに留意する必要があります。

そのため、コストと万一の際のデータ復元タイミングを鑑みて期間を見直して設定することを推奨します。

また単価もテーブルを上書きした直後であることによって「長期保存」料金ではなく、全てより割高な「アクティブストレージ」料金としてかかります。

BigQueryのストレージ料金詳細

手順4:CREATE OR REPLACE TABLE クエリを実行する。

CREATE OR REPLACE TABLE (テーブル名) AS (SELECT * except (削除したいカラム名) from  (テーブル名))

※ クラスタリングやパーティション等を利用している場合は、その分の設定もクエリに必要です。

手順5:手順1〜3で行った操作を元に戻す。

スロット予約を解除し、該当テーブルへのレコードの挿入を再開します。

またタイムトラベルの保持期間も必要あれば元に戻します。

まとめ

BigQueryのテーブルで不要なカラムが生じた場合でも、このようにカラムを削除して保存コストを削減することは可能です。

しかし、現状ではテーブルのリプレイスが必要になり、またテーブルを作り直すために様々な設定や一時的な対応コストがかかることになります。

状況が変化しても不要になった特定カラムの保存コストで頭を悩ませることが無いよう、可能な範囲で先を見据えて設計しようと思うきっかけにもなりました。

ゲームクリエイターを目指す高校生に模擬授業を行ってきました!

アカツキゲームスのクライアントエンジニア、田﨑です。 先日、東京情報デザイン専門職大学(以下、TID)様のオープンキャンパスにて、高校生とその保護者を対象にした模擬授業を担当させていただきました。このイベントは、高校生にゲーム開発の楽しさを伝えることを目的に開催されました。本日はその日の様子をレポートします。

当日の様子

このイベントは、TIDのオープンキャンパスの一環で行われました。 高校生とその保護者、約20組の参加者が集まりました。

当日は天候に恵まれましたが、茹だるような暑さでした。

新設された校舎とのことで非常に綺麗でした。

参加者が熱心に授業に取り組む様子。

授業の概要

今回の授業では、「プログラマと一緒にゲームをデザインしてみよう!」をテーマに、高校生の皆さんにプログラミングを用いて簡単なゲームをデザインする体験を提供しました。授業の前半では、ゲーム開発の基礎知識として、業界の報酬や働き方、職種を伝えました。後半ではゲームをデザインしてみよう!と称して、参加者のアイデアをもとに、私がリアルタイムにコーディングして、1つのゲームを作り上げていきました。

当日のスライド

speakerdeck.com

当日作り上げたゲーム:スペース玉転がしバトル。

授業の感想

・ゲーム業界やお金の話など業界の方から実際に聞けて良かった

・プログラミングをはじめて見たので興味深かった

・ゲームを作るのが楽しそう

・講師の先生と同じアニメが好きでうれしかった

授業後、参加者からこのような意見をいただき、非常に嬉しかったです。

振り返り

今回の模擬授業を通じて、参加者の皆さんがゲーム開発に対する興味を深めてくれたことを非常に嬉しく思います。自分の出したアイデアがゲームになっていくという創造的なプロセスを体験することで、ゲーム作りの楽しさ、エンジニアリングの世界に触れる良い機会になったのではないかと感じています。

今後もこうした機会を通じて、さらに多くの若者がクリエイティブな世界に飛び込んでくれることを願っています! 模擬授業にお声がけいただいたTIDの皆様、参加者の皆様、そして資料作りにご協力いただいた皆様、本当にありがとうございました!

株式会社アカツキのラウンジで『1周年!若手エンジニアふんわりLT Day!』を開催しました!

先日、弊社ラウンジスペースにて、エンジニアたちによるライトニングトーク(LT)会が開催されました。 本イベントは、若手エンジニアを対象に、技術交流とスキルアップを目的とした勉強会です。 今回の会場は弊社が提供し、参加者が快適に過ごせるようにサポートさせていただきました。

イベント概要

  • 日時: 2024年8月10日 (土) 13:00 〜 18:45
  • 場所: 株式会社アカツキ
  • 主催: 若手ふんわり勉強部
  • 参加者: 約40名の若手エンジニア

wakate-funwari-study.connpass.com

休日開催で20枠に拡大

過去に開催された同イベントは平日の夜に行われ、LTの枠は10枠程でしたが、今回は特別に休日の午後に開催され、LT枠も倍の20枠に拡大されました。参加者の数や発表内容が増えたことで、当初は少し時間が長く感じるかと思いましたが、実際には各発表が充実しており、あっという間に時間が過ぎてしまいました。技術はもちろん、仕事に対する態度やキャリアについても様々な学びが飛び交い、参加者全員にとって非常に有意義な時間となりました。

イベントの様子

LTの様子
集合写真

交流とネットワーキング

勉強会後の懇親会では、参加者同士のネットワーキングが盛んに行われ、技術やキャリアについての情報交換が活発に行われました。若手エンジニア同士が互いの経験や知識をシェアし、今後の成長につながる良い機会となりました。

まとめ

今回のイベントは、若手エンジニアが集まり、技術的な知見を深める素晴らしいイベントでした。弊社も会場を提供することで、コミュニティの成長に貢献できたことを大変嬉しく思います。今後も、このような勉強会の支援を通じて、エンジニアコミュニティの発展に寄与していきたいと考えています。

Gold Sponsor として協賛したRubyKaigi 2024に行ってきました!

はいさい! 沖縄が恋しいエンジニアの小山です。

今回 Gold Sponsor として RubyKaigi 2024 に協賛させていただき、多くのメンバーと参加してきました。本記事はそのレポートです。

RubyKaigiとアカツキゲームス

RubyKaigi は、プログラミング言語 Ruby に関する国際会議です。

私たちは2013年からほぼ毎年協賛をさせていただいており、今年で12回目のスポンサーとなります。

去年の様子: 

hackerslab.aktsk.jp

当日の様子

Ruby Commiterであるパッチモンスターこと nobuさんと

BoothスタンプラリーもComplate!

印象に残った発表

参加したメンバーより、印象に残ったセッションの感想を参加レポートとして紹介します。

Unlocking Potential of Property Based Testing with Ractor / @ohbarye

speakerdeck.com

@shivashin495 です。まず、簡単にこのセッションの振り返りをします。

Ractorを知っている人は会場でも多く、9割くらいはいました。しかし、Ractorを趣味もしくは仕事で使ったことがある人となると急に3割くらいに減ってしまいます。では、なぜ使ったことがある人が少ないかというとユースケースが少ないからだと発表者は述べています。その上で、Property Based Testingこそが良いユースケースであると仮定し、その検証をしたという発表になります。

私のいるゲームプロジェクトではExample Based Testingが書かれています。これは、あるテストを書くときに任意のExample(具体的な振る舞い例)を用意してその中で正しい振る舞いをするか確認するテストです。ゲームは入力や状態が多岐にわたるため、複雑なケースでの検証やテストが用意されてます。しかし、どれほどテストを用意してもエッジケースや意図しないデグレによってバグが発見されることがしばしばあります。そこで今回のProperty Based Testingに注目しています。具体的なExampleではなくランダムな値を使うことで、潜在的なバグを発見できる可能性もあるためです。

ゲームアプリケーション以外にも、スクリプトやインフラのテストなどで使えると面白そうです。アイデアが広がる素晴らしいセッションでした。

RubyGems on ruby.wasm / @kateinoigakukun

speakerdeck.com

こんにちは、竹下です。私からは、かねてより関心のあったWASMに関するセッションがとても印象に残っているので、そちらを紹介させて頂きます。

WASMでRubyランタイムを実現し、ブラウザ上でRubyのプログラムを実行することができるruby.wasmの機能追加に関するセッションでした。

ruby.wasmではGemを使用することができますが、従来はRubyのみのGemにしか対応しておらず、C拡張を含むGemは使えませんでした。そこで、事前にパッケージをインストールする手法を選択し、Cを含むパッケージも利用できるようになったとのことでした。

今後の展望として、ruby.wasmを通常のプラットフォームの一つとすることができることを目標としているとのことで、ハンディな実行環境として有用なものになりそうだと感じました。実際、セッション内で行われたデモでは、Mastodonのサーバーをブラウザ内で起動し、ブラウザからアクセスするといった、圧巻の実演をして頂きました。Webサーバを含めて実現したいことのすべてがブラウザ内で実現する世界観が近づいてきているのだなということが感じられる内容だったと思います。

ゲームのサーバーサイドを開発するうえで、今回紹介されたデモのようにブラウザ内でハンディに動かそうということは難しいかもしれません。しかし、ゲームを開発するうえで必要なものはサーバーとクラアントだけでなく、検証ツールや諸々の管理ツールなど様々にあり、今後のツール開発の形を変える技術になるのではないかと思います。

Leveraging Falcon and Rails for Real-Time Interactivity / @ioquatix

rubykaigi.org

@nkpoidです。Railsを使ってリアルタイム性の高いインタラクティブなWeb体験を構築する方法に焦点を当てたセッションについてご紹介します。

発表者の@ioquatixさんが開発したFalconというGemは、Async Gemを基盤としたイベント駆動型アーキテクチャをRailsに導入するRack Middlewareです。デモでは、このFalconとRailsを用いて、インタラクティブな操作が必要なWebゲーム「Flappy Bird」を実装していました。Pumaの代わりにFalconをbundle installするだけで導入でき、実際にサーバサイドロジックで動くFlappy Birdを見ることができました。

テクノロジーの進化とともに、ソフトウェア開発の複雑さも増しています。しかし、RubyやRailsはその複雑さをうまく隠蔽し、「書くのが楽しい」言語であることが魅力です。今回紹介されたFalconを使うことで、インタラクティブなコードも楽しみながら学ぶことができると実感しました。ただし、パフォーマンスの観点で言えば、サーバサイドでのロジックの限界もあるため、学習用途として利用するのが現実的かもしれません。

ちなみに、私のプロジェクトでもFalconを導入しようとしてみましたが、私たちの環境ではそのままでは動作しませんでした。とはいえ、Falconの導入によるパフォーマンス改善は魅力的なので、ベンチマークを取るところまでは検証を続けたいと思います。

Embedding it(RBS Type Declaration) into Ruby code / @soutaro

speakerdeck.com

こんにちは @fumihumi です 

RBS commiterの soutaroさん のセッションでは既存のRBS定義への課題から、soutro/rbs-inline の紹介がありました。またday3のRuby Committers and the World では Matz から”rbs-inlineのようなコメントで形定義を書くスタイルについては黙認する”というコメントもありましたね。(うろ覚えなため表現が正確ではないかもしれません。) 

私のいるプロダクトでは、RBSの導入を部分的に進めており、 基本的に自動生成を用いる + 一部のみ手書きによる型定義を実施するが、チームとしてRBS定義を書くということは必須ではない、というような導入状況です。

セッション中に触れていた、型定義が別ファイルにあると更新しづらく、いわゆる手書きの型定義ファイルは適切に更新されない、されにくいという問題は事実あり、これは導入時に型定義を必ずかくという強制をせずにあくまでも書きたい(欲しい)メンバーが書くというスタイルをとったため一定仕方がないとも思っています。

そんな中でrbs-inlineによって今まで yard 相当で記載していたDocを型定義として扱えるようになる、というのは個人的にとても嬉しいものでした。

yard 自体は一定数のメンバーが書いているため、これらのメンバーに rbs-inlineのsyntaxを受け入れてさえもらえれば自然と型定義が潤っていくということになります。今までの開発フローに近い形で、型定義が潤うのは嬉しいですね。

day3では会場投票によって型定義のシンタックスについての投票があったり、セッション中でもシンタックスについては検討段階、というような形で触れていたため、まだ変わることがあるとは思いますが、さっそくプロダクトにて試してみたいと思いました。

YJIT Makes Rails 1.7x faster / @k0kubun

speakerdeck.com

@shivashin495 です。こちらはYJITに導入されている最適化に関する発表です。

day2にもBreaking the Ruby Performance Barrier / @maximecbの発表がありました。このセッションでは、YJITはRubyのバージョンを重ねるごとに高速化しており、C拡張への依存を減らして純粋なRubyで実装されたものを使用し、JIT化可能な割合を増やすことで更なる速度アップをしているという内容でした。

day3のこのセッションでは、より詳しくYJITに導入された高速化に関するテクニックの内容で、valueをstackではなくregisterを使えるようにすることで処理が高速になったなどの紹介がありました。

弊社でもRailsを使用しており、こうした高速化にワクワクしています。以前Ruby v3.1.0でYJIT有効化を試したことがありますが、当時の検証ではパフォーマンスへの改善を大きくみることができませんでした。(ref: https://hackerslab.aktsk.jp/2022/09/26/183545 )

つい最近 ruby3.3.1 へのアップデートを実施しており、セッションで聞いたような改善の恩恵を受けられるため、今回の発表の内容でどういった結果が出るのか非常に楽しみです。パフォーマンスの比較などを発表できるようにYJITの導入に挑戦してみたいと思います。

Using “modern” Ruby to build a better, faster Homebrew / @MikeMcQuaid

speakerdeck.com

村上です。私からは、Macを使っているエンジニアの多くが利用していると言っても過言ではない、Homebrewのセッションについてご紹介します(そう、HomebrewもRuby製なのです)。

発表では、まずHomebrewが利用してきたRubyバージョンの変遷の確認から始まりました。リリースからつい最近まではOSに同梱されたRuby(”System Ruby”と呼ばれることが多いようです)を使っていたようなのですが、OSの更新や年月が経過してもなかなか新しくならず、2023年になってもRuby 2.6で動作していたとのことでした。Ruby 2.6は2018年に初版リリースされたものになるので、相当古いランタイムを使い続けていたわけですね。

そんな状況に痺れを切らしてか、2023年にHomebrewは独自ビルドのRuby(Portable Ruby)に切り替えを果たします。切り替え当初はRuby 3.1でしたが、ちょうどRubyKaigiの期間中にRuby 3.3に対応したとのことでした 🎉

~  $ brew config | grep ruby
Homebrew Ruby: 3.3.1 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.3.1/bin/ruby

コマンドの出力を見ると、確かにRubyが更新されています。自分たちの都合に合わせてランタイムのバージョンを制御できるようになった点は、メンテナンスの面でかなり良いことなのではないでしょうか。

また、HomebrewとRubyエコシステムの関係も説明がありました。Homebrewのパッケージ定義はFormulaと呼ばれるRubyのDSLで記述されているのですが、その記法チェックやテストにRuboCopやSorbet, RSpecを利用しているそうです。これらによりPRレビューを一定自動化できているとのことで、広く認知されているツール群が活用されていることが分かりました。

発表中はHomebrew FormulaのDSLにも少し触れられていたのですが、設定ファイルと似た形で簡単かつ綺麗に記述ができる点から、Rubyとの相性の良さが伺えます。

これを見ると、アプリケーション組み込みのスクリプトでもmrubyを用いればもっと綺麗なDSLで書けるかもしれないと希望を感じました。その分野で有名な Lua(JIT) の組み込みやすさとパフォーマンスの高さはもちろん魅力的なのですが、Ruby特有の「書きやすさ」は開発効率・メンテナンス性の面でこそ輝きます。ユースケース次第とはいえ、プロダクトで使えるかを積極的に検討してみても良いのかもしれませんね。

まとめ

今回は沖縄での開催ということで、講演の挨拶も「はいさい!」と明るい雰囲気でした。海外の方も観光を含め非常に楽しんでいる様子でした。開催地を楽しめるのもRubyKaigiの素敵なところですね!

また、RubyKaigiの1週間ほど前に、弊社が公開しているOctoballというOSSにPRを送っていただいた方とOfficialPartyで偶然お会いしました。こんな出会いがあるのもRubyKaigiのいいところです!

来年度は松山で開催されるとのことで、今から非常に楽しみです!!