$30 off During Our Annual Pro Sale. View Details »

システムリプレイスプロジェクト発足から7年、改めてコスト最適化に向き合う / replace ...

takumi
November 30, 2024

システムリプレイスプロジェクト発足から7年、改めてコスト最適化に向き合う / replace and cost optimization

takumi

November 30, 2024
Tweet

More Decks by takumi

Other Decks in Technology

Transcript

  1. © ZOZO, Inc. 株式会社ZOZO EC基盤開発本部 SRE部 カート決済SREブロック ブロック長 横田 工

    2013年株式会社スタートトゥデイ(現ZOZO)入社 情シスからキャリアを始め商用環境のインフラ担当へ (オンプレ→クラウド→今は両方) 現在はカート決済SREとして日々奮闘中 趣味は愛車の洗車と飲酒 2
  2. © ZOZO, Inc. https://zozo.jp/ 3 • ファッションEC • 1,600以上のショップ、9,000以上のブランドの取り扱い •

    常時102万点以上の商品アイテム数と毎日平均2,600点以上の新着 商品を掲載(2024年6月末時点) • ブランド古着のファッションゾーン「ZOZOUSED」や コスメ専門モール「ZOZOCOSME」、シューズ専門ゾーン 「ZOZOSHOES」、ラグジュアリー&デザイナーズゾーン 「ZOZOVILLA」を展開 • 即日配送サービス • ギフトラッピングサービス • ツケ払い など
  3. © ZOZO, Inc. 4 はじめに • クラウドネイティブの利点を最大活用できている状態とは? システムの 安定稼働 開発生産性の

    向上 システムの 稼働コスト これら3つの要素がバランスよく保たれた状態 稼働コストに関して重要なことは「納得感」 説明がつく投資をしている状態であることが重要 本セッションはZOZOTOWNプロダクトのSREが この3つのバランスを保つために取り組んできた アプローチを紹介します
  4. © ZOZO, Inc. 7 ZOZOTOWNリプレイスについて • Since 2004〜2017 WEB (Browser)

    API (APP) 更新系DB 参照系DB • 当時のZOZOTOWN ◦ 2004年「ZOZOTOWN」誕生 ◦ オンプレミス環境での稼働 ◦ 1枚岩のモノリシックなアーキテクチャ ◦ インフラ増強を繰り返し実施し規模を拡大 • 主要技術スタック ◦ Server OS:Windows ◦ Web Server:IIS ◦ 言語:VBScript ◦ Database:SQL Server 事業規模をさらに拡大していくために              解決したい課題が・・・ DataCenter Browser APP
  5. © ZOZO, Inc. 8 ZOZOTOWNリプレイスについて • 当時抱えていた課題 システムの安定稼働に難あり • 正月の0時から新春セールを行うのがZOZOTOWNでは慣例であり当時は最大級のイベント

    ◦ 毎年冬が近づくと大量のWEB・APIサーバーを増強(1からセットアップ) ◦ イベントのトラフィック量などの読みを外すと詰む • ビジネスロジックの多くはDBのストアドプロシージャに持たせていた ◦ 更新系のDBは垂直分割とスケールアップで対応 ▪ 結果SQL Serverのレプリケーションや分散トランザクションに強く依存 ◦ システムとしての結合度は高く1つのDB障害がサイト全域に波及する 開発生産性に課題あり • 本番環境と開発環境のスペックに大きな差がある • 本番環境と開発環境でコード差分がある、それを検知できる仕組みがない • リリースの準備の労力(ファイルベースでリリースするため手順を検討する) • レガシー言語故の学習コストの高さ、採用でも経験者が逆に少ない状態に 更なる事業成長のため、インフラ・アプリケーションを刷新する 「ZOZOTOWNリプレイスプロジェクト」が2017年より始動
  6. © ZOZO, Inc. 9 ZOZOTOWNリプレイスについて • 2017〜2022 WEB (Browser) API

    (APP) 更新系DB 参照系DB DataCenter Browser APP AWS EKS API Gateway 商品 基盤 検索 基盤 カート 基盤 ID 基盤 BFF Session 基盤 • 全てのAPI宛の通信を集約するAPI Gatewayを自社開発 ◦ ストラングラーパターンによる段階的移行 • 主要機能、クリティカルな機能のバックエンドから徐々にマイクロサービス化を進行 リプレイスプロジェクトにより ZOZOTOWNプラットフォーム基盤誕生
  7. © ZOZO, Inc. 10 ZOZOTOWNリプレイスについて • 2024(現在)のZOZOTOWN WEB (Browser) API

    (APP) 更新系DB 参照系DB DataCenter Browser APP AWS EKS API Gateway 商品 基盤 検索 基盤 カート 基盤 ID 基盤 BFF 注文 基盤 Session 基盤 会員 基盤 WEB Front WEB Gateway • 2023年頃からは本格的にフロントエンドリプレイスも進行中 ◦ Browserからのトラフィックの振り分けは利用中のCDNで実施 • 徐々にリプレイスプロジェクトの終着点が見えてきている段階
  8. © ZOZO, Inc. • クラウド ◦ AWS(*別基盤<ML等>はGCP) 11 ZOZOTOWNリプレイスについて •

    プラットフォーム基盤の主要技術スタック • コンテナオーケストレーションツール ◦ Kubernetes(Amazon EKS) ▪ サービスメッシュ:Istio ▪ Progressive Delivery:Flagger ▪ Deploy:Flux • Continuas Integration ◦ GitHub Actions • アプリケーション言語 ◦ Backend:Go、Java ◦ Frontend:Node.js • データストア ◦ MySQL(Aurora) ◦ DynamoDB ◦ Redis • Observability ◦ Datadog ◦ Splunk リプレイスが進みシステムの安定稼働率は大幅Up、また開発者の生産性向上に繋がった
  9. © ZOZO, Inc. 13 金銭面でのバランスが崩れた理由 • リプレイスが進み安定稼働と開発体験の向上を得たが・・・ https://techblog.zozo.com/entry/zozotown-api-gateway-intro • 移行後期に差し掛かったZOZOTOWNのクラウドコストはそれなりの金額に

    • ただしマネージドサービスの恩恵なども十分に感じておりそれが一概に悪いとは言えない • 最大の問題点は、「何故そのコストがかかっているかを明確にできない状態だった」こと
  10. © ZOZO, Inc. 14 金銭面でのバランスが崩れた理由 • SREチームもマイクロサービスに合わせ細分化 Service A Service

    B EKS RDS A RDS B 1つのSREチームで運用 AWS Account : XXXXXXXXXXX • リプレイス初期は1つのSREチームでシステムを運用 • マイクロサービスの増加に伴いSRE組織も開発を加速するため機能毎に細分化 • 1つのAWSアカウントと共通K8sクラスターを複数チームで利用するマルチテナント状態に • 運用作業の簡素化などをはじめメリットは多数存在 Service A Service B EKS RDS A RDS B 複数のSREチームで運用 AWS Account : XXXXXXXXXXX Service C RDS C
  11. © ZOZO, Inc. 15 金銭面でのバランスが崩れた理由 • 2017年〜2020年 • 1つのSREチームでシステムを管理していた時代 •

    チーム内で何をしているか把握しやすい状況なためコストに対する共通認識も持ちやすい ◦ Ex:〜をリリースしたから、負荷試験を実施していたから、、、など • イレギュラーなコストが出た際に必ず自チーム内に要因がある
  12. © ZOZO, Inc. 16 金銭面でのバランスが崩れた理由 • 2021〜 • 複数チームでシステムを管理するようになり、コストを深掘りする機会が減った •

    自チームのことは分かるが他のチームが何をしているかまでは把握しきれない • 今自分たちが利用している環境が本当に最適化された状態なのか?まで意識を向けづらい ◦ 初期構築から自分でしていればその辺も調べるきっかけはある
  13. © ZOZO, Inc. 17 金銭面でのバランスが崩れた理由 • その結果、クラウドコスト管理にて負のスパイラルが発生 予実の乖離 原因の推測 (不完全)

    見込み修正報告 修正後見込みと 実績の乖離 • 予算としては複数チームまとめて1つで(部として)管理を行っていた • 度重なるコスト予測と実績のズレ(しかも上振れ)、透明感のない状況に • クラウド環境を使ったリプレイス自体が悪手と経営層に捉えられかねないリスク • 改めてコスト最適化に向き合わなければいけないフェーズへ突入した ♾ 不信感誕生 のリスク 経営層
  14. © ZOZO, Inc. 20 コスト可視化に向けた取り組み • AWS CostExplorerでユーザー定義のコスト配分タグを活用 • AWSのコストを可視化し、分析するためのツール

    • デフォルトのディメンションでは同サービスを利用している場合に解析が困難だった • コスト配分タグを活用することでタグのValue毎にグループ化・フィルタリングが可能 • タグ付与後、請求ページ>コスト配分タグから有効化するだけで利用可能 • マルチAWSアカウント環境ではOrganizationsの管理アカウントで作業の必要あり Key Value CostEnv 稼働する環境(Ex:prd、stg) CostService マイクロサービス名 CostTeam 対象サービスの管轄チーム 実際に利用しているユーザー定義のコスト配分タグ
  15. © ZOZO, Inc. 23 コスト可視化に向けた取り組み • Kubernetes環境のコスト可視化における課題 • 課金要素の中でも大きな割合を占めていたのはマイクロサービス基盤となるEKS •

    運用負荷軽減の目的などから各チームで共通のNodeGroupを利用していた • コスト配分タグだけでは越えられない壁となり分析が難航していた コスト配分タグだけでは越えられない壁
  16. © ZOZO, Inc. 24 コスト可視化に向けた取り組み • Kubecostの活用 • Kubernetesクラスタ内のリソース利用とコストを管理するためのツール •

    Namespace単位でコストが可視化できればより各チーム分析がしやすくなる • KubecostはEKS上での利用に最適化されたカスタムバンドルも提供 • データの閲覧期間がカスタムバンドル版・無料版では15日 • 長期間でデータを見たい場合も往々にして存在するため有料版を使うべきか? (https://www.kubecost.com/)
  17. © ZOZO, Inc. 25 コスト可視化に向けた取り組み • カスタムバンドル版でも長期間データを閲覧できる仕組みを採用 • GitHub ActionsからKubecostのAPIをCallして日次データを取得

    • レスポンスされたデータをcsv形式でAmazon S3に保存 • 既に社内で利用中のSplunkと連携しデータを取り込み、ダッシュボードで可視化
  18. © ZOZO, Inc. 26 コスト可視化に向けた取り組み • Kubernetes環境のコストが日次単位で分析可能に • Splunkを活用することで保存期間を任意に設定することが可能に •

    日次単位ではあるものの環境毎やNamespace内の内訳を確認できる形に • 共通のNodeGroupを利用しているが故に不透明だったK8s内のコストを可視化できた ドリルダウンで選択したNamespaceの環境、内訳を確認
  19. © ZOZO, Inc. 27 コスト可視化に向けた取り組み • コストの可視化を進めた効果 ◦ 各チームが同じ基準でコストを見れる状態が整った ◦

    自チームのコストに絞って確認することが可能なため振り返りの場を設けやすい ▪ その結果予算策定・見込みなどの精度が上がった ◦ コスト施策として実施したことの効果を可視化できる状態になった ▪ コスト最適化に対するモチベーションが上がった! ここからは実際にコスト最適化として取り組んできた内容を紹介します
  20. © ZOZO, Inc. 株式会社ZOZO EC基盤開発本部 SRE部 プラットフォームSREブロック ブロック長 亀井 宏幸

    2017年株式会社スタートトゥデイ(現ZOZO)入社 ZOZOTOWNオンプレのインフラから始まり、リプレイ スには立ち上げ期より参画 現在はECプラットフォームの共通基盤を管理するSRE 趣味は犬を愛でること 28
  21. © ZOZO, Inc. 33 VPCの外部通信最適化 • GitHubへの通信はFlux Image Update Automations(以下IUA)を使った

    マイクロサービスPodのイメージ自動更新の仕組み • Gitリポジトリを定期的にクローンするがモノレポなので通信量が多い状態
  22. © ZOZO, Inc. 34 • IUAではクローンやコミットの動作を「ImageUpdateAutomation」カスタムリソースで定義する • 1分おきにサイズが大きいモノレポがフルクローンされていた ◦ 弊社のリポジトリ戦略では、checkout・pushブランチが別

    ◦ 現状のIUAではフルクローンとなってしまう VPCの外部通信最適化 apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImageUpdateAutomation metadata: name: service spec: interval: 1m sourceRef: kind: GitRepository name: <repository-name> namespace: flux-system git: checkout: ref: branch: <source-branch> commit: author: email: <github-user-email> name: <github-user-name> push: branch: <target-branch> update: path: <target-manifest-path> strategy: Setters 1分おきに リポジトリがフルクローン される動きになっていた checkout branchとpush branch が別ブランチ
  23. © ZOZO, Inc. 35 VPCの外部通信最適化 • 「ImageUpdateAutomation」のintervalの頻度を必要最低限に見直し通信量を最適化した apiVersion: image.toolkit.fluxcd.io/v1beta2 kind:

    ImageUpdateAutomation metadata: name: service spec: interval: 10m sourceRef: kind: GitRepository name: <repository-name> namespace: flux-system git: checkout: ref: branch: <source-branch> commit: author: email: <github-user-email> name: <github-user-name> push: branch: <target-branch> update: path: <target-manifest-path> strategy: Setters 必要最低限に変更
  24. © ZOZO, Inc. 36 VPCの外部通信最適化 • DatadogはPrivateLinkを提供しているため、PrivateLinkを構成し VPCエンドポイントを通す形に変更 • しかし、弊社の構成だとap-northeast-1のEKSから、us-east-1のDatadogサイトへ、

    VPC Peeringを行いつつ経路を構築する必要があった • NAT Gatewayの通信量削減とVPC Peeringの通信量増加でコストはトータル変わらない結果に
  25. © ZOZO, Inc. 39 EKSアーキテクチャの最適化 • ノードオートスケーラーのKarpenter移行 • Karpenterとは? ◦

    Cluster Autoscaler(CA)のプロビジョニング機能をクラウドネイティブに見直したOSS ◦ AWSにおいて、Cluster AutoscalerはEC2 Auto Scaling groupを介してノードをスケール するが、KarpenterはEC2を直接操作しスケールする ◦ より高機能で柔軟なノードのスケールが実現可能 ref. https://karpenter.sh/
  26. © ZOZO, Inc. 40 EKSアーキテクチャの最適化 • 問題解消のため合わせてPodの配置計画を大幅に見直し ◦ API Podの相乗りを許容

    ▪ 最低限同一サービスPodは同じノードに乗らないよう定義 ◦ NodePool(Karpenterのノードグループ単位)をテナント単位にし、影響範囲を限定 • 下記がDeploymentのspec.template.spec.affinity spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: run operator: In values: - <APIユニークなラベル> topologyKey: kubernetes.io/hostname nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: karpenter.sh/nodepool operator: In values: - <テナント名> NodePool をテナント単位に 同一サービスPodは 同じノードに乗らない
  27. © ZOZO, Inc. 43 開発環境の運用最適化 • KEDAを使い必要な時間のみ稼働するようスケジュールスケール • KEDAとは? ◦

    イベント駆動型のオートスケーラーで、Podの水平スケールを実現するOSS ◦ Horizontal Pod Autoscaler(HPA)より柔軟なスケールが可能で、外部メトリクスや Cronスケジュールでのスケールやゼロスケール(Pod数を0にする)が可能 ref. https://keda.sh/docs/latest/concepts/#architecture
  28. © ZOZO, Inc. 45 開発環境の運用最適化 • 停止期間でも必要な時に開発者やSREが柔軟に起動・停止できるツールを開発 • 詳細はいずれテックブログにて公開予定! apiVersion:

    keda.sh/v1alpha1 kind: ScaledObject metadata: name: service spec: scaleTargetRef: name: service-deployment maxReplicaCount: 2 minReplicaCount: 0 -> 1 (起動) triggers: - type: cpu metricType: Utilization metadata: value: "70" - type: cron metadata: timezone: Asia/Tokyo start: 0 7 * * 1-5 end: 0 0 * * 2-6 desiredReplicas: "1"
  29. © ZOZO, Inc. 48 まとめ • クラウドサービスは簡単・便利だがコストに注意すべし ◦ 可視化や日々の最適化を意識しないと「なんかわからないけど高い」状態となってしまう •

    コストの可視化をすべし ◦ AWSはCost配分タグ、KubernetesはKubecostなどを導入することで可視化 ◦ マルチテナント環境ではテナント単位での可視化 • 金食い虫を見つけ最適化すべし ◦ 可視化されたデータを元に各技術スタックで最適化の取り組みを行い、 インフラコストの健全化を行う ◦ ベストプラクティスと言われるものは臆病にならず積極的に • それらを継続し納得感のあるインフラを運用しよう