💭

移行業務の改善 その4 コンテナ化による生産性向上とインフラコスト削減

2023/10/03に公開

はじめに

弊社では ecforce というシステムをSaaSという形でサービスを提供しています。
ecforceの導入を希望されるクライアント様には、大きく2パターンがあります。

  • 新規で ECを立ち上げたいというクライアント様
  • 別のカートシステムを現在使っており、ecforceに乗り換えたいというクライアント様

後者につきまして、当然ながら顧客や注文データをリセットするわけにもいかないので、 既存データも引き継ぎたい という要望をいただくことが大多数です。
ただ他社のカートシステムとecforceではデータ構造が異なるので、データを抽出してそのままecforceのデータベースにインポートできるわけではありません。

この後者の要望を叶えるためにはデータを

  1. 抽出し
  2. 加工した上で
  3. ecforceのデータベースにインポートする

という手順を踏む必要があります。
これを社内では 移行業務 と呼んでおり、弊社にはこの移行業務を行う専門チームがあります。

本題

二つの課題

複合条件により、何起因でメモリ不足が発生しているかの判断が困難

当時データのインポートは、Sidekiq, Redis, Memcached, 対象ショップのテスト環境など、様々なリソースが相乗りしている本番サーバ上で直接スクリプトを実行していました。
リソースが相乗りしているということは、リソース同士でサーバのCPUやメモリをシェアしているような状態です。
そのため、移行スクリプトでの例外 Parallel::DeadWorker が発生した際に、何起因でメモリ不足になっているかが判断できませんでした。

ガーベージコレクションによる、メモリ開放の遅延

Rubyには、使われなくなったメモリを自動検知して開放する ガーベージコレクション(略: GC) という仕組みがあります。
ただし移行スクリプトのような大量のメモリを使用したり、テーブルへの書き込みが想定外の量になったりした場合、 メモリを拡張すると適切に開放されない(メモリ開放が追いつかない)可能性 があります。
それ故当時のスクリプトでは至ることろに GC.xxx というコードが書かれており、一部手動でメモリを開放させていました。
さらにメモリを拡張すると適切に開放されない可能性があるため、当時のスクリプト実行は1回目と2回目で実行環境が違う状態で行っているようなものでした。

コンテナ化

これらの課題を解決したのが コンテナ化 です。
コンテナ化したことにより以下のようなメリットをもたらしました。

  1. 冪等性の担保
  2. 複合条件の排除
  3. ローカル端末のスペックに依存しないデータインポート実行
  4. 本番サーバに依存しないデータインポート実行
  5. テスト環境構築の生産性向上

冪等性の担保

先程記載したように、当時のスクリプト実行は1回目と2回目で実行環境が違う状態で行っているような状態でした。
コンテナ化したことで、スクリプト実行する際メモリがまっさらな状態から始まるようになりました。

複合条件の排除

コンテナ化したことにより、複合条件が排除されました。
これは移行スクリプトでの例外 Parallel::DeadWorker でメモリ不足になったとき、100%移行スクリプトの設定ミスや、実装ミスと判断できるようになったということです。
つまり以下だけを意識すれば良くなりました。

  • 移行スクリプトの記述修正
  • 並列数の調整
  • チャンク数の調整

コンテナ化するということは、単一責任の法則に近いです。

ローカル端末のスペックに依存しないデータインポート実行

AWSにはコンテナを動かす環境が整っています。
バッチを動かすためのサービス AWS Batch と組み合わせたことで、CSVの加工とデータインポートをAWS上で実行できるようになりました。
これにより、エンジニアの対応工数を大幅に削減することができました。
特に大型案件をローカルで実装/実行していた時は、メモリ不足が頻発し苦行を強いられていましたので、担当メンバーの生産性が一気に向上しました。

ちなみにコンテナの実行環境は、Fargate よりも70%割引された Fargate Spot を採用しています。

本番サーバに依存しないデータインポート実行

AWS Batchによるデータインポート実行は、ローカル端末だけでなく、本番サーバとの密結合も解消しました。
これにより、様々なリソースが相乗りしていることを考慮することなくデータインポートを実行できるようになりました。
さらにAWS Batchのお陰で本番サーバのスペックのアップ/ダウングレードをせず、CSVの加工/データインポート実行時に、必要なスペックを指定するだけで良くなりました。
もし大型な案件の対応があったとしても、瞬間的なコストしかかからないため、インフラコストの削減にも繋がりました。

ちなみにAWS Batchと本番DBの接続は、 VPC ピアリング を行った上で、セキュリティグループのインバウンドルールの設定を行っています。
※詳しくは次の章で説明します。

テスト環境構築の生産性向上

移行業務はクライアントとのやり取りや、ショップをオープンさせるための準備が必要です。
そのため毎回本番環境とは別にテスト環境を構築していました。
ただテスト環境の構築は別のチームに依頼が必要で、コストが掛かっていました。
コンテナ化したことで以下と組み合わせることができ、ボタン一つでテスト環境の構築ができるようになりました。

  • コンテナ環境を動かすためのサービス ECS
  • 自動でソースコードをデプロイしてくれるビルドツール Code Build

コンテナイメージの管理

最後に移行業務において、どのような単位でコンテナイメージを管理しているかを紹介します。

  • Ruby
  • Redis
  • Sidekiq
  • ecforceのバックエンド
  • ecforceのアセット関連
  • ecforceのNginx設定
  • 移行スクリプト
  • CSVを加工するpythonコード
  • metabase (データ分析や不正データ検知で使用)

このように言語やサービス単位でコンテナイメージを管理することで、バージョンアップのしやすさや、リリースのしやすさにも繋がっています。

まとめ

今回は メモリ不足が発生の原因特定が困難GCによるメモリ開放の遅延 という二つの課題を解決するためにコンテナ化、それによるメリットについて記載しました。
コンテナ化したことにより、インフラ冪等性の担保と複合条件の排除による生産性向上はもちろんのこと、AWSとの接続により更なる生産性向上や、インフラコスト削減にも繋がりました。

次回で移行業務の進化のシリーズは最終回となります。
今まで四回に渡ってまとめた仕組みを使って、非エンジニアでも移行対応ができるようにした方法を書いていきます。

SUPER STUDIOの採用について

SUPER STUDIOでは、エンジニアを採用しています。
少しでも興味がありましたら、以下をご覧ください。
https://hrmos.co/pages/superstudio/jobs/0000400
https://hrmos.co/pages/superstudio/jobs/0000404

昨年12月に9期目を迎えたSUPER STUDIOのキックオフイベントで社内表彰されたエンジニア受賞インタビュー記事です。よりSUPER STUDIOのエンジニア組織を理解できる内容となっておりますので、ご一読ください。
https://www.wantedly.com/companies/super-studio/post_articles/497997
https://www.wantedly.com/companies/super-studio/post_articles/487617

SUPER STUDIOテックブログ

Discussion