booklista tech blog

booklista のエンジニアリングに関する情報を公開しています。

auブックパスのストア開発におけるスクラム

アイキャッチ

株式会社ブックリスタ プロダクト開発部の開発・運用を担当している片山と申します。

今回は、弊社が包括的なパートナーシップを結び開発を行なっている「auブックパス (運営:KDDI株式会社)」のストア開発におけるスクラムについて記載させていただきます。

本記事はauブックパスのストア開発でのスクラムについての説明であり、純粋なスクラムとしては正しくない内容が含まれている可能性がありますので、ご注意ください。

また、本記事は筆者が開発者であるため、開発者が参加するイベントのみに絞り込んで記載しており、開発者が参加しないイベントについては記載しておりません。

開発に集中できる仕組み

auブックパスのストア開発におけるスクラムは、開発者が開発に集中できる仕組みとなっています。

以下は、1スプリントの開発者の大まかな時間割です。

時間割

図を見ていただいて分かる通り、開発者は自分の時間の大部分を開発に使用することが出来ます。

また、スクラムとしては当然なのですが、開発者は2週間のスプリントで実施する作業をスプリントプランニングで明確にします。作業の優先度も必ず決めます。そのため、自分が何をすればよいか迷うことはありません。

メンバー紹介

スクラムチームのメンバーは以下のようになっております。(通常のスクラムとは違うメンバー構成です)

  • プロダクトマネージャー
    • マーケティング戦略に則ったプロダクト改善の立案
    • プロジェクトマネージャーと連携した各ステークスホルダーとの調整
    • リリース後の効果検証のリード
  • プロジェクトマネージャー
  • 開発者
    • ブロダクトゴールを実現するたための開発(設計・実装・テスト)
    • プロダクトの運用
  • インフラ担当者
    • AWSにおけるインフラの設計・構築
    • プロダクトの運用
  • QA担当者
    • テストの計画・実施
    • 開発者に対する品質面のレビュー
  • スクラムマスター
    • MTGのファシリテート
    • プロセスの監視・改善

スクラムの内容

朝会

毎朝10時30分から30分間だけ朝会を実施します。 朝会にはプロジェクトマネージャー、開発者、インフラ担当者、QA担当者、スクラムマスターが参加します。

プロジェクトマネージャーを除く参加者全員が前日やったこと、本日やること、今問題になっていることを報告し、情報共有します。

報告はだいたいいつも15分程度で完了し、残り15分は雑談をしています。趣味の話など仕事には関係のない会話が多いです。auブックパスのチームは全員がリモートで仕事していることが多いため、朝会の雑談は、チームワークを維持するための貴重な時間となっています。

スプリントプランニング

スプリントプランニングは、次回スプリントで各担当者が実施する作業を決める MTG です。 プロジェクトマネージャー、開発者、インフラ担当者、QA担当者、スクラムマスターが参加します。

スプリントプランニングを始める前までに、以下の作業を実施しておきます。

  • バックログの優先順位付
    • チケット管理ツール Jira を使用
    • プロジェクトを要求管理用と開発用に分けており、プロダクトマネージャーが要求管理用プロジェクトで付けた優先順位を元に、プロジェクトマネージャーが開発用プロジェクトの優先順位を決める
  • ストーリーポイントの算定
    • プランニングポーカーを用いて、開発者全員で見積もる

auブックパスのスプリントプランニングは2回に分けて実施します。スプリントを開始する4日前の月曜日にスプリントプランニング1を実施します。2日前の木曜日にスプリントプランニング2を実施します。

スプリントプランニング1では、優先度の高い順番にチケットの担当を決めます。チケットの優先度が付いていることは非常に重要で、開発者は自分が担当している未完了のチケットの中で一番優先度が高いチケットを集中して作業できるようになります。

また、チケットの担当者の割り当ては、できる限り希望者を優先して割り当てるようにしています。自分が希望したチケットを作業する方が、誰かが決めたチケットの作業をするよりもモチベーションが上がります。

スプリントプランニング1と2の間で開発者は、自分が担当となったチケットをサブタスクに分割し、作業時間を見積もります。ここで重要なのは、各チケットに対するサブタスクの洗い出しになります。出来る限り粒度の細かいサブタスクに分割することで、見積もりが正確になり、かつ、作業進捗も分かりやすくなります。

スプリントプランニング2では、各担当者のチケットにおける見積もり時間を確認し、次回スプリントで実施可能かどうかを判断します。見積もり時間が多い場合は、チケットを分割したり、チケットをバックログへ戻すなどして調整します。見積もり時間が少ない場合は、バックログにあるチケットを新たに割り当てます。

開発

ある程度の規模の開発であれば、設計、テスト仕様書作成、実装、テスト実施の順番に作業します。1スプリントで収まらない開発である場合は、それぞれの工程を別々のスプリントで実施することもあります。

設計

設計書は ConfluenceGoogle Sheets で記載することが多いです。

書き方は決めておらず、各開発者が好きな書き方で設計書を書いています。

そして、設計書は必ず他メンバーがレビューします。レビューすることで、担当者が気づかない問題を実装前に気づくことがよくあり、手戻りを防ぐことが出来ています。

テスト仕様書作成

テスト仕様書を実装前に記載することで、実装するプログラムのインプットとアウトプットを明確化します。

設計書と同様にテスト仕様書もレビューすることで、手戻りを防ぐことが出来ています。

以前は、テスト内容が十分でなく、不具合をリリースしてしまうことがありました。そこで、どの画面・機能で何を確認するべきかのテスト観点を資料化することで、全ての開発者が十分な品質を保証できるテスト仕様書を作成できるようになりました。

実装

テストファースト

可能な限りテストファーストで、Unit テストを実装するルールとしています。ただ、UI 部分など Unit テストが十分に実装できていない箇所があり、今後の課題となっています。

Linter、Formatter

Linter にて事前に分かる問題は自動で検出するようにし、Formatter にてコードのスタイルは自動で統一するようにしています。

CI/CD

GitHub でプルリクを作成したときに、 ビルド、Unit テスト、Linter を実行し、問題がない場合のみマージできるようにしています。これがあるおかげで、コードレビューの手間がかなり削減されています。

GitHub のプルリクをマージすると、AWS CodePipeline にて、自動で開発環境・ステージング環境にリリースされ、ステークホルダーがすぐに確認できるようになっています。

コードレビュー

GitHub のプルリクでは、最低一人の reviewer から approve が出ないとマージ出来ないルールとしています。

reviewer の選択は、GitHub の Code review assignment を使用し、各開発者が均等にレビュー担当となります。これにより、実装内容がバランスよく情報共有されています。

テスト実施

事前に作成しておいたテスト仕様書に従ってテストを実施します。

開発規模がある程度大きい場合は、開発者がテストを実施した後に、QA 担当者がさらにテストを実施することで、品質を保証するようにしています。

リリース

リリースは master ブランチにマージして、 AWS CodePipeline にて承認ボタンをクリックするだけで出来るように単純化されています。

ただし、一部のサービスは Jenkins を使用したリリースとなっております。Jenkins でも画面からいくつかの項目を入力して実行するだけなので、難しくはありません。

スプリントレトロスペクティブ

スプリントレトロスペクティブは終了したスプリントの反省会のようなものです。 スプリントレトロスペクティブには、プロジェクトマネージャー、開発者、インフラ担当者、QA担当者、スクラムマスターが参加します。

スプリントレトロスペクティブでは以下について、話し合います。

  • 各自の振り返り
  • ベロシティの推移の確認
  • 次回スプリントの改善目標

各自の振り返りでは、各自が個人、相互作用、プロセス、ツールに関して検査し、うまくいったこと・うまくいかなかったことを発表します。そして、うまくいかなかったことに関しては改善点をみんなで考え、うまくいったことに関してはみんなが真似できるように情報共有します。

ベロシティの推移の確認では、過去6回のスプリントと今回のスプリントのコミットメント1と完了2比較し、今回のベロシティが過去に比べてどうだったかを確認します。ベロシティの結果が過去と大きく異なる場合は、原因と対策を話合います。

スプリントレトロスペクティブの最後に、次回スプリントの改善目標をまとめます。

ナレッジ共有会

ナレッジ共有会はスクラムには関係のないイベントです。

参加は任意参加として、時間に余裕のあるメンバーのみが参加します。

開発者各自がauブックパスサービスに関わる知識、もしくは、システム開発に関わる知識を共有するための MTG です。

例えば、最近のナレッジ共有会では、以下のような知識を共有しました。

  • RDS のバックアップ
  • RDS の認証方法
  • Lambda の Layer
  • OpenVPN
  • トイルについて
  • jest の spyOn
  • 冪等性について
  • 書籍「はじめて学ぶソフトウェアのテスト技法」
  • auブックパスのアクセスログについて

用意する資料は箇条書きの簡単な文章程度で、資料作成など事前準備に時間をかけることはありません。

まとめ

以上は、2023年3月末時点のauブックパスのストア開発におけるスクラムです。

auブックパスのストア開発の今の体制が出来て2年半が経過しました。2年半の間に色々試行錯誤することで、記載したような開発方法となりました。この方法は、開発者中心の方法となっており、開発者が開発に集中出来る環境であると自負しています。


  1. スプリントプランニングで決めたストーリーポイントの合計。
  2. スプリントで完了にできたストーリーポイントの合計。

DatadogのRUM Session Replay費用削減について

アイキャッチ

こんにちは。プロダクト開発部でクラウドインフラエンジニアとして業務を行っている高澤です。

今回は、Datadogの料金削減の一環として行った、「RUM Session Replay の費用削減」についてお伝えします。

費用削減の効果を先に書くと、RUM Session Replayの料金がほぼ0ドルになりました。

この記事で伝えたいこと

Datadog の概要

Datadogとは、Datadog社が提供する監視・モニタリングのSaaSサービスです。

各リソースやクラウド(AWS,GCP,Azureなど)からメトリクス・ログなどを取り込み・連携し、モニタリングできるサービスです。

その他できることは多岐に渡ります。

Datadog の具体的な使用例

Datadogを利用し、現在以下をメインで行っています。

  • AWSのメトリクス連携をし、監視・通知
  • リソース監視・通知
  • ログを取り込み、可視化・検知
  • ダッシュボードを使用し、リソース状況やKPIを把握
  • SLO監視
  • Syntheticsテストの実施・監視・通知
  • アラート・オンコールの集約

Datadog費用削減に至る背景と見直しポイントについて

Datadogは上記機能を提供してくれて大変便利なサービスなのですが、データの取り込み量が増えるに従い、料金が増えていきます。

料金の削減が課題となり、プラン見直しも含め、Datadog営業担当の方と相談する機会を設けていただきました。

相談の結果、個々のサービスについて、最適なプラン変更などを実施していただき料金を抑える目処は付きました。

しかし「On-Demand RUM Session Replay」という請求項目については、「利用する・しない」を設定するものではありませんでした。

データを送っているとその分課金される種類の機能であり、呼び出し側でデータ送信の設定をしないといけない、と判明しました。

RUM Session Replayという機能について

この「RUM Session Replay」は、Datadogの請求から確認できる項目名です。

「RUM Session Replay」の具体的な機能としてはどのようなものでしょう、ということをまず確認しました。

を確認し、ポイントは以下です。

Datadogのセッションリプレイは、レビュー、分析、トラブルシューティングのために、ユーザーのWebブラウジング体験をキャプチャして視覚的に再生することができます。DatadogのエラートラッキングやAPMトレースによってフラグが立てられたユーザーセッションを再生することで、UXの問題をより迅速に特定し、修正することができます。

つまり、ユーザーのブラウズ操作(ユーザーセッション)をリプレイし、エラー発生や遅延を再現させ、問題解決に役立てる機能のようです。

RUM Session Replayの費用削減設定について

機能の利用有無についてチーム内確認

上記の機能説明にて「〜のようです。」という表現で書いている通り、このデータは意図して送信していたわけではなく、デフォルト設定のまま運用した結果、Datadogに送信されていたデータでした。

念の為、チーム内にて「RUM Session Replay」のデータを使った機能を利用している人がいないかを確認し、特にいないことが確認できたため、データ送信を止めることになりました。

対応方法についての確認

セッションリプレイ機能を無効にするドキュメントを確認しました。

上記ドキュメントで記述されている対応方法としては、以下です。

セッションの記録を停止するには、startSessionReplayRecording() を削除し、sessionReplaySampleRate を 0 に設定します。 これにより、リプレイを含む Browser RUM & セッションリプレイプランのデータ収集が停止します。

上記対応を実施していきます。

対応時の細かな問題

現在この機能のために使用している @datadog/browser-rum パッケージのバージョンは 3.11.0でした。

該当バージョンの場合、取りうる設定値の中に sessionReplaySampleRate という値がありませんでした。

そのため、以下パッケージのドキュメントを確認しました。

sessionReplaySampleRate の以前の値が、 replaySampleRate であったと読み取れます。

replaySampleRate については非推奨の値ですが、今回の対応ではパッケージのアップデートは見送ることとし、replaySampleRateを0としてみます。

設定及びデプロイ・設定効果確認

replaySampleRate を0に修正してデプロイします。

その結果を見るためには、Datadogにログインします。

左側メニューから「 UX Monitoring → Sessions & Replay 」を辿り、Real User Monitoring画面へ遷移します。

以下スクリーンショットのように Session Replay available にチェックを入れ、結果を見ます。

スクリーンショット

こちらで確認した結果、データが検索で出なくなっていることを確認できたため、対応完了となりました。

費用削減の結果

はじめに書いた内容の繰り返しになりますが、対応の結果、RUM Session Replayの料金がほぼ0ドルになりました。

まとめ

Datadogの料金削減ポイント・注意点を合わせてまとめると以下となります。

デフォルトのままだと意図していないデータが自動で送られ、料金高騰に繋がりますので、随時見直していきましょう。

  • 対応方法についてはドキュメントに記載されていることが多いので確認する
  • どうしてもわからない場合はDatadogサポートへ問い合わせる

機能のローンチ直後は無料であっても、有料になることが散見されますので、料金削減の観点からはなるべく明示的にデータを送らない設定にすることが有効です。

  • まず利用してみてから見極める
  • Datadogからのお知らせはよく確認し、料金改定・有料化のお知らせの場合は注意し対応を検討する

以上です。

YouTube Data API の Quota 上限アップ申請で注意すべき 3 つのこと

アイキャッチ

株式会社ブックリスタ プロダクト開発部の酒井です。

去年の秋頃、推し活アプリ「Oshibana」の新機能として「YouTube ウィジェット」を開発しました。
YouTube ウィジェットでは、ユーザーが登録中の YouTube チャンネル一覧から選択したチャンネルの最新動画および配信情報をウィジェット上に表示できます。
自分が推している YouTuber やゲーム実況者、芸能人、アイドルなどの新着動画や Live 配信を見逃さずに視聴できるので、非常に便利です。
ぜひとも使ってみてください。

YouTubeウィジェット YouTubeウィジェット



概要

ユーザーが登録中の YouTube チャンネル一覧は 「YouTube Data API」 の「Subscriptions: list」を利用して取得しています。
しかし、YouTube Data API では 1 日の API 最大使用量(Quota)が決まっています。
Quota は単純に API を呼び出した回数ではなく、呼び出し回数にコストをかけた数値になります。
API ごとにかかるコストが決まっており、例えば YouTube チャンネルの情報を取得する「channels:list」は 1 コストかかり、YouTube 動画を検索する「search:list」は 100 コストかかります。
デフォルトは 10000 であるため、その日中に「search:list」が 100 回呼ばれたら、次の 101 回目以降はエラーとなり、データが取得できなくなります。
API 実行は全ユーザーのリクエストが合計してカウントされるため、ユーザーが多ければ例え 1 コストだったとしても Quota が 10000 では心許ない数値となります。
※特に Oshibana では iOS のウィジェット上から定期的に API を実行するので、すぐに上限を超えてしまいます。

公式ドキュメント

YouTube Data API の概要 - クォータの使用量
https://developers.google.com/youtube/v3/getting-started?hl=ja#quota

YouTube Data API (v3) - Quota Calculator
https://developers.google.com/youtube/v3/determine_quota_cost

上限を上げるためには、YouTube に申請し、アプリが問題無いものであるか審査を受けて承認される必要があります。
申請内容やアプリ自体に問題があると申請が却下(リジェクト)されてしまい、以降はメールで直接 YouTube とやり取りすることになります。
相手はアメリカの企業であるため、返信メールの文面は全て英語で記述する必要があります。
基本的には Google 翻訳や DeepL 翻訳で大体伝わる内容になると思いますが、翻訳ミスにより内容が正しく伝わらない可能性もあるので、念のため文面に問題がないかある程度は確認しておいた方が良いです。

この記事では、申請を承認してもらうための注意点をできる限りまとめていきますので、これから申請を送る方たちの参考になれば幸いです。

なお、本記事の対象は iOS アプリ(ネイティブアプリ)が前提となります。
Android アプリ、Web アプリは対処法が異なる可能性がありますので、ご注意ください。



前提

この記事では、Google Cloud Platform(GCP)にて以下の作業が完了していることを前提としています。

  • プロジェクトの作成
  • YouTube Data API の有効化、API キーの取得
  • OAuth 同意画面の設定
  • Google OAuth 認証制限の解除



申請方法

申請は以下のページから行います。

YouTube API サービス - 監査と割り当て増加フォーム
https://support.google.com/youtube/contact/yt_api_form

アプリの開発組織の情報、アプリ本体(API クライアント)の情報、利用ユーザー数、API の使用方法などの基本情報を入力し、割り当てリクエストフォームの欄にて、追加割り当て量(デフォルトの 10000 から増やしたい数)、追加したい理由、追加しないとアプリで使えなくなる機能などを入力し、送信ボタンをクリックすれば申請が行われます。

申請画面は日本語でも表示できますが、内容は英語で送った方が良いです。

上限を無制限にはできないので、追加割り当て量は必要量をしっかりと計算し、申請する必要があります。
例えば Oshibana では、申請時点での API リクエストの実測値(アクティブユーザー数、画面の表示数、ウィジェット配置数など)から今後の成長予測を行い、将来の API リクエスト数を割り出し、それにコストをかけた数値を追加割り当て量として申請しています。

追加理由や上限突破で使用不可になる機能についても細かく記述しました。
追加理由については、上記の追加割り当て量の算出方法も含めてしっかりと明記した方が伝わりやすいです。



注意すべき 3 つのこと

1.デモ動画の作り方

Quota 上限アップの申請後、YouTube から「Quota の上限増加申請の理由と申請内容の根拠、および追加した Quota がどのようにアプリで利用されるのかを英語で解説した動画を準備せよ」という内容のメールが届くことがあります。
おそらく申請フォームに入力された内容だけでは判断がつかないため、実際にアプリを操作して、どのように API が呼び出されているのか、なぜ多量のリクエストが発生するのかを解説して欲しいということだと思われます。

動画は iPhone の画面録画機能を使って撮影し、YouTube へ投稿後、字幕機能を使って英語の字幕を付けました。
公開設定は「限定公開」にしており、動画の URL を返信メールで伝えています。

Oshibana のデモ動画では以下の内容を撮影しました。

  • Google OAuth 認証の手順
  • YouTube ウィジェットの作成方法およびホーム画面への配置方法
    → この時、各画面やウィジェットで実行されている API の種類や実行頻度について字幕で解説しています。
  • YouTube ウィジェットの削除方法
  • Google OAuth 認証の解除手順

特に 以下の 2 つは重要なポイントであるため、字幕でも個別に解説を入れています。

API スコープについて

API スコープとは、GCP の OAuth 同意画面で登録する「OAuth 認証の際にアプリのユーザーに許可を求める権限の範囲設定」のことです。
YouTube Data API の Subscriptions:list は「機密性の高いスコープ」に該当するため、API スコープの登録が必要となります。

「.../auth/youtube」のスコープは登録や更新等、表示以外にできることが多くなるため、「YouTube API サービス利用規約」に引っかかってリジェクトされるリスクが高くなります。
よって、API の取得結果を表示するだけなら「.../auth/youtube.readonly」で登録するのがオススメです。

GCP APIスコープ

Oshibana のデモ動画では、Google OAuth 認証の際に表示される YouTube アクセス許可ページで YouTube API が readonly のスコープであることを確認する内容を撮影しています。

アラートのメッセージが「View your videos and playlists (動画とプレイリストの表示)」となっていれば、readonly のスコープで登録されています。

ここでスコープが readonly であることをアピールすれば、YouTube からポリシー違反を指摘されるリスクが減ります。

APIスコープ APIスコープ

別件ですが、OAuth 同意画面は英語で表示されている必要があるので、表示言語を「English(United States)」に変更し、言語を切り替えている様子も撮影する必要があります。

言語変更 言語変更

API の実行方法について

YouTube API サービス利用規約 では「ユーザーの認証と認可」に関する規約があり、認証における制約やトークンの失効に関する内容が定められています。
アプリが規約を満たしていると判断されなければ、リジェクトされてしまいます。

例えば Oshibana では、「Subscriptions: list」を実行するために Google アカウントで OAuth 認証し、トークンを発行しています。
このトークンが OAuth 認証の解除処理で失効され、API が実行できなくなっていることを示す必要があります。
よって、デモ動画で Google OAuth 認証の解除手順を撮影し、トークンが失効されたことで API が実行できなくなった旨を字幕で説明しています。

ただし、API 実行に OAuth 認証を使っていない場合はその限りではありません。
Oshibana では、ホームに配置した YouTube ウィジェット上で「PlaylistItems: list」「Videos: list」「Channels: list」の API を実行していますが、これらは「非機密スコープ」の API であるため、OAuth のトークンを必要とせず API キーで実行しています。
よって、ウィジェットは OAuth 認証の解除後も API を実行し続けますが、認証不要で動く API であるためポリシーに違反してないことを字幕で説明しています。

認証の解除後も API が動いているので規約違反だと認識されないよう、API の実行箇所ごとに認証が必要なのかどうかをしっかりと解説するのがポイントです。


2.プライバシーポリシーの記載内容

以下の内容がアプリのプライバシーポリシーに記載されていないとリジェクトされます。

  • YouTube の利用規約への言及
  • アプリが YouTube API Services を使用していることの明記
  • Google のプライバシーポリシーへのリンク
  • Google のセキュリティ設定ページでアプリからのアクセス権が取り消せることについての言及

よって、Oshibana では以下のような内容をプライバシーポリシーに記載しています。

YouTube API サービスの利用
本アプリでは、動画情報などを取得するために YouTube API サービスを利用しています。
YouTube API サービスは、Google 社のプライバシーポリシー、YouTube の利用規約に基づいて提供されています。
YouTube の利用規約、YouTube API サービス利用規約、Google プライバシーポリシーについては以下をご覧ください。
Google プライバシーポリシー( https://www.google.com/intl/ja/policies/privacy/
YouTube( https://www.youtube.com/t/terms
YouTube API サービス利用規約( https://developers.google.com/youtube/terms/api-services-terms-of-service

また、ユーザーは、Google セキュリティ設定ページ( https://security.google.com/settings/security/permissions )から本アプリケーションのアクセス権を削除することで、本アプリケーションによるユーザーの Google アカウントへの接続を無効にすることができます。
ただしこれらの場合、本アプリケーションの一部の機能が使用できなくなる、または一部のページが正しく表示されなくなる場合があることをあらかじめご了承ください。

なお、プライバシーポリシーを修正した場合、本番環境にリリースしてから YouTube に返信してください。
ユーザーがプライバシーポリシーを確認できる状態になっている必要があるらしく、プライバシーポリシーの原文をファイルで送ったり、開発環境に掲載したものを共有するなどは許容されませんでした。
社内の法務確認などで時間を要する場合は早めの対応が必要です。


3.返信メールの文面

前述の通り、申請がリジェクトされ YouTube からメールが届いた場合は、指摘を解消後、英語でメールを返信する必要があります。
指摘の内容に対して、修正結果や対応方法などが明確に伝わるよう工夫すると、やり取りが少なくなります。

例えば Oshibana では、以下のような内容でメールを返信しています。

デモ動画について

指摘内容について解説した箇所を動画の再生時間を記載するなどで伝わりやすくしました。

[Response to Policy D Violations]
The application has been modified.
The points we would like to ask you to reconfirm are explained in the video.
Please turn on subtitles to confirm.
https://www.youtube.com/watch?v=XXXXXXXXXX

  • The scope of the YouTube API used was changed to readonly. (2:51〜)
  • The application connects to the YouTube API with an OAuth token, but the acquired user data is used only for display and is not stored in the DB. (3:52〜)
  • The iOS widget also calls the YouTube API, but only the YouTube API that can be executed in a non-confidential scope. The API key is then used to access the YouTube API. (5:14〜)
  • We added a button to disconnect YouTube account. (7:00〜)
    →This is in response to your point "Add an option to disconnect your YouTube account".
  • After disconnecting your YouTube account, you can switch to another YouTube account when reassociating. (8:53〜)

プライバシーポリシーについて

プライバシーポリシーは日本語で掲載しているため、英語に翻訳した状態でキャプチャを取り、追記した部分を赤枠で囲み、修正結果をわかりやすくしました。
公開されているプライバシーポリシーが日本語でも、ここで英訳した内容を伝えることができれば問題ありません。

[Response to Policy A Violations]
We have updated our Privacy Policy regarding Policy A.
https://oshibana.fun/privacy_policy.html

The red framed area in the following screenshot is the content added in this revision.

プライバシーポリシー



やってみた感想

海外の企業を相手にメールでやり取りするのは非常に大変でしたが、YouTube の字幕の付け方を覚えられたり、YouTube API サービス利用規約の内容に詳しくなったりと、申請以外にも色々なノウハウを得ることができたと思っています。
記事では全てを記載していませんが、YouTube とは実に半年近くやり取りをしており、特に後半は YouTube から指摘されたポリシー違反がなかなか解消できず、苦労しました。
やり取りが長くなると、実は過去に返答していた内容が誤って伝わっていたり、説明不足のままやり取りが進んでしまっているケースがあるので、その時は一度最初から振り返ってみるのも良いかもしれません。

長くなりましたが、本記事が皆さんの申請作業の役に立てば幸いです。

Reader StoreのPMのお仕事

アイキャッチ

自己紹介

はじめまして。プロダクト開発部の森本です。
現在、「Reader Store(運営:株式会社ソニー・ミュージックエンタテインメント)」のPMを担当しております。

PMと言っても、会社によって業務内容が多岐にわたるのでReader StoreのPMはこんなことしていますというのをイメージしていただければと思い記事にしました。

業務内容

最近実施した新機能開発の案件に沿ってお話しします。

課題抽出

2020年~2021年にかけて有名人気コミックがシリーズ完結を迎えました。
これまでReader Storeで上記シリーズを購入していたお客様は、シリーズの完結をきっかけにストアから離れてしまう可能性があります。
BIツールを使い、実際の数値を確認し、仮説を検証していきます。実際の数値を見ても、完結シリーズを購入していたお客様の数パーセントが、シリーズ完結以降、新しい商品をストアで購入していないことがわかりました。

新しく読みたいコミックがないお客様に対し、新しい出会いを提供し、ストアを継続して利用してもらいたいと考えます。
そんななかで、選んだコミックに似た商品を表示する機能(以後、「似た商品を探す」機能)を提供したいという要望が上がったので、この機能の導入について検討を進めました。

まず、「似た商品を探す」機能を導入することでどんな効果・インパクトがあるかを試算します。
ストアには新機能と同じように、タグを用いて商品を探す機能があるため、タグ機能と同じくらいの売上が見込めるのではないかと仮定しました。

また、「似た商品を探す」機能は、作品同士の似てる要素をグラフ化するなど独自性を持たせることで、お客様に楽しんでいただく機能です。その結果、利用者の拡大や利用頻度向上にも繋がるはずだと考えました。

要件整理

「似た商品を探す」機能の要件を整理していきます。

  • シリーズを指定し、似た商品を検索
  • 似た商品結果を表示するページを新設
  • コミックジャンルに限定
  • 書誌詳細、シリーズ詳細ページに結果ページへの導線を追加

新設ページの画面構成要素については、既存のデータの持ち方や既存コードを見て実現可能なものを判断しながらラフ案(ワイヤーフレーム)を作成しました。

また、このタイミングでやらないことも明確にしておきます。
今回はスモールスタートとして、改善を進めていく前提にし、コミック以外のジャンルは見送ることや、似た商品結果の利用範囲を書誌詳細やシリーズ詳細ページからの導線に限定することなどを事前に決めておきました。

各部との調整

デザイン検討・調整

要件整理で作成したラフ案をもとに、デザイナーへデザイン作成を依頼します。
今回の案件では、似ている要素を視覚的にわかりやすくするためにどうするかをポイントにしていたので、デザイン案をいくつか作成していただきました。

似た商品を探す・デザイン検討案

上記のキャプチャは一例ですが、A案のチャートの方がB案と比べて似た商品が並んだときにぱっと見て似ている要素がわかりやすいです。
ですが、検索元商品との比較がしづらいなどの課題にも気付きました。検索元商品の要素もチャート化することにより、視覚で比較できるようにする工夫を盛り込みました。

似た商品を探す・確定デザイン このようにデザイン案を見ながら、細かく関係者と議論して調整しました。

ビジネス部門との調整

ビジネス部門に向けて、開発目的や、変更内容・決まったデザインなどを共有します。
新しい機能のリリースになるため、リリース時のユーザー周知や露出の方法なども関係者を巻き込んで相談しながら決めていきました。

開発共有

開発者へ要件を説明します。
開発者が詳細設計をしていく中で、要件では明記されていなかった細かな仕様の詳細を詰めたり、開発スケジュールの確認をしたりします。

開発サポート

進捗状況や開発を進める中で出てきた課題を確認します。
必要があれば、仕様を再調整するなど、開発がスムーズに進むよう尽力します。

効果測定

「似た商品を探す」機能の効果が期待通りに出ているかリリース後に効果測定しました。
BIツールやGAの数値を見ていくつかの気付きがありました。
「似た商品を探す」機能は、他の既存機能と比較して、CVRや離脱率などでは良好な数値を出していましたが、PV数が想定していたより良くないことがわかりました。
新機能のユーザー周知が足りていないことが原因だと考え、改善するために他チームにも協力してもらい、PUSHやメルマガ配信を実施しました。さらにTOPページの露出追加を行い、多くのお客様に知っていただこうと画策中です。
このように、効果が良くない場合は改善できる方法を考え、できることから進めていきます。

案件以外の業務内容

問い合わせ対応

運用チームやCSからの問い合わせ対応を行います。
コードやデータを見て、状況確認します。

システム対応が必要な場合は、対応の進め方を検討したり、関係部門との調整したりします。

障害対応

システム障害が発生したときには、開発メンバーの音頭をとって障害対応を進めます。

開発プロセス改善

開発が迅速に進むよう、開発ルールの整備など開発プロセス改善も進めます。

全体を通して

やりがい

新しい機能をリリースして終わりではなく、効果検証をして改善を進めていくことができます。単発ではなく、一貫して関わることができます、もっとこうしたいということを実現するチャンスが多いです。

リリースした機能に対して、社内評判が良かったり、感謝の声掛けをしてもらえるとやって良かったなと感じます。
また、ユーザーからの良い感想などを見ることでも嬉しい気持ちになります。

大変なところ

さまざまな部署やチームに説明する上で、知りたいポイントがそれぞれ違います。そのため、それぞれが理解しやすいように伝えないといけないです。資料作成など時間がかかってしまい、つらいです。

やりたいことがたくさんあり、行列待ちになっているので、できないことも出てきてしまいます。優先順位を上手く決めることややらないことを判断するのは難しいです。

まとめ

Reader StoreのPMは業務が幅広く、私自身まだまだできないことも多いですが、その分やりがいがあり、成長できる仕事です。
これからも日々の業務を頑張っていきます。

最後まで読んでいただきありがとうございました。

コミックの類似性の算出とそのシステム構成について

アイキャッチ

はじめまして。プラットフォームソリューション部の山口です。
今回は、昨年2022年末にReader Store(運営:株式会社ソニー・ミュージックエンタテインメント)にてリリースされた「似た商品を探す」の裏側について紹介します。
(現在は、コミックのみで利用できる機能です。)

機能

まずは、「似た商品を探す」機能について簡単に紹介します。
簡単には、「○□ぽい本」、「□○みたいなテイストの本」 を見つけることができる機能と考えています。
現在は、あるコミックの要素を算出して、その要素と近しい作品たちが一覧となって表示されます。

例えば、幕末を舞台にしたバトルマンガであれば、そのマンガは「幕末」「バトル」「刀剣」などの要素が強いだろうと算出します。
そして、それらの要素の傾向を持っているマンガを算出しています。

このあたりは実際に、Reader Store にて好きな、 もしくは興味のあるマンガを検索し、 「似た商品を探す」を使っていただけるとわかりやすいですので
よければ一度利用してみてください。

類似性とシステム

さて、ここからはよりシステム的な面での機能説明や裏側のことについて紹介していきます。
次のような区分にわけて説明します。

  • 要素の抽出と類似性について
  • 検索方法とシステム構成

要素の抽出と類似性について

「似た」と一口に言っても、どう似ているのか、どの程度似ているのかなど気になることがあります。
その点をシステム的にどう算出し、どう表現するのかをまずは説明します。
本を構成する要素は多分にありますが、どんな本であるかがわかる1つの要素として「あらすじ」や「説明文」があります。
今回は、「説明文」に絞って説明します。

説明文を1つとっても使われている言葉・単語や表現は多岐に渡ります。
我々はまずWord2Vecなどの機械学習アルゴリズムを利用して、この表現方法を学習し、ベクトル化することを行いました。

例えば、次のように説明文を利用して、ベクトルを算出しました。

  • マンガA ならば (0.1, 0.2, 0.3)
  • マンガB ならば (0.3, 0.1, 0.6)

この時点でも、このベクトルを利用することで、似た作品の算出はできますが、「何故似たのか」「どこが似ているのか」がわかりません。

そのため、「バトル」「刀剣」などの要素についても同様にベクトル化を行い、
本ごとにどの要素と類似しているのか(その要素を持っているのか)を算出できないかと考えました。
「バトル」「刀剣」などの要素のベクトル化は、本の説明文のベクトル化と同様の手法で算出しました。

例えば、次のようにです。

  • バトル ならば (0.0, 0.0, 0.9)
  • 刀 剣 ならば (0.3, 0.1, 0.0)

これで、本のベクトルと要素のベクトルが算出されました。
次に、「本ごとにどの要素と類似しているのか」を算出します。
この算出にはいろいろな手法があります。
例えば、ユークリッド距離やCosin類似度などです。
今回は、簡単にL1ノルムを利用して、「マンガA」と「バトル」との距離を出してみます。

バトル 刀剣
マンガA 0.9 0.6
マンガB 0.7 0.6

例えば、マンガAは「バトル」が0.9、「刀剣」が0.6とバトルが強い作品だろうと算出します。
また、マンガAとマンガBは「バトル」の要素を強くもち、「刀剣」については同程度触れている作品だろうと予測できます。

結果、マンガAの似た作品として「バトル」の要素を強くもち「刀剣」要素もあるマンガBを算出します。

実際には他の計算手法の利用やスコアのBoostingなどを行っていますが、
このようなステップで、本の要素の抽出と類似性の算出をしています。

検索方法とシステム構成

本のベクトル化やその計算方法について説明しましたが、ここでは実際のシステムに落とし込んだ構成などについて紹介します。

主だったものとして以下を利用しています。

  • AWS Lambda: 本のベクトル化などの算出に利用
  • AWS ECS: APIサーバーとして
  • OpenSearch: 書籍間の類似度の計算と絞り込みのため

今回は、運用上の観点からAWSのマネージドサービスを優先的に選択しています。
簡単に、どのような利用をしているか説明します。

簡易な構成図

本のベクトル化

まず、本のベクトルの処理は、日々多くの書籍を扱う関係上、AWS Lambdaを利用しています。
AWS Lambdaの同時実行を利用することで、数分間に数万件のベクトル化を行っています。
実際には、以下の3フェーズにわけて、処理できるようにしています。

  1. 説明文の形態素解析
  2. 説明文のベクトル化
  3. 要素との類似度の算出とDBへの挿入

また、これらの処理結果は都度S3に保存することで、
途中の処理で失敗しても、中断箇所からやり直せるようにしています。

類似作品の検索

次に、ベクトル化した本同士の類似度の計算には、OpenSearchを利用しました。
OpenSearchの持っているKNN近傍検索によって、類似度の計算をしています。
さらに、ビジネス要件にそった絞り込みに関しても、OpenSearchの検索機能を利用しています。
そのため、一度のリクエストでビジネス要件にそった類似作品の抽出を行えるようにしています。

検索API

最後に、いままでの機能を外部に提供するためのAPIについて説明します。
利用状況に応じたスケールなどの運用上の観点から、AWS ECSを利用しています。
スケールに関しては、ECS キャパシティープロバイダーとEC2 Auto ScaringGroupを利用しています。
これらを利用することで、タスクの負荷状況に応じてタスクのスケールイン/スケールアウトから、
EC2インスタンスのスケールイン/スケールアウトまでを自動で行えます。
これにより、必要なタスクの増減に伴った、インスタンスの増減に繊細な注意を払う必要がなくなりました。
おかげで、一見するとシンプルな構成にできたのではないかと考えています。

最後に

本機能は、よりお客様が本と出会える機会を増やせないかという考えを元に開発が進められました。
未熟な部分もありますが、「お、こんな本があったのか」などの本との出会いの一助となれれば幸いです。

新規プロダクト開発でOpenAPIを導入した話

アイキャッチ

簡単な自己紹介

株式会社ブックリスタでスマートフォンアプリエンジニアをしている城と申します。

現在YOMcomaというショートマンガアプリを作っています。 投稿者さん、読者さんに向けたサービスを提供予定ですので、リリースまでどうぞ楽しみにお待ちくださいませ。

OpenAPIとは

REST APIの定義方法をまとめた仕様のことで、かつてはSwaggerという名称でした。 JSONまたはYAMLでREST API定義が可能ですが、公式のサンプルはほぼYAMLで記述されており、開発現場でもYAMLで記述していることが多い印象を受けます。

参画時の状況

YOMcomaは投稿者さん向けのWEBと読者さん向けのスマートフォンアプリ(以下アプリ)があり、それぞれがREST API(以下API)でバックエンドにアクセスする構成となっています。

私は読者さん向けのアプリとバックエンドの開発を担当させていただくことになりました。 そのため本記事ではアプリ⇄バックエンドAPIの話に焦点を合わせて書かせていただきます。

アプリ開発に必要なAPIの基本設計は済んでいて、各APIの概要がドキュメントにまとめてある状態だったのでまずは詳細を定義してしまう事にしました。 OpenAPIで定義したい旨をチームメンバーに相談し「便利そうだから使ってみよう」と快諾いただけました。

YAMLによるAPI定義

サンプル

上に貼ったのは非常に簡単な例ですが、まずはYAMLを書いていきました。 私はVisual Studio Codeで記述していましたが、拡張機能のSwagger Viewerを使えば画像右側のようなプレビューを見ながら記述できるので間違いに気が付きやすかったです。 また今回はOpenAPIが初見のチームメンバーにもレビューしていただきましたが、記法は調べればすぐわかるし直感的に分かりやすいと言っていただけました。

OpenAPI仕様でYAMLを記述する方法は調べるとたくさん情報が出てくるので書き方には触れませんが、必須項目ではないけれど重要だと感じたポイントに絞って書かせていただきます。

example

パラメータや要素に例を記述できます。

後述のモックサーバーを立てる場合に返却値として活用されます。 また各要素のフォーマットを明確にしておく事で齟齬が生まれにくいので記述しておくことをおすすめします。

operationId

各APIに明示的な命名ができます。

後述のソースコード自動生成を使う場合、各APIを実行する関数名に使われるので、プロジェクトの命名規則に準じて記述することをおすすめします。 後述のドキュメント生成を使う場合、operationIdが未指定だとパーマリンクが正しく設定されなくなってしまいます。

実は色々あるYAMLの使い道

APIの詳細をYAMLで記述し、準備はととのいました。 ここからはYOMcomaでどのようにYAMLを活用していたのか紹介させていただきます。

ドキュメント生成

ReDocでYAMLファイルをドキュメントとしてHTMLに変換しました。

具体的には、コミットやプッシュ時に任意のコマンドを自動で実行できるhuskyを使用し、pre-commit時にReDocを実行しています。 これによりYAMLを改変したらドキュメントも自動更新するようにしていました。 HTMLファイルならエディタが入っていない人でも見られますし、YAMLより直感的に理解しやすいです。 API定義が見られれば作業可能なチームメンバーには、git上にあるドキュメントのパスだけ伝えることで常に最新のAPIを参照してもらえます。

huskyでpre-commit時にHTMLを出力するためのコマンド例
npm install -g redoc-cli
npm install -D husky
npx husky-init
npx husky add .husky/pre-commit 'redoc-cli bundle [yaml path] -o [output path]' 

ソースコード自動生成

YOMcomaのバックエンドはTypeScript(NestJS)で、アプリはDart(Flutter)でそれぞれ自動生成しました。

API通信部分を自動生成することで仕様と実装に乖離が生まれず、結合試験が比較的スムーズであった事もよかったです。 またAPIに修正があった時、再度ソースコード自動生成をし直す事で修正の大部分が完了する事も大きなメリットでした。

バックエンド

Himenon/openapi-typescript-code-generatorでレスポンスのスキーマ部分のみ自動生成しました。

自動生成にはほんの少し実装が必要なので、手順はリンクをご確認ください。

アプリ

OpenAPI Generatorでソースコードを自動生成しました。

Modelクラスやシリアライズ処理、APIClientクラスを自動生成し、実装工数がかなり削減できました。 ライブラリへの対応も充実していて、YOMcomaでもFlutterのHTTPクライアントとしてメジャーなライブラリDioを使ったソースコード自動生成をしています。

コマンド例
brew install openapi-generator
openapi-generator generate -i [yaml path] -g dart-dio -o ./openapi

モックサーバーを立てる

Prismでモックサーバーを立てました。

YOMcomaではバックエンド開発よりアプリ開発が先行していました。 そのためバックエンドでスタブを返すことが難しく、モックサーバーの出番となりました。 PrismはYAMLのexampleに記述した値を返してくれるので、ノーコードでモックサーバーを立てることができました。

モックサーバー起動コマンド例
npm install -D prism
npx prism mock [yaml path] -p 8080

テスト実行する

Postmanでテスト実行しました。

バックエンドのAPI開発時はPostmanにYAMLをimportしてテスト実行していました。 エンドポイントやパラメータ名を入力する手間が省けてテスト効率がアップしました。

サンプル

ハマりポイント

今回OpenAPIを使ってハマったポイントです。

allOf

type: arrayの直下にallOfや複数のpropertyを入れているケースは、OpenAPI Generatorでうまく変換されませんでした。

これはソースコードに置き換えて考えると分かりやすいのですが、List型に指定可能なのは単一のクラスです。 少なくとも私の知る言語ではList<{int id, String name}>のようには書けないので、type: arrayの下に複数の値を入れたい場合は別途Schemeを定義する必要がありました。

サンプル

さいごに

OpenAPIで定義する時にはプレビュー機能があったり、プレビューからAPIを実行できたり、他にも便利な機能がたくさんあり、きっとこれからも増えていくのではないでしょうか。 また導入コストが高くないのも大きな魅力の1つと思っています。 現在YOMcoma開発は第2フェーズに入り、チームメンバー全員がYAMLを使ってAPIを改版しており、開発サイクルが定まってきていると感じています。

この記事の内容が、これからアプリ開発をされる方の何かしらのヒントになれば幸いです。

Aurora1からAurora3へアップグレードするときのアプリケーション対応の注意点について

アイキャッチ

はじめまして。プロダクト開発部に所属しているエンジニアの姚です。
今回は「Reader Store(運営:株式会社ソニー・ミュージックエンタテインメント)」のDBをAurora1からAurora3へアップグレードしたときにアプリケーション側が対応したことを話していきます。

Aurora3導入の背景

Amazon Aurora MySQL 1 (MySQL 5.6 互換) は 2023 年 2 月 28 日にサポート終了となります。
サポート期間が終了する前にアップグレードしないといけません。
また、Aurora MySQL 2 (MySQL 5.7 互換) は 2024 年 10 月 31 日にサポート終了となります。
*2022年11月時点、最新の情報は下記公式ページにご参照ください。
Amazon Aurora メジャーバージョンが利用可能な期間

Aurora2にアップグレードしても、二年後にもう一度アップグレードすることになり、二度手間になりますので、今回はAurora1からAurora3へアップグレードすることにしました。

方針

MySQL8.0ではマイナーバージョンアップ時に後方互換を担保しないため、非推奨機能は使えなくなる可能性があります。Aurora3ではまだLTS版が出てないため、AWSのサポート期間が短かいことも予想されます。
マイナーバージョンアップ時に規模の大きな改修を行わないで済むように、アプリケーションへの影響がでる非推奨機能も調査して事前対応することとしました。

対応の流れ

アプリケーション改修

  1. 開発環境の設定変更、DBエンドポイント変更、DBドライバーのバージョンアップ
  2. 事前調査結果に基づき、MySQL8.0で廃止/変更機能、非推奨機能の改修
  3. 動作検証で検知した問題の追加改修

インフラ

  1. MySQL8.0でシステム変数のデフォルト値への対応
  2. アプリケーション改修と並行してAurora3の環境構築とデータ移行

動作検証

  1. 全機能テスト
  2. 負荷試験

リリース準備

  1. リリース手順の整備(リカバリー手順も含む)
  2. リハーサル



MySQLのバージョン変更による影響調査

基本は公式ドキュメントを参照し、MySQL5.7、MySQL8.0の廃止/変更機能+非推奨機能をリストアップして、システムに影響があるかを確認します。


アプリケーションへの影響が大きい変更

  • 廃止/変更機能
    • 予約語
    • GROUP BY暗黙/明示的のソート順変化
    • クエリーキャッシュ廃止
  • 非推奨機能
    • 文字セット(utf8)
    • システム変数explicit_defaults_for_timestamp
  • 課題
    • 一時テーブルメモリ不足のチューニング



予約語

MySQL5.6, 5.7, 8.0のキーワードーと予約語変更の公式ドキュメント: Keywords and Reserved Words

  • 予約語

    下方にキーワード表がありますが、「(R)」が付いているのが予約語です。

  • キーワードだけど非予約語

    非予約語はテーブル名などの識別子として、そのまま使っても大丈夫です。

予約語リスト

参考としてMySQL5.6から8.0の間で変更がある予約語を下記にリストアップします。

追加された予約語(31件)

CUBE
CUME_DIST
DENSE_RANK
EMPTY
EXCEPT
FIRST_VALUE
FUNCTION
GENERATED
GROUPING
GROUPS
JSON_TABLE
LAG
LAST_VALUE
LATERAL
LEAD
NONBLOCKING
NTH_VALUE
NTILE
OF
OPTIMIZER_COSTS
OVER
PERCENT_RANK
RANK
RECURSIVE
ROW
ROWS
ROW_NUMBER
STORED
SYSTEM
VIRTUAL
WINDOW

削除された予約語(1件)

ONE_SHOT

予約語の対応

DB名、テーブル名、カラム名などの識別子としてそのまま使うとダメなので、バッククォートで囲みます。

-- NG
CREATE TABLE rank (id INT PRIMARY KEY, val INT); ❌

-- バッククォートで囲めばOK
CREATE TABLE `rank` (id INT PRIMARY KEY, val INT); ✅



GROUP BY暗黙/明示的なソート順変化

ソート順を指定しないとき、GROUP BYカラムによる暗黙の昇順ソート (ASCが省略されているもの)が8.0以後なくなります。
参考:ORDER BY の最適化

変更点

  1. GROUP BYの暗黙/明示的ソート順変化
-- 発行のSQL
SELECT hoge FROM fuga GROUP BY hoge;

-- 5.7までの動作
SELECT hoge FROM fuga GROUP BY hoge ORDER BY ASC;

-- 8.0での動作
SELECT hoge FROM fuga GROUP BY hoge ORDER BY NULL;

2. GROUP BYのASCとDESCの付け方

-- 5.7まで
SELECT hoge FROM fuga GROUP BY hoge ASC;

-- 8.0
SELECT hoge FROM fuga GROUP BY hoge ORDER BY ASC;

GROUP BY仕様変更対応

  1. GROUP BYでソート順を指定していない箇所に、GROUP BYカラム順にソートするように明記
  2. GROUP BYにASCとDESCが付いているがORDER BYがない箇所にORDER BYを追加



クエリーキャッシュ廃止

クエリーキャッシュは5.7.20で非推奨に、8.0で削除されます。 過去バージョンでクエリーキャッシュが活用されていた場合に性能低下の可能性がありますので、パフォーマンスの変化に気をつける必要があります。

負荷試験を実施し、パフォーマンス劣化がありましたら、下記に限らず適切に対応します。

  • 古いデータ削除やパーティションテーブルを利用して、クエリ対象のデータを減らす
  • インメモリデータベース(Redisなど)を使ったキャッシュを導入
  • ProxySQLを使ったキャッシュの導入※
  • インフラの増強

※参考:MySQL 8.0: Retiring Support for the Query Cache
ProxySQLのキャッシュは旧来のMySQLと異なり、データ更新のタイミングでキャッシュが破棄されないので注意が必要です



文字セット(utf8)

公式ドキュメントに記載がある通りutf8文字セットが非推奨になっています。

MySQLのutf8はutf8mb3のエイリアスなので、utf8mb3 文字セットに合わせて非推奨となります。将来の MySQL リリースで削除される予定のため、かわりに utf8mb4 を使用しようした方が良さそうです。

照合順序

照合順序はデータの文字の大小関係を比較する場合の基準となるものです。

MySQL 5.6は文字セットutf8の照合順序がデフォルトutf8_general_ciとなっています。MySQL 8.0の文字セットutf8mb4のデフォルトの照合はutf8mb4_0900_ai_ciになります。

utf8mb4_0900_ai_ciだと絵文字(🍣、🍺など)が区別できません。 ソート順などを現行のまま保持したい場合は、MySQL 8.0ではutf8mb4_general_ciを明示的に指定する必要があります。

注意点
データベース、テーブル、カラムが変更対象です。文字セットを変更するときCOLLATIONを明示的に指定します。

ALTER TABLE `fuga`.`hoge`
    CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

viewは作成時の照合順序が適用されるので、テーブルの照合順序を変更した後でviewを作り直す必要があります。
なお、viewの照合順序は指定できませんが、view作成時のセッションと同じ照合順序になるためview作成前にセッションの照合順序を明示的に指定します。

-- view作成前にcollationをutf8mb4_general_ciに指定
SET @@session.collation_connection = 'utf8mb4_general_ci';

-- viewを作り直す
CREATE OR REPLACE VIEW `fuga`.`hoge_view` AS
  SELECT concat('ABC',`hoge`.`hoge_column`)
  FROM `hoge`
  WHERE ...;

文字セット移行変更方式の検討

プランA. Aurora3へアップグレード後、ALTERを発行して文字セットを変更する

  • メリット
    • 移行手順が簡単
    • データ整合性は保証できる
  • デメリット
    • 照合順序変更すると、インデックスも作り直されるので時間がかかる
    • 文字セット変換のAlter文実行中は、テーブルがロックされるのでサービス稼働中に実施できない

プランB. DMSを使ってストア稼働中に文字セットを変換する

  • メリット
    • 移行中でもデータベースは利用可能の状態になる
  • デメリット
    • データ整合性のチェックが必要となる

DMSを使った場合の具体的な対応は下記のイメージになります。

  1. 移行先のDBを作成し、utf8mb4に文字セットを変更
  2. AWS DMSでレプリケーション実施
  3. データが一致していることを確認

Amazon Database Migration Serviceを使えば、文字セットが違うDB間でもデータレプリケーションが可能です。
データ量が少ないDBはプランAで対応しやすいですが、 データ量が多いDBやサービスを長時間停止することを避けたい場合は、プランBで対応する方が良さそうです。



システム変数explicit_defaults_for_timestampをOFFにするのは非推奨

explicit_defaults_for_timestampとは

システム変数explicit_defaults_for_timestampはtimestampカラムにnull値セットの処理を有効にするかどうかを決定します。
OFFになっているとき、timestampカラムにnullをセットできますが、ONにするとnullはセットできなくなります。
詳細はMySQL 公式ページをご参照ください。

MySQL 8.0 系においてexplicit_defaults_for_timestampの設定が非推奨であり、デフォルト値 ON の動作は以下となります。

-- NG timestamp null insert
INSERT INTO hoge(..., created_tm, create_user)
values (..., null ,"aaa") ❌
-- OK 
INSERT INTO hoge(..., create_user)
values (..., "aaa") ✅

ORMを利用している場合、Entityのtimestamp項目に値を未設定のまま永続化するとtimestampにnull insertが発生する可能性があります。
なお、Aurora 1において、explicit_defaults_for_timestampを設定せず、無効化になっている事象があります。
アプリケーションがnull insertのSQLを発行しているかを気をつかないといけません。

対策として、explicit_defaults_for_timestampをOFFにすることで、timestampにnull insertのパターンも正常動作できます。
Aurora 3においてパラメータグループで explicit_defaults_for_timestamp の値は変更可能ですが、実際には反映されないので注意が必要です。

AWSサポートに問い合わせをしたところ、下記対応方法を回答いただきました。

explicit_defaults_for_timestamp を無効化する必要がある場合には、アプリケーション等でのセッション開始時に "set explicit_defaults_for_timestamp=0;" を実行いただく必要がございます。
あるいは、ドキュメントの「explicit_defaults_for_timestamp が有効になっている場合...」以下の動作を前提としてアプリケーションを修正いただくこともご検討ください。

Reader Storeにおいては、アプリケーション側でtimestampにnull insertされないように対応しました。



内部一時テーブルメモリ不足のチューニング

MySQL 8.0にアップグレード後、データ量が多いテーブルは、内部一時テーブルメモリが不足する恐れがあるので、チューニングを考慮する必要があります。

内部一時テーブルと使用するストレージエンジンについて

MySQLでは一部のクエリで内部一時テーブルを作成してます。

使用されるストレージエンジンについて、MySQL 5.6ではMemoryしかありません。
MySLQ 8.0からは従来のストレージエンジンであるMemoryに加えて、TempTableが追加され、デフォルトエンジンになります。
ストレージエンジンの仕組みは、AWSのドキュメントをご参照ください。

Aurora 3での注意点

  1. Aurora3 MySQL8.0.23のTempTableに不具合がある

    指定した一時ファイルの割り当てサイズよりデータが多かった場合に、本来は使用すべきInnoDBの内部一時テーブルが使用されず、エラーが発生します。
    参考:https://forums.percona.com/t/mysql-8-0-the-table-tmp-sql1-f519f-7-is-full/10767

  2. Aurora3 で利用可能なストレージエンジン

    パラメーターグループのinternal_tmp_mem_storage_engineでエンジンを指定できますが、リーダーインスタンスはTempTableだけが使えます。

対策

従来のMemoryを使用することにより回避できます。 リーダーインスタンスでTempTableを使用する場合は、現行のテーブルサイズから一時テーブルに使用される容量を見積もり、一時テーブルのパラメーターに適切な値を指定します。
TempTableモードで使用されるストレージ上の内部一時テーブルのサイズが不足するとSQLエラーとなってしまうため、temptable_max_mmapに余裕あるサイズを指定します。



まとめ

今回はアプリケーションエンジニアの視点から、Aurora3へのアップグレードの内容をまとめてみました。
作業するときインフラ側と密にやり取りしたり、周りの協力を得られるとスムーズに進められそうです。

MySQL8.0 へのバーション変更の影響範囲はかなり広いです。ドキュメントやコードを見るだけで全ての影響点を把握しきれてない可能性があります。
全機能テストで問題を検知したこともありますから、しっかりテストを行った方が安心です。