Diverse developer blog

株式会社Diverse(ダイバース) 開発者ブログです。

YYCのバックエンドをPerl5.40とDebian Bookwormへ更新したプロジェクトを振り返る

こんにちは Diverse developer blogです。今回はプロジェクトの構想から完了まで、1年半ほどかけて行った「PerlとDebianの更新プロジェクト」を振り返ります。

なぜやったのか?

弊社のYYCは20年以上稼働しているサービス(SNS, マッチング, ライブ配信)です。ユーザーの要望に応えるため、機能開発を優先してきたことで開発環境の改善が遅れていました。

特にバックエンドの開発言語(Perl 5.8)と、コンテナOS(CentOS)のアップデートが遅れており、今後の機能開発やセキュリティ対応に課題が生じていました。

そのため、プロジェクトの目標は「開発言語とコンテナOSをLTS(long-term support)バージョンまで更新する」ことにしました。そして、課題を一つ一つ段階的に解決して、ついに目標を達成しました。現在のYYCのバックエンドは、最新のPerl5.40とDebian Bookwormで稼働しています。

どうやったのか?

ここらはプロジェクトの進行を時系列順に紹介します。

1. 段階的リプレイスで失敗した

プロジェクト当初は、当時のYYCとは別にYYC v2を開発して画面や機能ベースで段階的にリプレイスする方式をとりました。しかし、新旧のYYCから共通のDBを安全に操作するのが難しくなり、途中でリプレイスを中止しました。

当時の判断や取り組みは、YAPC::Kyoto 2023で登壇した資料 にまとまっています。この取り組みは失敗になり、段階的なリプレイスに半年ほど費やしました。しかし、サンクコストを気にせずに方針を転換して、今では正しかったと思います。

2. リファクタリングに方針転換した

段階的なリプレイスで開発したコードやリソースは完全に削除して、既存のYYCをリファクタリングする方針に切り替えました。まずは、開発環境を理想の状態に近づけることを目指しました。そして、この作業で出た差分を本番環境へ徐々に適応しました。実施した順に具体的な作業内容を箇条書きで紹介します。

  1. CentOSをDebian Busterへ移行する
    • 開発環境のコンテナOSをまずはDebianベースへ移行した
  2. mod_perl v1をStarmanとPSGI(Perl Web Server Gateway Interface)へ移行する
    • PSGIでも動作するか開発環境で検証した
    • Perlのバージョンを固定している原因のひとつがmod_perl v1だったため、mod_perlは置き換え可能か調査した
  3. Perlは5.16までアップデートする
    • 5.18にアップデートするとコードの修正箇所が多いため
      • 例えば foreach my $hoge qw(a b c) {} が使えない
      • 多数のモジュールがインストールに失敗する
    • 5.16でモジュールの整理整頓と非推奨の警告修正を優先した
  4. ファイルベースで管理していたライブラリをcpanfile経由へ移行する
    • プロジェクトで使用中のライブラリを洗い出し、必要なライブラリのみを移行した
    • すべてのパッケージを最新バージョンにアップグレードした
    • 移行できないライブラリ(社内専用、CPANに存在しない)は、専用ディレクトリを用意してコードをそのままコミットして利用する方式をとった

3. 段階的にLTSバージョンまでアップデートする

PerlもDebianも段階的にアップデートしました。まずは、Debian Busterで本番環境でも正常に稼働する確認がとれてから、Perlのアップデートへ移りました。段階的な手順は以下のとおりです。

  1. Perl5.8 + mod_perl + busterとPerl5.16 + PSGI + Starman + busterのどちらでもバックエンドが起動して単体テストとE2Eテストが通ることを確認した
  2. パフォーマンステスト(taurus)で性能劣化がないことを確認した
  3. Perl5.16 + PSGI + Starman + busterをリリースして正常に稼働した

最後にPerl5.38.2をアップデート対象にしてコードの修正をしつつ、2024年6月30日にBusterはEOLをむかえるため、Bookwormの検証も同時に開始しました。ところが、この作業中にPerl5.40がリリースされました。Perl5.38.2で動作確認がとれていたのでPerl5.40へアップデートしてリリースしました。Perl5.40 + PSGI + Starman + bookwormでリリース後、use v5.40; をすべてのPerlのコードに追記して、プロジェクトは完了しました。

4. アップデート対応で工夫したこと

このプロジェクトと同時並行で、現行環境での機能開発も継続して行っていました。そのため、Perl 5.16 + PSGIへの移行時は、新しい環境の変更をできるだけ現行環境にも取り込んでいく必要がありました。特に以下の2点を重視していました。

  • 新しい環境の変更点を現行環境の開発中でも意識できるようにして移行をスムーズに進めたい
  • コード自体は事前にリリースしておき、環境の切り替えはコンテナイメージの変更のみで行い、切り戻しをしやすい状態にしたい

これらを実現するために以下の工夫をしました。

  • Perl5.8 + mod_perl と、Perl5.16 + PSGI どちらでもプロジェクトのコードが動くように、ベースクラスで環境の違いを吸収した
  • Apache::ConstantsApache::Singletonなど環境に依存するパッケージを直接使っている場合は、プロジェクト内に同様の役割のクラスを作成して事前に移行した
  • パッケージの最新化で Perl5.8 環境から挙動やインタフェースが変わる場合には、一時的にプロジェクト内で該当のパッケージを継承したり MixIn をすることで、Perl 5.16 環境と同じように動くようにした
  • CI では Perl 5.8 + mod_perl と Perl 5.16 + PSGI の2つの環境を用意し、どちらの環境でも動作確認できるようにした

2つの環境をまたがって作業すると、混乱することはありました。しかし、切替はイメージの変更だけで行えたので、不具合の特定やロールバックはしやすい状態で移行できました。正常に移行できた後、新旧の両方で動くように工夫したコードはすべて削除しました。

やってよかったことは?

1. 課題と解決策がわかりやすくなった

アップデートを安全かつ効率的に進めるために不要なコードや機能をたくさん削除しました。考慮するコンテナの数やライブラリの数も減りました。開発言語とOSのアップデートと同時に、利用中のミドルウェアやライブラリも最新化できました。この結果、問題の特定が楽になり、新たな課題の発見とその解決策がわかりやすくなりました。

2. 取れる選択肢が増えた

開発言語もOSもLTSバージョンなので、ライブラリやパッケージが利用できないケースが減りました。以前まではOSが古いため、PerlだけでなくNode.jsなどの他のライブラリのバージョンも更新できない状況でしたが、その心配はなくなりました。

まとめ

プロジェクトを完了して、古く閉ざされた開発環境から解放されました。開発するモチベーションも上がっています。このようなプロジェクトを経験できたのは、多くのユーザーがYYCを長年利用してくれた結果だと思います。今後は、もっと早く計画的に対応できるよう、Diverseでは継続的な改善を怠らない体制を維持していきます。

ブログの内容や弊社に興味のある方は、ぜひ以下の採用ページからカジュアル面談へ!様々な意見をお待ちしています。

diverse-inc.co.jp

メール配信基盤をSendGridへ移行している話

こんにちは、Diverse developer blogです。最近弊社では、メール配信基盤の移行作業を行いました。今回はその経緯についてご紹介いたします。

背景

弊社では、複数のメール配信サービスを利用しており、AWS EC2上に構築したメールサーバーで運用していました。しかし、複数のサービスを利用することでメールの管理が煩雑になっていました。

SendGridの選定理由

SendGridに移行した主な理由はコスト削減で、具体的には月額約10万円のコストが削減されます。一方、新しいメールサービスへの移行によるコストは増加しますが、これはメンテナンスと管理の効率化によって相殺されると見込んでいます。 加えて、SendGridはサーバーレスであり、メール送信プロセスをAPIで統一できるため、AWS EC2のメールサーバー管理コストも削減されます。

sendgrid.kke.co.jp

移行手順

移行した手順と、進める際に留意したポイントについて以下でご紹介します。

1. 送信量とプランの適正確認

SendGridは、プランによって送信可能なメールの量が異なります。移行の検討段階で、現在の送信量とSendGridのプランを比較し、適切なプランを選択できるよう概算を立てました。

2. 独自ドメインの設定と認証

SendGrid上のドメイン設定(Domain Authentication)で、SPFやDKIM、DMARCに必要なDNSレコードをSendGridが自動的に生成します。それを弊社が管理するAmazon Route53へ登録します。 手順詳細については、マニュアルが用意されているので、それに従ってスムーズに進めることができました。

独自ドメインを利用する - ドキュメント | SendGrid

3. APIの実装とテスト

既存のメールサービスの使用範囲を調査し、影響範囲が最小のサービスから開発環境でSendGridへの移行作業を開始しました。SendGridの公式ライブラリではサポート外のPerlで開発しているため、REST APIへ直接リクエストする形で実装しました。事前の調査で既存システムへ置き換えられるSendGridのAPIを検討していたため、スムーズに実装自体は進めることができました。

移行作業中に苦戦したこと

移行作業中、メール送信処理後にSendGrid側で受付完了したメールが宛先に届かない問題が発生しました。調査を行いましたが解決に至らず、問い合わせて判明した原因は、SendGridのアカウントが無効化されていたことでした。SendGridの管理画面上で警告があったのを見落としていたようで、しばらく使用していないアカウントだったのが原因というオチでした。 問い合わせ後、回答が24時間以内で迅速に届いたので、今後トラブルが発生した際も迅速に対応してもらえそうです。

開発環境での実装に問題がないことを確認できた後は、SendGridを無料プランから有料プランへ切り替え、本番環境へリリースしました。

最後に

まだ移行できたサービスは一部ではありますが、この変更によりメール配信システムの効率化を図ると共に、コスト削減も達成できました。残っているサービスも順次移行作業を進めていく予定です。今後も、システムの改善に向けた取り組みを続けていきます。

Diverseエンジニアチームの2023年の開発を数字で振り返る

こんにちは。 Diverse developer blogです。今回は2023年のDiverseエンジニアチームの開発を数字で振り返った話をします。年間振り返りMTGにはエンジニア全員が参加して、CTOが数字をもとに年間を振り返ったあと、Miroを使ってCTO以外のエンジニアも2023年の開発を振り返りました。

利用した数字

振り返りMTGで利用したデータは以下の4つです。

  1. 開発生産性の指標(Git)
  2. スプリントタスクの完了タスクの数(Asana)
  3. リリースした施策の数(Notion)
  4. インシデント報告書の数(Notion)

開発生産性はGitのコミットログを使って「デプロイ頻度」や「変更障害率」を計測しています。詳しくは Diverseが開発生産性を計測する理由 - Diverse developer blog をご覧ください。

弊社はスクラムで開発しており、1スプリント1週間です。このスプリント期間だと、モバイルアプリの場合、年間リリース数は月が約4週なので約48回になります。計測すると、2023年はちょうど48回でした。一方、モバイル以外のWebフロントエンドとバックエンドはモノリポで開発しており、1日平均で約3.7回デプロイしており、エンジニア1人あたり1日に約1.6回Pull Requestを作成してmainブランチへマージしています。

単純に量のみで生産性を振り返ると、スプリントのサイクルは回っているように見えます。エンジニアからは、スプリントタスクをこなす量が昨年よりも増えた(たくさん開発や施策をこなせた)という声が出ました。

このようなエンジニアの声は、Miroを使って可視化しています。弊社の振り返りはKPTに加えて、GoodとActionを加えたGKPTAで振り返るフレームワークを採用しています*1。GoodはKeepから継続を抜いて素直に良かった出来事を書きます。ActionはTryに繋がる具体的で小さい行動を書きます。

GoodとActionを加えたのは、出来事と感情(例:◯◯が嬉しい、イラっとした、ツラかった、楽しかった)を一緒にして書きやすい枠をつくり、付箋を貼るハードルを下げたいのと、抽象的な内容になりがちなTryを具体的な行動で考える方向にシフトさせたいからです。*2

来年に向けたチャレンジ

ここまで数字のみで主に生産性を振り返りましたが、生産効率の観点でみると課題はあります。

プロダクトの施策を設計する弊社のBizチームは、施策の内容と結果をNotionに書いています。今年の施策ページ数は、38件で月に3件ほどのペースです。1スプリント1週間だと、ユーザに対してインパクトのある施策をまだ1件届ける余地がありそうです。そして、一部の施策は期待した成果にならなかったものもあります。

小出しで小さく検証するサイクルを回して、不確実性の高い市場に価値を届けるのを理想とするならば、施策の設計や実装には改善の余地がまだまだあります。

さらに、Asanaで集計した年間の完了タスク数のうち、不具合の修正タスクが約35%でした。またインシデント報告書もインシデントのレベルの高低差はありますが、年間通して数件発生しました。生産性のために効率を犠牲にしては本末転倒です。来年はこれらの数値を適切に下げて、検証のサイクルをチーム全体で回せるようにチャレンジしていきます。

まとめ

これらの数字の正確な計測は、今年から開始しました。したがって、現時点では過去と比較してどれだけ改善できたのか、また出来なかったのかわかりません。来年も引き続き計測して、自分たちの開発を感覚による感想ではなく、具体的な数字と共にどう改善できるか振り返られる状態にしていきます。

このようなチーム開発に興味のある方は、ぜひ以下の採用ページからカジュアル面談へ!様々な意見をお待ちしています。

diverse-inc.co.jp

*1:ふりかえりガイドを変更しました(第36版) - https://www.agile-studio.jp/post/update-retrospective-guide-v36

*2:付箋は社外秘もあるので一部モザイクにしています

FlutterKaigi 2023に参加してきました

はじめに

2023年11月10日(金)に開催されたFlutterのカンファレンス、FlutterKaigi2023 に参加してきましたので、その感想を綴ろうと思います。

イベント概要

FlutterKaigiは、日本において開催されるFlutter技術情報の共有とコミュニケーションを目的としたカンファレンスです。

行動規範 | flutterkaigi

flutterkaigi.jp

WebサイトもアプリもFlutter製!

FlutterKaigiは今年で3回目でオフライン開催は今年が初!

会場は、表参道のナビタイムジャパン社の1Fフロアをセッションブース2つとスポンサーブースに分かれて使用。

時間は、10:00~18:20 +after party(懇親会)のスケジュールで行われました。

印象に残ったセッション

基調講演

Googleの方による、2015年から今にいたるまでのFlutterの歴史を振り返る内容でした。

弊社はFlutter v1 がリリースされる前である2018年からFlutter開発に着手し初めていたので、発表を聞きながら回想に浸っていました。

リリースから現在に至るまで安定性とパフォーマンスアップに注力し、ドキュメントも充実しており、いい意味で枯れた技術となった現在新規プロジェクトでFlutterを採用することに躊躇する必要はないと確信しました。 またWeb〜Linux・3Dゲームに至るまでカバーしていくとのことでますます今後のFlutterの成長が楽しみになりました。

また発表中に状態管理の話題もでて、Googleの方もriverpodを使っているとのことでした。

Flutterアプリにおけるテスト戦略の見直しと自動テストの導入

発表者のチームにe2e自動テスト導入までの背景と導入時のツール選定、どこまで網羅するかの線引きの話など事例をまとめた、かなり密度が濃い発表。

Unit TestやVRTで自動テストやり尽くしたが、さらにQC効果をあげるためにe2eの導入を検討しているプロダクトを抱えてる方には大変参考になる発表でした。

Add Material touch ripples

NavitimeのKosuke MatsumuraさんによるMaterialデザインにおけるタッチエフェクトについての解説でした。 普段の開発において見落としがちなボタンへのタッチエフェクトについて、その大切さを改めて認識させてくれるスピーチでした。 個人的にはKosuke Matsumuraさんが角丸の範囲を超えてタッチエフェクトがついているボタンを見ると許せないとおっしゃっていたのが面白かったです。 基本のInkWellの他に、InkResponse, TableRowInkWell等知らなかったWidgetも紹介されていました。

Master of flutter lifecycle

まずスライドデザインがアプリ風でおしゃれだった発表。

Flutterによる基本的なlifecycleの紹介と、現状最新版であるFlutter v3.13.0とそれ以前で実装の差分について紹介する内容。

AppLifecycleListenerの登場によって、StatefulWidgetからlifecycleの実装が剥がせるようになるのは衝撃でした。

3.13.0で追加されたhiddenは主にweb用のためアプリでは気にしなくてよいというTipsも知見を得ることができました。

詳解!Flutterにおける課金実装

アプリからカレーを注文できるTOKYO MIX CURRYでの課金の実装について解説されていました。 TOKYO MIX CURRYでは購入できるのがカレーという実物のため、クレジットカードやバーコード決済、タッチ決済など多岐な決済手段を実装しています。 前半と後半に分かれており、前半では元々Swift製だったものがいかにしてFlutterに変わっていくのかのお話をされていました。 スピーカーの方が最初Flutterを採用するのは厳しいという意見だったのが、今にして思えば全然杞憂だったと言っていたのが印象的でした。

後半では実店舗での注文〜決済までできるアプリについての解説でした。 同時注文されたり、途中でキャンセルされたまま放置されることによって引き起こされるバグなどをお話しされており、アプリだけで閉じてるサービスでは想定できないバグが起きるのは興味深かったです。

今度TOKYO MIX CURRYで注文してみたいと思いました!

Dartのコード自動生成の仕組みとコード自動生成のパッケージを自作する方法について

Dartの自動生成におけるツールの紹介、コードでの実装方法の紹介を基本編、実践編の三段構成の発表。

基本編はサンプルのコードをコピーする内容だったが、数行書くだけで自動生成できるのは衝撃でした。

実践編は内容が濃く、スライドに加えてGitHubのコードを実際に触りながら学習するとよさそうな内容でした。

Flutterアプリのセキュリティ対策を考えてみる

debug/releaseビルドでの内部の仕組みの違いの紹介から、Flutterでの基本的なセキュリティ対策の紹介から便利なpluginの紹介までの発表。

リリースして満足しがちだけど、そのアプリ本当に大丈夫?と改めて考えさせられる内容で、

スライドがとても簡潔にまとめられていて、学びの多かった発表でした。

通信の中間者攻撃を防ぐためにSSLのfinger printをサーバー経由で受け渡してセットする方法が紹介されていましたがスピーチ終わりの質問でそのfinger printを受け渡しするAPIが攻撃を受けた場合にどうするのか?という質問もあり、セキュリティとは常にイタチごっこなんだなと改めて考えさせられました。

最終的にはサービスの提供者がセキュリティリスクをどこまで許容するのかしないのかの線引きをきっちりしてそれに合わせた対応をしていくことが重要なんだなと認識させられました。

魅せろ! Flutter で目を惹く UI デザインを実装する

Flutterでユーザーの目を惹くUIデザインの作り方をFlutterの奥深くにあるclass等のカスタマイズ方法や、riveによるUIデザインについて紹介されていました。 Flutter Puzzle Hackで自信を持って提出したゲームが入選せず、何かの間違いかなと思ったけど他のゲームを見てみるとすごいアニメーションで納得の結果だということをおっしゃっていて、特にゲームなどは業務アプリとは異なるレベルでUI,アニメーションに力を入れる必要があるのだと思いました。 実際に公開されているゲームもやってみましたが、私からみると十分すごかったです。

tomohiko-tanihata.github.io

個人的にはスピーチのテンポもよく、人を惹きつけるような話し方で聞いていて楽しかったです。

印象に残ったスポンサーブース

フロアは広々としてて、回りやすかったです。

弊社もシルバースポンサーで参加していました!

ノベルティでバズっていたm3社のステッカーがこちら。

Flutter開発してる人は一度は遭遇したことあるエラーをモチーフにしてて、アイデアが秀逸でした(笑)Flutter完全に理解したステッカーは完全には理解できてなかったようです。

また、ゆめみ様のブースでは、Dartのコードに関する問題が2問出題されていて、回答できたらノベルティをいただけるものでした。

Dart3のsyntaxに関するものや、riverpodに関する良問で興味深いものでした。

最後に

私個人としてはオフラインでのカンファレンス参加が久しぶりで、熱量高い参加者から刺激を受けました。

セッションも現状の他者事例や運用、開発体制などの知見が得られて身になるものばかりで、充実した時間を過ごすことができました。

来年の開催もぜひ楽しみにしています!ありがとうございました!

(写真は主宰であるkikuchyさん挨拶時の様子です)

AWS JumpStart 2023 運用編に参加しました

はじめに

こんにちは!今回は2023年10月18日に開催された「AWS JumpStart 2023 運用編」に参加してきたので、その体験レポートを残そうと思います。

参加経緯

私は普段、サーバーサイドとフロントエンドの開発に携わっています。 社内のプロダクトでAWSを使用しており、開発時のデバッグ環境構築やデプロイ、本番障害の調査などでAWSコンソールを操作する機会もあります。 AWSの知識としてはアーキテクチャ図を見て各AWSサービスの役割や基本的な概要は理解できる程度です。

弊社では「Fail Fast, Go Higher(大胆に試そう、そして成長しよう)」を行動指針のひとつとしています。

社内には専任のインフラエンジニアもいますが、AWSは開発に密接に関わるので自身でもより実践的な知識を習得したいと考えています。アプリケーションの効率的な運用とスムーズな開発を実現するために、パフォーマンスの最適化やモニタリングなど、どこに改善の余地があるかまたその実現方法としてどんなサービスがあるのか。視野を広げるヒントとなればと思い、今回の研修プログラムに参加しました。

イベント概要

「AWS JumpStart 2023 運用編」は AWS 初学者のエンジニアの方々を対象とした、実践的な研修プログラムです

将来的にAWS 活用をリードする人材になるための第一歩をスムーズに踏み出せるようなプログラムをご提供します 単なるAWS サービスの学習だけでなく、運用時に直面する具体的なユースケースや課題を例に適切な対応をご自身で検討・実施できるようになる部分にフォーカスした内容となっております

イベント当日には350人前後が参加されており、インフラエンジニア、サーバーサイド、フロントエンド、情シス、QAなどなど異なるポジションの方が集まっていました。 講義中は質問をslackに投稿していく形式で行われ、他の参加者の質問も見ることができます。自身とは異なる視点で新しい気づきにもなり、後日一通り眺めてみても面白かったです。

プログラムの内容

IaC編

講義では「Infrastructure as Code(IaC)」について学び、IaC関連のサービスである「AWS CloudFormation」と「AWS CDK」の構成、仕組み、開発フローについて解説を受けました。 ハンズオンでは「AWS Cloud9」を使いコードを書き、CDKでCloudFormationのテンプレート作成からデプロイまでの実際のプロセスを体験しました。

実施したハンズオンはこちらに公開されているので、ご興味がある方はぜひお試しください。

catalog.workshops.aws

CI/CD編

CI/CD編では必要性について学び、その実現のためのサービスのひとつとして「Amazon CodeCatalyst」が紹介されました。 ハンズオンではCodeCatalystを使用して、Issueの管理からプルリクエストの作成、デプロイまでのフローを体験しました。

実施したハンズオンはこちらに公開されているので、ご興味がある方はぜひお試しください。

catalog.workshops.aws

モニタリング編

モニタリング編ではObservability(可観測性)に焦点を当て、監視の目的について学びました。また、アンチパターンからベストプラクティスまでの実例の解説を聞けました。 ハンズオンでは「Amazon CloudWatch」を活用して、ELB、ECS、RDSのメトリクスを確認し、それをダッシュボード上に可視化できるようグラフを作成。さらに、「AWS CloudShell」を使用して、アプリに大量のリクエストを送り続ける負荷をかけ、数値やグラフの変化を観察できました。

最終的に作成したダッシュボードはこちらのようになりました。

参加してみて

ハンズオンで実際にコードを書いて印象的だったのは、CDKのコードが非常に簡潔である点です。少ない記述で、AWSのベストプラクティス設定内容がCloudFormationテンプレート生成時に自動的に反映されるため、非常に便利でした。 弊社ではTerraformを使用していますが、CDKとの利点と欠点について今後深掘りして比較してみたいなと思いました。

モニタリングでは業務上、CloudWatchを使用する機会は以前からありましたが、ダッシュボードなどは主に既存の完成したものを参照する程度にとどまっていました。ですが今回の研修プログラムを通じて、具体的なメトリクスの解釈方法やグラフの作成方法など、詳細な可視化手法を学ぶことができ、非常に有意義でした。

今回学んだ内容を起点として、さらに気になった内容を深掘りして学んでいきたいと思います。

Aurora MySQL version2 から version3にアップグレードした話

こんにちは、Diverse Developer Blogです。

今回は、2024年10月31日でEOLを迎えるAurora MySQL v2からAurora MySQL v3のアップグレードの話をします。 Blue/Green deploymentを利用してアップグレードを行ったので、その前提での内容となります。

Blue/Green deploymentを利用することで発生した問題

Blue/Green作成時に「mysql.flush_rewrite_rules」のエラーが発生する

Blue/Greenの作成ボタンを押した段階で、エラーが発生しprecheckログには「mysql.flush_rewrite_rules」に関するエラー内容がありました。

        {
            "id": "routinesSyntaxCheck",
            "title": "MySQL 8.0 syntax check for routine-like objects",
            "status": "OK",
            "description": "The following objects did not pass a syntax check with the latest MySQL 8.0 grammar. A common reason is that they reference names that conflict with new reserved keywords. You must update these routine definitions and `quote` any such references before upgrading.",
            "documentationLink": "https://dev.mysql.com/doc/refman/en/keywords.html",
            "detectedProblems": [
                {
                    "level": "Error",
                    "dbObject": "mysql.flush_rewrite_rules",
                    "description": "at line 5,8: unexpected token 'QUERY'"
                }
            ]
        },

解決策

AWSに連絡してプロシージャをDROPしてもらうことで解決しました。

本問題は RDS for MySQL DB インスタンスから移行した DB クラスターにおいて発生する場合があることを確認しております

ということで、RDS for MySQLからAuroraに移行したデータベースでは発生することがあるそうです。

Blue/Green切替ができない

Blue環境とGreen環境の切り替えが失敗してしまう

Message : Switchover from DB cluster dev-aurora to dev-aurora-green was canceled due to external replication on dev-aurora. 
Stop replication from an external database to dev-aurora before you switch over.

解決策

元々オンプレミスからRDSに移行した際に、ライターインスタンスのSlave解除をせずに運用していたため発生していました。 ライターインスタンスのリセットを行うことで解決しました。

SELECT * FROM mysql.rds_history;

もしリセットされてなかったら

CALL mysql.rds_reset_external_master;

でリセットする

MySQL5.7 → MySQL8.0 になったことによる問題

Rankが予約語になった

選択肢として、

  1. アプリケーション側でのエスケープ対応

  2. カラム名の変更

となると思いますが、エスケープ忘れなどミスが起きる可能性があるため 2. カラム名の変更 で対応しました。

移行後に特定クエリのパフォーマンスが劣化した

巨大なテーブルをJOINするクエリにおいてパフォーマンスが劣化してしまう

解決策

MySQL8.0から一時テーブルの動作が変更されていたことが原因でした。

公式ドキュメントには

一時テーブルの累積サイズが 20 GiB になることがわかっています。インメモリ一時テーブルを 2 GiB に設定し、ディスク上で最大 20 GiB に拡張します。 temptable_max_ram を 2,147,483,648 に、temptable_max_mmap を 21,474,836,480 に設定します。これらの値はバイト単位です。 これらのパラメータ設定により、一時テーブルが累積合計 22 GiB に拡張できます。

と記載がありましたが、JOINするテーブルサイズから半分程度の値でストレージエンジンパラメータ(temptable_max_ram、temptable_max_mmap)を調整する対応を行いました。 この対応によりパフォーマンスがAurora MySQL version2と同等のパフォーマンスに改善しました。

まとめ

MySQL8.0に上げて良かったこと

  • MySQL 8系統にアップグレードしたことで、以前は使用できなかったWith句など、利用したかった機能が利用可能になり分析チームの効率が上がりました。

Blue/Green deploymentを利用して良かったこと

  • 大変なDBのアップグレード作業をコンソール上の簡単な操作で実行できました。
  • 開発環境での検証中でエラー時にも正常に元の状態にリバートすることを確認できていたので、本番でも安心して作業を進めることができました。

AWS公式の記事以外で参考にした記事

Diverseが開発生産性を計測する理由

こんにちは、Diverse Developer Blogです。今回は、Diverseの開発組織の生産性と計測結果をどのように活用しているかをご紹介します。

リポジトリごとの開発生産性ダッシュボード

最初に計測中の開発生産性ダッシュボードを公開します。このダッシュボードはGoogleスプレッドシートで作成しており、データは自作したGitコマンドで集計しています。指標や計測の詳細は後述します。

計測対象は、開発が最も盛んで売上の高い弊社のサービス「YYC(https://www.yyc.co.jp)」の3つのリポジトリです。なお、Serverリポジトリは課題解決を優先して実施中なので、ClientやInfraにはない指標を追加しています。

  • Serverリポジトリ:Perl製のサーバー(API/batchなど)でWebクライアントと管理画面も含む
  • Clientリポジトリ:Flutter製のiOS/Androidのコード
  • Infraリポジトリ:AWSのリソースを管理するTerraformのコード

■ Serverリポジトリの開発生産性ダッシュボード

server_development_productivity

■ Clientリポジトリの開発生産性ダッシュボード

client(iOS, Android)_development_productivity

※ デプロイはAppleやGoogleのコンソールに次回バージョンをアップロードしたタイミング
※ ClientのRevertはデプロイ前のQAで発覚した不具合をrevertするため、本番で発生した変更障害の数と同じではありません

■ Infraリポジトリの開発生産性ダッシュボード

infra_development_productivity

なぜ計測するのか

計測する理由は2つあります。ひとつ目は社内的な理由で「開発組織を改善する手がかり」を見つけることです。

弊社では、改善の第一歩は現状を正確に把握することだと考えています。弊社のサービスは20年以上稼働しており、組織や技術に課題があります。これらの課題をできるだけ正確に把握するために開発生産性の計測を始めました。

ふたつ目は社外的な理由で「エンジニア採用時にイメージしやすい情報を使って開発組織の現状を伝えたい」からです。

弊社の採用ピッチ資料*1は全職種向けの会社紹介になっています。エンジニア採用の面接時は採用ピッチ資料に加えて、利用中の言語やフレームワークの話や、プロダクトのコードやタスクの一部を共有して開発組織の現状を紹介しています。つまり、質的な内容だけで開発組織を説明していました。ここに量的な情報も加えて開発組織をさらにイメージしやすい状態にして採用広報を進めたく、開発生産性の計測を始めました。

デプロイの頻度の計測

開発生産性で有名な指標は「デプロイの頻度」「変更のリードタイム 」「変更障害率」「サービス復元時間」の4つです。これらはFour keys*2と呼ばれています。弊社では、計測が簡単で特に重視される「デプロイの頻度」の計測から始めました。

計測はGitで作成したコマンドを各リポジトリで実行して月初にデータを集計しています。デプロイ頻度の計測方法を説明する前に弊社のデプロイフローを説明します。フローは以下のとおりです。

  1. mainブランチからreleaseブランチに向けてPRを作成する
  2. releaseブランチにPRをマージする
  3. CI/CDが本番に変更をデプロイする

つまり、releaseブランチへのPRマージ数が「デプロイの頻度」と同じになります。このマージ数を月間で集計するGitコマンドは以下のとおりです。これで毎月どれだけのデプロイがあったのか数値で把握できます。

# releaseのマージコミット数だけ対象(--since=で対象開始日を指定)
git log --merges --date=format:%Y-%m --pretty=format:'%ad %s' --since="2022-01-01" release \
| awk '{print $1}' \
| sort \
| uniq -c \
| awk '{print $2","$1}' \
| sed 's/^ *\([0-9]*\) /\1,/'

# 実行結果はCSV形式の日付とマージ数となります
2022-01,32
2022-02,27
2022-03,40
<省略>
2023-07,77

d/d/dの計測

次に計測した指標は、d/d/d (deploys/ a day / a developer)です。d/d/dは、1日あたりのデプロイ回数を開発者数で割った数値で0.1以上だと、健全な開発組織と判断する指標*3です。祝日と週末を除いた営業日数を月ごとに算出しておき、現在の開発者数*4と当月のデプロイ数を計測してd/d/dを算出します。

最近はd/d/dを計測する企業も増えましたが、d/d/dを知らないと数値を見ても開発組織の状態をイメージしづらいと思います。そこで弊社では「デプロイ数のデイリー平均(23/01~前月)」も算出して日々の開発をイメージしやすい数値でも表示しています。

Serverは1日3回ほど、Infraは1日0.8回なので2日1度ぐらいの頻度でデプロイすると言えます。一方、審査が発生するClient(iOS,Android)は少し解説が必要です。Clientは7月分の計測終了時点でデプロイ数のデイリー平均が0.27回となっています。

ClientリポジトリはreleasブランチにPRをマージすると、CI/CDでAppleやGoogleのコンソールに次回のバージョンをアップロードします。弊社のiOSとAndroidはこのタイミングをデプロイとカウントします。そして、弊社のスクラムは1スプリントを5日(土日祝日を除く1週間)にしています。つまり、5日に1度はデプロイする頻度(0.27回 x 5日 = 1.35デプロイ/週)だと言えます。

変更障害率とRevert数の計測

Four keysの「変更障害率」はRevertのコミット数を代用して計測しています。コミットメッセージの先頭にRevertやrevertのメッセージが含まれるコミットが対象です。弊社では、デプロイの変更に問題があった場合、 git revert して復旧作業を行います。Revertのコミット数を計測するGitコマンドは以下のとおりです。

# releaseのRevertコミット数だけ対象(--since=で対象開始日を指定)
# 補足: 極稀にRevertを打ち消すRevertコミットがあるため、コミットメッセージでRevertやrevertが重複するコミットはperlワンライナーで対象外にした
git log --grep="Revert\|revert" --date=format:%Y-%m --pretty=format:'%ad %s' --no-merges --since="2022-01-01" release \
| perl -ne 'print if /^(\d{4}-\d{2}) (Revert|revert)/i && (()= ($_ =~ /(Revert|revert)/ig)) < 2;' \
| awk '{print $1}' \
| sort \
| uniq -c \
| awk '{print $2","$1}' \
| sed 's/^ *\([0-9]*\) /\1,/'

# 実行結果はCSV形式の日付とRevertコミット数となります
2022-01,3
2022-02,1
2022-03,5
<省略>
2023-06,2
2023-07,6

提供するサービス内容によって水準は代わりますが、Four keysでは、最も高いパフォーマンスレベルのエリートで変更障害率は15%以下です*5。弊社のServerでは10%台になる時期もありましたが、単体テストの増加やWeb側にe2eテストを導入して改善を試みています。直近数ヶ月はデプロイ頻度が増加しても、変更障害率が10%をこえない状態を維持しています。

なお、Client(iOS, Android)のみ git revert の運用方法が他リポジトリとは異なります。本番リリース前のQAで発覚した不具合に git revert を行うため、本番で発生した変更障害と同じではありません。

廃止/削除のPRマージ率の計測

最後に弊社独自の指標である「廃止/削除のPRマージ率」を説明します。「廃止/削除のPRマージ率」とは、PRタイトルに廃止または削除の文字があるPRをmainブランチにマージした数(廃止/削除PRマージ)を、mainブランチにマージしたPRの数(PRマージ)で割った数値です。

廃止/削除PRマージ ÷ PRマージ = 廃止/削除のPRマージ率

この指標は社内のエンジニアの「廃止や削除のPRでデプロイ数が増加したのであって、ユーザーへの価値提供は増えてないのでは?」という意見から生まれました。不要な機能やコードが減って開発効率が上がるのは、基本的には良いことです。しかし、デプロイの量だけではなく質にも注目すべきと考えて計測を始めました。

Serverのダッシュボードを見ると、23年3月から6月は「廃止/削除のPRマージ率」が20%以上です。これはサービス内で利用するポイントシステムの抜本的な改善に着手したのが原因です。20年以上サービスを運営すると、現在のニーズに合わない機能や古いポイントシステムが残ったりします。そこで機能の廃止やコードの削除を改善と同時に実施しました。そして、7月にポイントシステムの改善がほぼ完了したため、現在の「廃止/削除のPRマージ率」は11%まで低下しました。

このようにポイントシステムの改善という明確な方針があって「廃止/削除のPRマージ率」が上昇するのは妥当な結果です。改善に必要な廃止や削除だったと説明できれば、チーム内の認識のズレが少なくなり、より良い振り返りがチームで行なえます。

「廃止/削除のPRマージ率」はどの程度が適切な数値でしょうか。5%以下だと機能やコードを継ぎ足してばかりな可能性がありそうです。逆に30%以上だと、コードや機能の質に問題があったり、開発環境の改善を優先し過ぎなどの振り返りができそうです。この数値の適切な水準は模索中ですが、計測し続けると見える改善点もあると考えています。

まとめ

弊社の開発生産性の指標と活用事例を紹介しました。開発組織を数値で振り返り、社内外にイメージしやすい形で公開できると、開発組織に対する認識のズレが少なくなり、より良いコミュニケーションのきっかけになります。

だだし、弊社はこれらの指標の変動を人事評価に使ったり、目標にしたりはしません。数値の改善が目的ではなく、数値が示す現状から何を改善すべきかを知る手がかりに過ぎないと考えているからです。

読者のみなさんは弊社の開発生産性から、どのような課題や改善が見えますか?もし、何か気づいた方は以下の採用ページからカジュアル面談へ!様々な意見をお待ちしています。

diverse-inc.co.jp