Cloud SpannerのTTLを利用したデータの自動削除

この記事は「GCP(Google Cloud Platform) Advent Calendar 2022」の23日目のエントリーです。

Cloud SpannerはGoogle Cloud Platformで提供されている、フルマネージドなリレーショナルデータベースです。
Cloud SpannerにはTTL(データの有効期限)を設定して、自動でデータ削除する仕組みが備わっています。

なぜTTLが必要なのか?

サービスは運営を続けるとデータ量は右肩上がりに増加していきます。
大量のデータを抱えたデータベースには以下のような問題が発生してきます。

  • ストレージ/バックアップ費用が増大する
  • ストレージ確保のためにCloud Spannerのノード数を増やす必要がある
  • クエリでスキャンする行数が増え、クエリのパフォーマンスが悪化する
  • 法律遵守のために特定期間しか保持してはいけないデータがある場合、データ削除のバッチ処理を定期的に実行するなどの対応が必要になる

大規模なサービスになればなるほど、これらの問題には直面する可能性は高くなります。
従来のデータベースでは、特定時期より前に生成されたデータを定期的に削除するような仕組みを自前で用意する必要がありました。

Cloud Spannerには標準でTTLの機能が備わっており簡単に自動データ削除を実現することができます。

TTLを設定する

例えば以下のようなテーブルがあるとします。

CREATE TABLE ShopOrders (
    ShopOrderId STRING(32) NOT NULL, -- 主キー
    CustomerId STRING(32) NOT NULL, -- 顧客ID
    Detail STRING(MAX) NOT NULL, -- 詳細
    CreatedAt TIMESTAMP NOT NULL, -- 注文作成日時
    UpdatedAt TIMESTAMP NOT NULL -- 注文更新日時
) PRIMARY KEY (ShopOrderId);

これは注文データを保存するテーブルで、顧客が注文をするとデータが1つ増加します。
最初は大きな問題にはならないですが、何年も利用しているとデータが増えすぎてしまいます。

何年も前の注文データは残しておく必要はあるでしょうか?
少なくともデータベース上には必要はないケースがほとんどだと思います。

では、直近3ヶ月(90日)のデータだけを残してデータが自動削除されるように設定してみたいと思います。

ALTER TABLE ShopOrders ADD ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 90 DAY));

ALTER文を実行するだけです。
こうすることで、CreatedAtから90日経過したデータを自動削除してくれるようになります。
※ CREATE TABLEで指定する方法もあります。

データに存在するTIMESTAMPを指定して「○日経過したデータを削除する」というような設定がおこなえるため、テーブルの設計時に基準となるカラムを追加しておけば後々楽ができます。

まとめ

Cloud SpannerにはTTLを設定して簡単に自動データ削除が実現できます。 自動データ削除には以下のようなメリットがあります。

  • ストレージ/バックアップ費用が削減できる
  • クエリでスキャンする行数が減り、クエリのパフォーマンスが向上する
  • 法律遵守のために特定期間しか保持してはいけないデータがある場合、簡単に削除ができる

また、TTLの設定はROW DELETION POLICYを実行するだけとお手軽に導入ができます。

この記事では簡単な条件指定だけでしたが、「注文を処理したものだけを削除する」というような高度な条件指定もできますので、公式ドキュメントなどを参考にしてください。

cloud.google.com

cloud.google.com

ゲーム開発に携わるエンジニアが大切にしていること

はじめに

2009年にWEBエンジニアとしてキャリアをスタートして、気づけば13年もエンジニアを続けてきました。

キャリアの中で一番長い時間を費やしてきたのがゲーム開発です。

ブラウザの簡単なゲームから始まり、モバゲーやGREEソーシャルゲームスマートフォンでプレイするカードゲーム、パズルゲーム、アクションゲームなど、様々なタイトルに携わってきました。

バックエンドエンジニア、フロントエンドエンジニア、Unityエンジニア、リードエンジニア、エンジニアマネージャーなど、一言にエンジニアといっても扱う技術やポジションも様々な経験を積んでいます。

そんな私が、ゲーム開発に携わるエンジニアとして大切にしている価値観を備忘録として残しておきたいと思います。

基本的にはバックエンドエンジニアなので、グラフィックスやUXなどの話は出てきません。 ※ ゲーム開発だけに限らずITエンジニアにも通じるものはあると思います。

ソフトウェアの価値は利用者が決める

ゲームに限らず、社内で利用するツールや、日々の業務を手助けしてくれるツールをつくったりしていますが、全てのソフトウェアの価値は利用者が決めるものだと思っています。

エンジニアは技術を扱いますが、技術が目的になってしまっていることがあります。

  • 最新の技術を利用することに価値がある
  • 美しくて、高速に処理ができるコードに価値がある
  • テストコードのカバレッジが100%なコードに価値がある

例えば、これらの要素をすべて満たしているが、利用者がいないソフトウェアだとしたら...価値があるといえるでしょうか? 少なくとも、ゲーム開発では価値がないと思います。

枯れた技術で、キレイじゃなくて泥臭いコードでも、多くの利用者が楽しめたり、便利だと思えるものの方が価値があると私は思います。

スケジュールと優先順位を意識する

日々様々なタスクがありますが、スケジュールと優先順位をしっかりと意識してやることが重要です。

経験上、ゲーム開発でスケジュールが予定通りに進行することは稀で、だいたいの場合遅れが発生します。
以下は開発の流れの一例です。

  1. ゲームデザイナーが仕様書を作成する
  2. ゲームデザイナーが仕様書を関係者に説明する
  3. アーティストが必要でデザインを行う
  4. バックエンドエンジニアが必要な実装を行う
  5. クライアントエンジニアが必要な実装を行う
  6. ゲームデザイナーがバランス調整を行う
  7. QA担当者が動作テストを行う
  8. エンジニアがリリースの準備を行う
  9. リリース

開発には様々な人が関わり、どこかで遅れが生じると全体にも遅れが生じます。
なので、前後の担当者のスケジュールも意識して、スケジュールを守ることが大切になってきます。

また優先順位に関しても重要です。

エンジニアは開発チーム内で起こる「Unityが起動しない」「Jenkinsが動かない」「ゲームプレイしていたらエラーになった」にようなトラブルへの対応も日々求められます。
また、運営型のゲームの場合、突然エラー発生してしまったりして緊急対応が必要になる場合もあります。

優先順位を意識せずに、トラブルを放置してしまったり、発生しているエラーを放置してしまったりといったことがないように、優先順位を意識することが大切です。

開発スピードと品質のバランス

ソフトウェア開発でよく論争されるのが「スピード VS 品質」です。

トレードオフではないと主張する声もよく聞きますが、たしかにトレードオフではないと考えています。
大前提として両立できるなら両立すべきですが、開発期間が短かったり、どちらも100%満たすのはかなりの力量が必要だったりと、常に実現できるものではありません。

そんなとき、どうするべきか?
私が持っている基準は、プレイヤーの資産に影響するところは品質重視、そうでないところはスピード重視です。

例えば、ショップでアイテムを購入する処理を考えます。
プレイヤーが商品一覧から選択したアイテムと、プレイヤーが所持しているお金を交換する処理になりますが、誤って過剰にお金を消費したり、お金だけ消費してアイテムが手に入らないということはあってはいけないことです。
こういった場合は品質を重視してテストも手厚めに実施します。

例えば、オプションで文字送りの速度を変更する処理を考えます。
プレイヤーが選択した速度にする処理ですが、バグで速度が変更できなかったとしてもプレイヤーの影響はアイテム購入にくらべて軽微なものです。

ゲーム開発では開発終了後にバグがないかQAをするので、大小様々なバグはリリース前に修正されますが、発見されずにリリースされてしまうことは避けることができません。

きちんと品質のことも考え、スピードも両立できるように、常に最適なバランスを意識する必要があります。

工数見積もり-1

仕様書から、開発にかかる時間を工数として見積もりをだすことがあります。

工数の見積もりはとても難しく、日々精度を上げていく努力が必要です。
私は工数見積もりの実践するときは、見積もりを通常通り行い、「工数見積もりした日数より、1日早く終わらせるのを本当の目標」として日々取り組んできました。

継続して達成していくことで、工数の精度を上げられるのは当然ですが、集中力を持続させたり、実装スピードをあげたりなどすることもできています。

相手の立場でコミュニケーション

「エンジニア = デスクに向かってもくもく作業して誰とも関わらない」というイメージを持っている人がいるかも知れませんがそんなことはありません。

ゲーム開発では、ゲームデザイナーと仕様の相談をしたり、エンジニア間で相談やレビューをしたり、エラー対応やQA対応などを行ったり、様々な人とコミュニケーションをする場面が多いです。
事実、コミュニケーションが苦手なエンジニアは一定数おり、コミュニケーションが上手くできるというのは武器になります。

では「コミュニケーションが上手い」とはどういうことでしょうか?
私は「相手の立場でコミュニケーション」できている人はコミュニケーションが上手いなと感じています。

多くの人がやってしまっているのが「技術用語を多用」することです。
ゲームデザイナーやアーティストは技術の知識はないので、技術用語で話されても困ってしまいます。

相手がわかる用語に置き換えて、相手が理解できる言葉でコミュニケーションすることはとても大事なことです。

エンジニアが一番偉いなんてことは全くない

ゲーム開発には多くの人が関わります。

企業によってエンジニアの立ち位置は様々ですが、エンジニアの給料が高い、エンジニアの発言権が強い、エンジニア中心の文化という企業が稀にあります。
昔ながらの老舗ゲームメーカーではプロデューサーやゲームデザイナーが強かったりしますが、ソーシャルゲームから参入したIT企業の場合にエンジニアが強いケースがあります。

ディレクターが最終決定権があるといったことは例外ですが、 基本的に特定の職種が強いなんてことはない方がよく、エンジニアが強いなんてこともありません。

実際にゲームを購入したいとなったときに、エンジニアのプログラム目的で購入する人がどれくらいいるでしょうか?
私自身そうですが、人気シリーズの新作だから、主人公キャラクターのイラストが可愛いから、面白そうなゲーム企画だからというのはゲーム購入の動機になりますが、洗練されたプログラムだからという理由でゲーム購入する人はいないでしょう。

ゲームで表舞台に立つのはプロデューサー、ディレクター、ゲームデザイナー、アーティストが多いです。
でも、実際にゲームが動くのは最終的にはエンジニアがいるからです。

全ての人が協力して完成するのがゲームであり、エンジニアが一番偉いなんてことはありません。

技術を言い訳の材料にしない

ゲーム開発は技術的なチャレンジが多くあります。

時には、目を背けたくなるような難しい課題、難しくはないがとても手間がかかる課題に立ち向かう必要があります。
そういったときに「技術を言い訳にしない」というのはとても重要です。

技術的な懸念がある場合はコミュニケーションをして、リスクをきちんと理解してもらい、その上でリスクを承知でやるのか?別のアプローチを探るのか?といったことを決めていきます。
また、チーム外のエンジニアの意見を聞いたりすることも必要になります。

『難しいのでできません』というのは本当の最終手段であり、代替案を考えたり、別のエンジニアの知識を借りるなどして、安易に技術を言い訳の材料にすべきではありません。

常に快適なゲーム体験を

キャリアのスタートがWEBエンジニアでしたが、当時の新卒研修で教えられた教訓を今でも大事にしています。

「インターネット上のサービスを開発するエンジニアにとって一番大切なことは...利用者が好きなときに利用てきるように、常に正常動作し続けられる品質を保つこと」

これは、インターネットに接続して遊ぶオンラインゲームやソーシャルゲームにも同様のことが言えます。
ゲームをプレイしようとおもったらメンテナンス中でプレイできないとき、プレイヤーはとてもガッカリしますし、ゲーム運営側もできるだけ避けたいことです。

とくにバックエンドエンジニアは大切にすべきことです。

さいごに

ゲーム開発に携わるエンジニアである私が日々大切にしていることをいくつか記載しました。
コンシューマーゲームの開発経験はないので、コンシューマーだと意識する場所が違ったりするケースは大いにあると思いますが、大目にみていただけると嬉しいです。

Webサービス・アプリ一括管理ツール「Station」が便利

ブラウザでタブを大量に開いてしまう人なんですが、Webサービス・アプリ一括管理ツール「Station」を導入したらすこぶる便利でした。

getstation.com

Statioというアプリをインストールして、よく使うWebサービス・アプリを登録すれば、Stationアプリだけで全て利用できるようになります。

一番うれしいのが、プライベート用/仕事用のGmailをそれぞれ別に登録できること。 普段利用しているGoogle Chromeだと、Chrome自体に紐づけてあるアカウントをいちいち切り替えたりしないといけないくて面倒でした。

プライベート用

仕事用

Mac用のアプリって無知なんですが、最近よくみているmonograph/堀口さんYoutubeで紹介されていて知りました。

Gitのコミットメッセージで絵文字を使う

会社の人がやっていたので真似てみる。

gitmoji.carloscuesta.me

gitmojiを使うらしいので早速セットアップする。

インストール

npmがインストールされているなら以下だけです。

npm i -g gitmoji-cli

絵文字を使ってコミットする

gitmoji -cを利用してインタラクティブにコミットができます。

$ gitmoji -c
? Choose a gitmoji: 🎉  - Initial commit.
? Enter the commit title [12/48]: First commit
? Enter the commit message:
[master (root-commit) 01736ce] :tada: First commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

gitmoji -iを実行しておくとgit commitを実行時にフックしてくれます。

$ gitmoji -i
✔ Gitmoji commit hook created successfully

$ git commit
? Choose a gitmoji: 📝  - Writing docs.
? Enter the commit title [25/48]: Update readme description
? Enter the commit message:
[master d34dee1] :pencil: Update readme description
 1 file changed, 2 insertions(+)

Github上で絵文字が表示されているのが確認できます。 f:id:tnnsst35:20200604232512p:plain

絵文字一覧を見る

絵文字のルールは事前に決めておいたほうが良さそうです。

$ gitmoji -l
✔ Gitmojis fetched successfully
🎨 - :art: - Improving structure / format of the code.
⚡️ - :zap: - Improving performance.
🔥 - :fire: - Removing code or files.
🐛 - :bug: - Fixing a bug.
🚑 - :ambulance: - Critical hotfix.
✨ - :sparkles: - Introducing new features.
📝 - :pencil: - Writing docs.
🚀 - :rocket: - Deploying stuff.
💄 - :lipstick: - Updating the UI and style files.
🎉 - :tada: - Initial commit.
✅ - :white_check_mark: - Updating tests.
🔒 - :lock: - Fixing security issues.
🍎 - :apple: - Fixing something on macOS.
🐧 - :penguin: - Fixing something on Linux.
🏁 - :checkered_flag: - Fixing something on Windows.
🤖 - :robot: - Fixing something on Android.
🍏 - :green_apple: - Fixing something on iOS.
🔖 - :bookmark: - Releasing / Version tags.
🚨 - :rotating_light: - Removing linter warnings.
🚧 - :construction: - Work in progress.
💚 - :green_heart: - Fixing CI Build.
⬇️ - :arrow_down: - Downgrading dependencies.
⬆️ - :arrow_up: - Upgrading dependencies.
📌 - :pushpin: - Pinning dependencies to specific versions.
👷 - :construction_worker: - Adding or updating CI build system.
📈 - :chart_with_upwards_trend: - Adding or updating analytics or tracking code.
♻️ - :recycle: - Refactoring code.
🐳 - :whale: - Work about Docker.
➕ - :heavy_plus_sign: - Adding a dependency.
➖ - :heavy_minus_sign: - Removing a dependency.
🔧 - :wrench: - Changing configuration files.
🌐 - :globe_with_meridians: - Internationalization and localization.
✏️ - :pencil2: - Fixing typos.
💩 - :poop: - Writing bad code that needs to be improved.
⏪ - :rewind: - Reverting changes.
🔀 - :twisted_rightwards_arrows: - Merging branches.
📦 - :package: - Updating compiled files or packages.
👽 - :alien: - Updating code due to external API changes.
🚚 - :truck: - Moving or renaming files.
📄 - :page_facing_up: - Adding or updating license.
💥 - :boom: - Introducing breaking changes.
🍱 - :bento: - Adding or updating assets.
👌 - :ok_hand: - Updating code due to code review changes.
♿️ - :wheelchair: - Improving accessibility.
💡 - :bulb: - Documenting source code.
🍻 - :beers: - Writing code drunkenly.
💬 - :speech_balloon: - Updating text and literals.
🗃 - :card_file_box: - Performing database related changes.
🔊 - :loud_sound: - Adding or updating logs.
🔇 - :mute: - Removing logs.
👥 - :busts_in_silhouette: - Adding or updating contributor(s).
🚸 - :children_crossing: - Improving user experience / usability.
🏗 - :building_construction: - Making architectural changes.
📱 - :iphone: - Working on responsive design.
🤡 - :clown_face: - Mocking things.
🥚 - :egg: - Adding or updating an easter egg.
🙈 - :see_no_evil: - Adding or updating a .gitignore file
📸 - :camera_flash: - Adding or updating snapshots
⚗ - :alembic: - Experimenting new things
🔍 - :mag: - Improving SEO
☸️ - :wheel_of_dharma: - Work about Kubernetes
🏷️ - :label: - Adding or updating types (Flow, TypeScript)
🌱 - :seedling: - Adding or updating seed files
🚩 - :triangular_flag_on_post: - Adding, updating, or removing feature flags
🥅 - :goal_net: - Catching errors
💫 - :dizzy: - Adding or updating animations and transitions
🗑 - :wastebasket: - Deprecating code that needs to be cleaned up.

ゲームができるリモートワーク環境を整えた

f:id:tnnsst35:20200419184523j:plain

コロナウィルスの影響で3月末から自宅でリモートワークしています。
今まで家には作業できる環境がなかったので、これを期に環境を整えました。

ゲーム機を置きたかったので少ない空きスペースにおてますが、もっと良い方法はないものだろうかと考え中です。

購入したもの

モニタ

ViewSonic VX3211-4K-MHD-7

www.viewsonic.com

31.5インチの4Kモニタにしました。
ASUS VA32UQとも迷いましたが、価格面と性能面で比較をして、ViewSonicに決定。

2週間ほど使った感想としては、31.5インチ大きくて最高なのと、
PCだけでなく、PS4Nintendo switchを繋いでゲームしたりもしてますが、画質もとても満足です。

コネクタがもう少しあると嬉しかったですが、今のところ全く問題ないです。

デスク

サンワサプライ シンプルデスク

デスクはサイズと価格重視で決めました。
配置スペース的にW120 × D60 が必須条件だったのですが、シンプルなデスクが意外となくて、
サンワサプライのシンプルデスクはサイズが細かく選べるのがとても良いです。

オカムラのSwiftや、FLEXISPOTのような昇降デスクも良いなーと思いましたが、予算的にアウト。

チェア

オカムラ バロンチェア
ハイバック/可動肘掛/座メッシュ/ランバーサポート

www.okamura.co.jp

チェアは大切なので、しっかりしたものをということでバロンチェアにしました。
WORKAHOLICさんのような店舗で、実際に座って色々比較してから購入できると良かったんですがそういうわけにもいかず。
普段、会社でも使ってて信頼性のあるバロンチェアで落ちつきました。

高級チェアの部類ですが、中古にしたので30,000くらい。

タイルマット

ニトリ タイルカーペット ハーゲン

バロンチェアに限らずですが、 オフィスチェアは重くて床を傷つけそうなのでカーペットを敷いています。
タイルカーペットは色の組み合わせが楽しいです。
安物なので、カーペット自体のはすぐ傷ができましたが、ダメになっても安くてすぐに買い直しできるので気軽に使えて満足です。

持ってたもの

キーボード

Happy Hacking Keyboard Professional HYBRID Type-S 英語配列/白

happyhackingkb.com

今年の誕生日に買ってもらったHHKBです。
会社ではMISTEL BAROCCO MD600を利用していて、HHKBは初めてなのでタッチミスしますが、Bluetoothでワイヤレスに接続できるのが最高です。

トラックボール

ロジクール WIRELESS TRACKBALL M570T

www.logicool.co.jp

以前から利用しているトラックボールです。

スピーカー

BOSE SOUNDLINK MINI II

数年前の誕生日に買ってもらったBOSEスピーカーです。
モニタにもスピーカーが内蔵されているので利用はしていないですが、雰囲気で置いてます。

欲しいもの

モニタアーム

モニタの下スペースを活用したい。

クラムシェル スタンド

Macを広げてスペースをとりたくないので、可能ならクラムシェルで運用したい。
ただ、クラムシェルだとhangoutやzoomのために別途カメラが必要なるのできっと買わないです。