Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ZOZOTOWNの検索APIにキャッシュを導入、実装時の工夫や効果について

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Satto Satto
March 22, 2023

 ZOZOTOWNの検索APIにキャッシュを導入、実装時の工夫や効果について

Avatar for Satto

Satto

March 22, 2023
Tweet

Other Decks in Technology

Transcript

  1. © ZOZO, Inc. 株式会社ZOZO 技術本部 検索基盤部 検索基盤ブロック 佐藤 由弥 •

    2020年4月新卒として入社(今年4月で4年目) • 入社当時はJava未経験 ◦ 検索マイクロサービスの開発や運用業務を通じて習得 • 最近の主な業務は検索ページのフロントエンドリプレイス ◦ レガシーコードをJavaに置き換え • 扱う言語やサービス:Java・Python・VBS・Elasticsearch・BigQuery • 趣味:ゲーム、最近はホグワーツに入学 2
  2. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 3
  3. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 4
  4. © ZOZO, Inc. 検索システムとして大切な要素 10 今日話すこと • 速度 ◦ 検索APIにキャッシュ導入

    • 精度 • 可用性 • 再現性などなど 本資料ではここを深掘る
  5. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 11
  6. © ZOZO, Inc. 19 キャッシュ導入による効果(工夫を含めた最終的な効果) • 速度改善に効果あり ◦ 最終的に殆どのエンドポイントで 50ms~100msほどレイテンシが低下

    ◦ 特に効果があったエンドポイントはp99で94%改善 • 安定した速度で検索結果の提供が可能に ◦ レイテンシの振れ幅が少なくなり安定した 例)世代別ランキングAPIのレイテンシの様子 ※ この後紹介する様々な工夫を取り入れた後の 最終的なレイテンシの低下を表しています 90%以上改善
  7. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 20
  8. © ZOZO, Inc. 21 実装時の工夫 • エンドポイントごとにTTLを最適化 ◦ エンドポイントごとにTTLを延長してレイテンシを計測 ◦

    最適な値になるまで上記を繰り返す • キャッシュキーの最適化 ◦ セールの開始時にキャッシュが切り替わるように キャッシュキーにタイムセクションを追加 ◦ Cache Stampedeの対策 • キャッシュのGZIP圧縮 ◦ 検索結果をそのままキャッシュすると ネットワークI/Oやストレージが逼迫 ここを深掘る リンク:https://techblog.zozo.com/entry/implement-cache-in-search-microservice 割愛:詳細はテックブログ参照ください
  9. © ZOZO, Inc. 22 キャッシュのGZIP圧縮の概要 • どんな課題があった? ◦ 登録するキャッシュは、商品の様々な情報を含むためデータサイズが大きい ◦

    RedisのネットワークI/Oやストレージの使用量が増加 • なにが嬉しい? ◦ Redisに保存するデータを圧縮することで、 ネットワークI/Oやストレージの使用量を減らし、検索APIの高速化を図る • この後の話 ◦ 実際のJavaのコードを交えて、どのようにGZIP圧縮したか詳細を説明
  10. © ZOZO, Inc. 23 Spring bootからRedisにキャッシュを保存するまでの流れ Redisはインメモリデータストアのため、オブジェクトをデータ形式に変換して保存が必要 扱うRedisクライアント:spring-boot-starter-data-redis https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data- redis

    • シリアライズ/デシアライズは JdkSerializationRedisSerializerクラスで行われる • オブジェクトのシリアライズを可能にするには 追加する Redisクライアント Redis シリアライズ 検索結果オブジェクト バイト配列 キャッシュ保存 デシリアライズ キャッシュ読み取り バイト配列 検索結果オブジェクト 同 じ 検索API Icon made by flaticon from https://www.flaticon.com/
  11. © ZOZO, Inc. 24 キャッシュのGZIP圧縮 シリアライズ gzip 圧縮 約60%~80%圧縮 GZIP圧縮の流れ

    • serialize() ◦ オブジェクトをシリアライズするメソッド ◦ isGzipEnabledでGZIP実行有無を制御 • compress() ◦ バイト配列をGZIP圧縮するメソッド ◦ GZIPOutputStreamにByteArrayOutputStreamを 渡すことで出力先はバイト配列になる 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  12. © ZOZO, Inc. 25 キャッシュのGZIP圧縮 シリアライズ gzip 圧縮 約60%~80%圧縮 GZIP圧縮の流れ

    • serialize() ◦ オブジェクトをシリアライズするメソッド ◦ isGzipEnabledでGZIP実行有無を制御 • compress() ◦ バイト配列をGZIP圧縮するメソッド ◦ GZIPOutputStreamにByteArrayOutputStreamを 渡すことで出力先はバイト配列になる 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  13. © ZOZO, Inc. 26 キャッシュのGZIP圧縮 シリアライズ gzip 圧縮 約60%~80%圧縮 GZIP圧縮の流れ

    • serialize() ◦ オブジェクトをシリアライズするメソッド ◦ isGzipEnabledでGZIP実行有無を制御 • compress() ◦ バイト配列をGZIP圧縮するメソッド ◦ GZIPOutputStreamにByteArrayOutputStreamを 渡すことで出力先はバイト配列になる 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  14. © ZOZO, Inc. 27 キャッシュのGZIP圧縮 GZIP解凍の流れ gzip 解凍 デシリアライズ •

    deserialize() ◦ Redisから取得した圧縮データを復元するためのメソッド ◦ バイト配列からオブジェクトに変換 • decompress() ◦ 圧縮されたバイト配列を解凍するメソッド ◦ データの解凍と解凍されたデータをバイト配列に書き込む ◦ 一連の流れは煩雑化しやすいので IOUtilsクラスのcopyメソッドを使い簡略化 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  15. © ZOZO, Inc. 28 キャッシュのGZIP圧縮 GZIP解凍の流れ gzip 解凍 デシリアライズ •

    deserialize() ◦ Redisから取得した圧縮データを復元するためのメソッド ◦ バイト配列からオブジェクトに変換 • decompress() ◦ 圧縮されたバイト配列を解凍するメソッド ◦ データの解凍と解凍されたデータをバイト配列に書き込む ◦ 一連の流れは煩雑化しやすいので IOUtilsクラスのcopyメソッドを使い簡略化 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  16. © ZOZO, Inc. 29 キャッシュのGZIP圧縮 GZIP解凍の流れ gzip 解凍 デシリアライズ •

    deserialize() ◦ Redisから取得した圧縮データを復元するためのメソッド ◦ バイト配列からオブジェクトに変換 • decompress() ◦ 圧縮されたバイト配列を解凍するメソッド ◦ データの解凍と解凍されたデータをバイト配列に書き込む ◦ 一連の流れは煩雑化しやすいので IOUtilsクラスのcopyメソッドを使い簡略化 検索結果オブジェクト バイト配列 圧縮されたバイト配列 Icon made by flaticon from https://www.flaticon.com/
  17. © ZOZO, Inc. 30 キャッシュのGZIP圧縮 • spring-boot-starter-data-redis ◦ RedisTemplateが用意されている ◦

    Redisとのデータ操作が簡略化 • RedisTemplate ◦ デフォルトシリアライザーの JdkSerializationRedisSerializerをラップ したクラスに差し替える Redisを扱うための依存関係 RedisTemplateにてラップしたクラスに差し替える 元のRedisTemplate ※ テンプレートが異なる場合、適宜差し替え場所を変える
  18. © ZOZO, Inc. 31 キャッシュ圧縮による効果 • ElastiCacheメモリ使用率が約1/3に減少 • ネットワーク通信量が約1/7に減少 懸念していたCPU使用率は変化なし

    ◦ 約200KBの文字列で構成されたレスポンス情報の圧縮なので サイズが小さく負荷がかからなかった ◦ リソースが十分に与えられたPod上で実行されているため 影響が少なかった キャッシュ圧縮によって、以下の効果が得られた ElastiCacheメモリ使用率 ネットワーク通信量 CPU使用率 約1/3減少 約1/7減少
  19. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 32
  20. © ZOZO, Inc. 33 まとめ/学んだこと まとめ • 速度改善の一環で検索APIにキャッシュを導入 • 殆どのエンドポイントで50~100msほどレイテンシが低下

    • GZIPによるキャッシュ圧縮/解凍の実装方法を紹介 • ストレージやネットワーク使用量が低下 学んだこと • Java完全理解 ◦ ほぼ未経験でしたが、実装をある程度任せてもらえたので理解が深まった • レイテンシをより意識するように • 闇雲な改善は良くない ◦ 計測→仮説→実装の流れが大切
  21. © ZOZO, Inc. Agenda 1. ZOZOTOWNの検索について 2. キャッシュの導入 3. 実装時の工夫

    4. まとめ 5. おまけ(フロントエンドリプレイスの話) 34
  22. © ZOZO, Inc. 35 おまけ(フロントエンドリプレイスの話) これまでのZOZOTOWNの課題 • Webサーバの技術スタックがレガシー ◦ Classic

    ASP・jQuery・ES5 ◦ 他言語でよくある便利機能は自作が必要で開発速度が鈍化 • ビューロジックが独自テンプレートエンジンで実現 ◦ コードが独特で癖があり実装コストが高い ◦ ビューとAPI側にビジネスロジックが分散 リプレイス後のZOZOTOWN ※ 説明のため簡略化しています