Slide 1

Slide 1 text

Scala アプリケーションのビルドを改善して デプロイ時間を 1/4 にした話 2024/09/06 Scalaわいわい勉強会 #3 Copyright © 3-shake, Inc. All Rights Reserved.

Slide 2

Slide 2 text

自己紹介 門脇 拓巳 (KADOWAKI Takumi) 株式会社スリーシェイク Incubation 事業部 Reckoner 開発チーム データ処理系 Scala 製アプリケーションの 開発を行いつつ、インフラ業務などを担当 X (Twitter): @nomadblacky GitHub: NomadBlacky

Slide 3

Slide 3 text

Reckoner というデータ連携サービスを開発してます https://reckoner.io/ 裏側のデータ処理部分が Scala アプリケーションです

Slide 4

Slide 4 text

アジェンダ デプロイ、快適ですか? つらい😭😭😭 これをなんとかしました、というお話です

Slide 5

Slide 5 text

前提 - デプロイには Cloud Build を使用 - デプロイ時間には Scala アプリ以外のビルドも 含まれる - が、大半は Scala アプリのビルド - Scala アプリのビルド手順 - Scala ビルド用コンテナイメージのビルド - アプリケーションのコンパイル - docker build - docker push (to: Artifact Registry) - sbt-native-packager を使用 - コンテナイメージを 100種類以上 (!) 作成 Scala ビルド部分 約 40 分

Slide 6

Slide 6 text

改善したこと - ビルド用のコンテナイメージを事前に作成しておく - ライブラリ依存のキャッシュを使う - sbt のリモートキャッシュを使う - Cloud Build の実行リージョンを asia-northeast1 にする - gsutil をやめて gcloud storage を使う - docker build/push の並列化

Slide 7

Slide 7 text

ビルド用のコンテナイメージを事前に作成しておく Dockerfile が更新されたら GitHub Actions で イメージをビルドするよう設定

Slide 8

Slide 8 text

ビルド用のコンテナイメージを事前に作成しておく ビルド済みのイメージを使用して 毎回実行されないように

Slide 9

Slide 9 text

ライブラリ依存のキャッシュを使う ci.yml deploy.yml CI で作成したライブラリ依存の キャッシュをデプロイに利用

Slide 10

Slide 10 text

sbt のリモートキャッシュを使う CI 時にあらかじめ pushRemoteCache で コンパイルキャッシュを保存 ライブラリ依存とともにアーカイブ

Slide 11

Slide 11 text

sbt のリモートキャッシュを使う デプロイ実行時に pullRemoteCache で コンパイルキャッシュを展開

Slide 12

Slide 12 text

Cloud Build の実行リージョンを asia-northeast1 にする キャッシュや Artifact Registry は asia-northeast1 にあるので リージョンを合わせる global だとどのリージョンでビルドが実行されるかわからない 実行リージョンによっては無駄なネットワーク転送が発生していた

Slide 13

Slide 13 text

gsutil をやめて gcloud storage を使う https://cloud.google.com/blog/ja/products/storage-data-transfer/new-gcloud-storage-enables-super-fast-data-transfers

Slide 14

Slide 14 text

gsutil をやめて gcloud storage を使う イメージとコマンドを置き換えるだけでOK (gsutil のすべての機能が使えるわけではない点には注意)

Slide 15

Slide 15 text

docker build/push の並列化 docker build 対象の サブプロジェクトがあまりにも多い …

Slide 16

Slide 16 text

docker build/push の並列化 native-packager の publishLocal で docker build すべてのサブプロジェクトに対して 並列で docker push コマンドを実行 before

Slide 17

Slide 17 text

docker build/push の並列化 https://docs.docker.com/reference/cli/dockerd/ --max-concurrent-uploads int Set the max concurrent uploads (default 5) docker daemon はデフォルトでレイヤーのアップロードは 5並列 に制限されている Cloud Build のジョブはひとつのインスタンス上で実行されるため、 単に docker push コマンドを並列で実行してもこの制約に引っかかる 並列で docker push できていると思っていたが …

Slide 18

Slide 18 text

docker build/push の並列化 native-packager の stage で Dockerfile を出力 after 1. Dockerfile の生成 2. docker build/push を別インスタンスで実行 という2つの手順に修正

Slide 19

Slide 19 text

docker build/push の並列化 Dockerfile を転送して新しい Cloud Build ジョブとして docker build/push する gcloud builds submit コマンドを使用 after build_rdap2_process_images.sh サブプロジェクトの数だけ並列で実行

Slide 20

Slide 20 text

結果 デプロイ時間が 1/4 になった!! 💪🥳

Slide 21

Slide 21 text

まとめ - 一見当たり前の設定がちゃんとできてないことがあるので確認しよう - デプロイにもキャッシュを使おう - docker build/push はホスト単位で並列化しよう - そもそもコンテナイメージを大量に作らなくて済むほうがいいかも - 細かい最適化でも積み上げていくと大きな改善になるよ 少しでも参考になったら嬉しいです󰢛 良いデプロイライフを!

Slide 22

Slide 22 text

最後に Reckoner では Scala エンジニアを募集しています! - https://jobs-3-shake.com/ - https://hrmos.co/pages/threeshake/jobs/E_0220