クラウドワークス エンジニアブログ

日本最大級のクラウドソーシング「クラウドワークス」の開発の裏側をお届けするエンジニアブログ

2021年 SREチームでやったこと

この記事は クラウドワークス Advent Calendar 2021 の 11日目の記事です。

こんにちは。SREチームの@kangaechuです。 この記事ではSREチームが2021年に実施したことをまとめました。やっていることは色々で、まとまりはないですが、そこら辺はご容赦ください。

2020年の振り返り

去年までにどのようなことをしてきたかはこの記事を参照ください。

engineer.crowdworks.jp

【あらすじ】

crowdworks.jpでは2012年のサービス開始から約9年が経過していた。サービス開始当初はさくらインターネットVPSだったが、その後AWSに移行。インフラの継続的な改善は行なっていたが、サービスの成長や技術の進化に伴い、インフラ構成のモダナイズは喫緊の課題であった。2020年までに、SREチームではアプリケーションサーバのDocker化を進めたり、Chefを使用していた部分を完全になくすことでアプリケーションサーバの構成のモダン化に成功したのであった。

2021年やったこと

2021年にSREチームはこんなことをやっていました。

MySQL 5.7バージョンアップ

MySQL 5.6 on AWS RDSは2021/8/3でEOLとなりました。crowdworks.jpでは長らくMySQL 5.6を使用していましたが、EOLに伴いMySQL5.7へのバージョンアップを実施しました。

Changes in MySQL 5.7をもとにバージョンアップに伴う変更点を一つずつ確認しながら、MySQL 5.7で指定すべき設定値を一つずつ確認しました。

特にsql_modeONLY_FULL_GROUP_BYは曲者でした。ONLY_FULL_GROUP_BYを有効にした場合、GROUP BYで指定したカラム全てがSELECTするカラムであるか、推移従属している必要がありました。ActiveRecordで生成されたSQLのため、Railsのコードを修正する必要がありました。色々な場所でこの問題が発生していたため、ONLY_FULL_GROUP_BYは無効とし、5.7にバージョンアップしてから修正をする方向性としました。

リリース時にはバージョンアップに伴うSQLエラーや結果の差異、パフォーマンス悪化などを懸念していましたが、無事にリリース完了しました。

AWS DMS移行

マスタデータベースから分析系のデータベースへのレプリケーションの仕組みをSaaSのサービスからAWS DMS (Database Migration Service)に移行しました。 詳しくは以下の記事を参照ください。

engineer.crowdworks.jp

DMS に変更したことにより、レプリケーションにより発生する遅延はおおむね1分程度となり、レプリケーション遅延によりRedshiftを再起動するというダメハックはなくなりました。

Aurora移行前作業

さらなるサービス成長に備え、crowdworks.jpではデータベースサーバのAurora化を予定しています。

MySQL 5.7バージョンアップにも書きましたが、一部設定値が過去のバージョンを踏襲したものになったままのため、事前作業としてできるだけデフォルトのパラメータに近づける作業を実施しています。

先日、Aurora MySQL 3がGAとなりました。Aurora MySQL 3 はMySQL 8ベースのため、MySQL 8への移行も視野に入れる必要が出てきました。AWSを追うのは大変です。

Atlantis

crowdworks.jpのインフラはAWSを使用しており、Terraformで構成管理しています。Terraformではレビュー時に変更後の構成を確認するためterraform planコマンドを実行し、レビュー後の反映時にterraform applyコマンドを実行する必要があります。 2021年当初は以下の運用でした。

  • terraform plan: Pull Request作成時にCIでAWS CodeBuildにより実行
  • terraform apply: Pull Requestマージ後に人力で terraform apply コマンドを実行

planは自動化されていたのですが、apply時にはマージ後に手元で再度plan結果を確認し、問題ないことを確認してからapplyする作業が発生していました。これは

  • apply時に再度plan結果を確認するのが面倒
  • マージ後にapplyが正しく行われたかわからない
  • AWSの権限がないメンバーはapplyできない

などの問題がありました。そのため、Atlantisによりplan/applyをGitHubから行えるようにしています。

Atlantisによるフロー

最近はカスタムワークフローにより、tfmigrateにも対応し、リファクタリングし放題になりました。詳細は @minamijoyo の記事を参照ください。

qiita.com

Redashのバージョンアップ

crowdwowrks.jpではデータからのインサイトを重視しており、マーケティングなどのチームや施策の検討時にはそれらのデータを頻繁に参照します。crowdworks.jpの分析系データベースはAmazon Redshiftで構成されており、それらのデータを参照する際にはRedashを活用しています。

その重要性にもかかわらず、Redashは長い間バージョンアップされていませんでした。とりあえず動いているため、優先度が上がらないことと、独自に拡張した部分(残念ながらupstreamではマージされなかったもの)の2点が理由でした。

今年Redash v4をv8までアップデートしました。また、2021/10/02にv10がリリースされたため、最新版へのリリースを計画中です。

画像リサイズ処理の改善

crowdworks.jpではプロフィール・仕事・メッセージなど、さまざまな場所でユーザがアップロードした画像が使われています。それらの画像はページのさまざまな場所やデバイスで表示するため、画像ファイルへのリクエストがあった場合はリサイズしてからレスポンスを行います。

Docker移行後、画像リサイズ処理によりメモリ使用量が増加し、ECSタスクで設定したメモリ制限を超過して強制終了するようになりました。実行中の他のリクエストを巻き込んで終了するため、巻き込まれた利用者からすると体験の悪い状態となっており、改善が必要でした。

5月頃にリサイズの処理を軽量なlibvipsに変更したのですが、効果はありませんでした。 メモリのプロファイリングを行いましたが、Rubyのプログラム内でメモリリークは起きていない様子。色々原因を調べていく中、Ruby: mallocでマルチスレッドプログラムのメモリが倍増する理由(翻訳)という記事を見つけました。メモリアロケーションの問題であれば理由も納得できます。 記事の通り MALLOC_ARENA_MAX=2 を指定したところ、メモリ使用量を削減できました。 それに伴い、強制終了するタスクはなくなり、エラー率を改善することができました。

MALLOC_ARENA_MAX=2を指定前後の5xxエラー率

Rubyバージョンアップ

crowdworks.jpのRubyバージョンの更新(2.6から2.7、そして3.0)も行いました。

engineer.crowdworks.jp

私は直接関わっていなかったので詳細まで追えてないですが、「キーワード引数を通常の引数から分離」の対応が大変だったりモンキーパッチをあてたりと対応が大変そうでした。

今年のクリスマスあたりにリリースされるRuby 3.1では、YJITによるRailsのパフォーマンス改善が謳われています。期待が持てますね。

まとめ

比較的規模の大きいものだけをピックアップしたので、他にも細かい改善も色々行なっています。 こうやってまとめてみると、着実にインフラを改善し続けてきたということが可視化できていいですね。 とはいえ、まだまだ改善すべき項目やSREとしてすべきことは多くあるため、優先度の高いものから順番に行っていきます。

We're hiring!

クラウドワークスでは、SRE・バックエンド・フロントエンド・モバイルアプリなど全方位でエンジニアを募集しています。

crowdworks.co.jp

© 2016 CrowdWorks, Inc., All rights reserved.