ランサーズ Advent Calendar 2021 9日目の記事です。
ランサーズの金澤です。
現在はSREチームとQAチームを兼任しております。
QAチームの取り組みについては様々ありますが、現在は「レガシーの排除」を掲げ、
主にCakePHPのバージョンアップ(CakePHP2→CakePHP4)をメインに取り組んでいます。
CakeFestについて
CakeFestはCakePHPの国際イベントです。
毎年、世界各地で開催され、2019年は日本でも開催されました
ランサーズは2017年からCakeFestへのスポンサーを開始し、
2020年はゴールドスポンサーになっています。
CakeFest2019 東京開催での登壇
2019年の東京開催では、Proposalが採択され、登壇する機会をいただきました。
CakePHP3への滑らかな移行を考えるというテーマで発表いたしました。
この時の様子は、過去のエンジニアブログでも紹介させていただいております。
CakeFest2021 リモート開催での登壇
CakeFestは2020年以降はリモート開催となっております。
2021年もリモート開催となり、再び登壇の機会をいただくことができました。
CakeFestは国際イベントのため、英語での発表になります。
2019年の東京開催のときは、リアルタイム通訳のサポートがあったため、英語発表とは言えど、何とかなりそうだという安心感がありました。
しかしながら、今回は通訳なしのため、東京開催とは違った緊張感がありました。
進行中のリアルタイムでのやり取りに関しても自分で対応する必要があります。
心強かったのは、もう一人の日本人発表者のコネヒトの伊藤さん(@itosho)がいらっしゃったことです。
本番前に2回ほどリハーサルが行われましたが、この時も一緒に準備をさせていただきました。
※伊藤さんも当日の様子をブログにしております。
CakeFest2021 の発表内容
今回の発表内容は、「CakePHP4で自動的にMasterとReplicaを分散させる」という内容でした。
CakePHPは、データベースのMasterとReplicaを分離する仕組みをまだ用意していません。
分離が可能であれば、参照クエリを複数のリードレプリカに分散できるのですが、その仕組みがないため、プラグインを使って実現します。
このプラグインを開発したのが、元コネヒトの金城さん(@o0h_)です。
詳細は以下のブログにまとめられています。
https://tech.connehito.com/entry/cakephp-master-replica
ランサーズは、CakePHP2移行完了後にすぐにCakePHP3バージョンアップに取りかかりました。
2019年の発表の通り、CakePHP2と共存しながらのバージョンアップ体制を整えましたが、
管理画面とバッチについては新規にCakePHP3プロジェクトとしてリポジトリ分離し、
スクラッチ開発しています。
その際、データベースの分離の仕組みについては、このプラグインを採用させていただきました。
※CakePHP4リリース後は、ランサーズ側でCakePHP4対応をさせていただきました。
https://github.com/Connehito/cakephp-master-replica/pull/3
このプラグインを利用すると、CakePHPのデータベース設定において、複数のコネクションを定義することができるようになります。
Master用のRoleとReplica用のRoleをそれぞれ定義し、参照クエリを発行する直前に、Replica用のRoleに切り替え、書き込み用のクエリの直前にmasterに切り替える、といった実装を行うことで負荷分散を実現させます。
しかしながら、単純にこの実装を行うと、ソースのいたるところに切り替え処理がちりばめられてしまい、煩雑なソースコードとなってしまいます。
※現在運用中のCakePHP2では、この切り替え処理を独自実装していますが、同様にソースが煩雑になってしまっています。
アプリ開発者側の立場に立つと、開発環境ではこのような分散を意識する機会がありません。
また、煩雑な実装になることを嫌がる事情もあり、結果、Replica分散が徹底されない状態になってしまいます。
理想的なのは、参照クエリを発行するときに自動的にRead Replicaに切り替えることです。
今回の発表では、Tableクラスを継承し、クエリ発行関数をオーバーライドして、直前に切り替え処理を挿入することで、自動的に切り替えを実現させる方法を紹介しました。
具体的な実装についてはQiitaやGithubで紹介していますので、興味がある方は参照して合わせてご覧ください。
発表当日の失敗談
リハーサルでは、発表順にカメラの表示、スライドの共有チェック等を簡単に行いましたが、本番のプレゼンの表示で失敗をしていたことに後で気づきました。
2019年の東京開催でも、今回の開催でも、英語で発表するにあたり、スライドのノートに翻訳内容を事前に記入しておきました。
PowerPointは、発表の際は外部スクリーンに全画面を表示し、手元PCのモニタには次のスライドと翻訳のカンペを表示させることができます。
リモート発表においてもその機能を利用することは可能で、リモート先では全画面表示にして、自分の手元ではカンペを表示することができます。
事前の社内リハーサルにおいては、ZoomでもGoogle meetでもその機能が使えることを確認していました。(ただし確認は、リモート先の見ている人に口頭で確認が必要)
CakeFestでは、リモートのMTGツールにRing Centralというものを利用していたのですが、これは、その機能が有効にならず、視聴者側にカンペが表示された状態で発表してしていました。
発表後に日本人の視聴者から教えてもらって、相当落ち込んだのですが、他の世界各地の視聴者はそれを気にする素振りも全く見せておらず、何事もなく自分の発表は終わってしまいました。
(自分が気にしすぎなだけ?)
発表当日のビデオがこちら(自分は見ていませんが。。)
その後の影響について
今回、私のProposalが採用された背景として、CakePHPにもMasterとReplicaを切り替える仕組みの導入を検討している背景があったようです。
以前、議論されてたIssueがこちら。
https://github.com/cakephp/cakephp/issues/9197
CakeFest終了後に、CakePHPのSlackで発表内容についての質問を受けました。
最初、視聴者からの質問だと思って答えていたのですが、話していくうちに、CakePHPのコアデベロッパーの方だということがわかりました。
CakePHPにMasterとReplicaを分離する機能を標準で欲しいかを知りたかった様子でした。
そこで、
・MasterとReplicaを分離する機能は標準で欲しい
・MasterとReplicaでそれぞれ別のコネクションを持ち、いちいち切り替えなくても良くしたい
・Replica Lagは常に難しい問題だが、自分の環境ではAWS Auroraにしてからその問題は無視できるようになった
という意見、およびリクエストをさせていただきました。
これをきっかけに、CakePHPに読み取りと書き込みの両コネクションをサポートするIssueが始まっています。
https://github.com/cakephp/cakephp/issues/16095
最後に
国際イベントの中で、自分の発表内容がどれだけ意味のあることか、また、行っているアプローチが妥当なものかどうか常に自問自答しながらの発表でしたが、その後の視聴者やコアデベロッパーの方々からリアクションをいただけたことは、登壇した甲斐あったと思えました。
ほんの少しですが、CakePHPへの開発に貢献できたと感じることもでき、良い体験ができたと思います。