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

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

Satto
March 22, 2023

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

Satto

March 22, 2023
Tweet

Other Decks in Technology

Transcript

  1. Spring Boot+Redis Cache
    検索APIにキャッシュを導入、実装時の工夫や効果
    2022年3月23日 ZOZO Tech Meetup
    株式会社ZOZO
    技術本部 検索基盤部 検索基盤ブロック
    佐藤 由弥
    Copyright © ZOZO, Inc.
    1

    View Slide

  2. © ZOZO, Inc.
    株式会社ZOZO
    技術本部 検索基盤部 検索基盤ブロック
    佐藤 由弥
    ● 2020年4月新卒として入社(今年4月で4年目)
    ● 入社当時はJava未経験
    ○ 検索マイクロサービスの開発や運用業務を通じて習得
    ● 最近の主な業務は検索ページのフロントエンドリプレイス
    ○ レガシーコードをJavaに置き換え
    ● 扱う言語やサービス:Java・Python・VBS・Elasticsearch・BigQuery
    ● 趣味:ゲーム、最近はホグワーツに入学
    2

    View Slide

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

    View Slide

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

    View Slide

  5. © ZOZO, Inc.
    5
    突然ですが!

    View Slide

  6. © ZOZO, Inc.
    6
    ZOZOTOWNの検索と聞いて何を思い浮かべますか?

    View Slide

  7. © ZOZO, Inc.
    以下を思い浮かべた方、正解です!
    7
    ZOZOTOWNの検索について
    世代別ランキング 類似画像検索
    サジェスト パーソナライズ化された商品の並び順
    これ以外にも沢山あるよ
    検索フォーム

    View Slide

  8. © ZOZO, Inc.
    8
    ZOZOTOWNの検索を支えるシステム構成
    ● 検索API:Elasticsearchから商品情報を受け取り、ZOZOTOWNへ検索機能を提供
    ● インデクシングバッチ:DBからElasticsearchへ商品情報を定期的に同期するバッチ

    View Slide

  9. © ZOZO, Inc.
    検索システムとして大切な要素
    9
    今日話すこと
    ● 速度
    ● 精度
    ● 可用性
    ● 再現性などなど

    View Slide

  10. © ZOZO, Inc.
    検索システムとして大切な要素
    10
    今日話すこと
    ● 速度
    ○ 検索APIにキャッシュ導入
    ● 精度
    ● 可用性
    ● 再現性などなど
    本資料ではここを深掘る

    View Slide

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

    View Slide

  12. © ZOZO, Inc.
    12
    キャッシュ導入に至った背景

    View Slide

  13. © ZOZO, Inc.
    13
    検索APIにキャッシュを導入した背景、その1
    マイクロサービス化に伴い検索APIの直接参照の機会が増加、負荷面に懸念が出てきた

    View Slide

  14. © ZOZO, Inc.
    14
    検索APIにキャッシュを導入した背景、その2
    検索APIのABテスト実施にあたりWebサイト側の修正も必要、改善サイクルが回りづらい

    View Slide

  15. © ZOZO, Inc.
    15
    キャッシュ導入のシステム全体像

    View Slide

  16. © ZOZO, Inc.
    16
    ZOZOTOWNの検索を支えるシステム構成(キャッシュ導入後)
    Amazon ElastiCache for Redisを追加
    キャッシュのやり取りはJavaで実装

    View Slide

  17. © ZOZO, Inc.
    17
    キャッシュ導入による効果

    View Slide

  18. © ZOZO, Inc.
    18
    ZOZOTOWNの検索を支えるシステム構成(キャッシュ導入後)
    Elasticsearchを経由せず、高速に検索結果を返却可能

    View Slide

  19. © ZOZO, Inc.
    19
    キャッシュ導入による効果(工夫を含めた最終的な効果)
    ● 速度改善に効果あり
    ○ 最終的に殆どのエンドポイントで
    50ms~100msほどレイテンシが低下
    ○ 特に効果があったエンドポイントはp99で94%改善
    ● 安定した速度で検索結果の提供が可能に
    ○ レイテンシの振れ幅が少なくなり安定した 例)世代別ランキングAPIのレイテンシの様子
    ※ この後紹介する様々な工夫を取り入れた後の
    最終的なレイテンシの低下を表しています
    90%以上改善

    View Slide

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

    View Slide

  21. © ZOZO, Inc.
    21
    実装時の工夫
    ● エンドポイントごとにTTLを最適化
    ○ エンドポイントごとにTTLを延長してレイテンシを計測
    ○ 最適な値になるまで上記を繰り返す
    ● キャッシュキーの最適化
    ○ セールの開始時にキャッシュが切り替わるように
    キャッシュキーにタイムセクションを追加
    ○ Cache Stampedeの対策
    ● キャッシュのGZIP圧縮
    ○ 検索結果をそのままキャッシュすると
    ネットワークI/Oやストレージが逼迫
    ここを深掘る
    リンク:https://techblog.zozo.com/entry/implement-cache-in-search-microservice
    割愛:詳細はテックブログ参照ください

    View Slide

  22. © ZOZO, Inc.
    22
    キャッシュのGZIP圧縮の概要
    ● どんな課題があった?
    ○ 登録するキャッシュは、商品の様々な情報を含むためデータサイズが大きい
    ○ RedisのネットワークI/Oやストレージの使用量が増加
    ● なにが嬉しい?
    ○ Redisに保存するデータを圧縮することで、
    ネットワークI/Oやストレージの使用量を減らし、検索APIの高速化を図る
    ● この後の話
    ○ 実際のJavaのコードを交えて、どのようにGZIP圧縮したか詳細を説明

    View Slide

  23. © 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/

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. © ZOZO, Inc.
    30
    キャッシュのGZIP圧縮
    ● spring-boot-starter-data-redis
    ○ RedisTemplateが用意されている
    ○ Redisとのデータ操作が簡略化
    ● RedisTemplate
    ○ デフォルトシリアライザーの
    JdkSerializationRedisSerializerをラップ
    したクラスに差し替える
    Redisを扱うための依存関係
    RedisTemplateにてラップしたクラスに差し替える
    元のRedisTemplate
    ※ テンプレートが異なる場合、適宜差し替え場所を変える

    View Slide

  31. © ZOZO, Inc.
    31
    キャッシュ圧縮による効果
    ● ElastiCacheメモリ使用率が約1/3に減少
    ● ネットワーク通信量が約1/7に減少
    懸念していたCPU使用率は変化なし
    ○ 約200KBの文字列で構成されたレスポンス情報の圧縮なので
    サイズが小さく負荷がかからなかった
    ○ リソースが十分に与えられたPod上で実行されているため
    影響が少なかった
    キャッシュ圧縮によって、以下の効果が得られた
    ElastiCacheメモリ使用率 ネットワーク通信量
    CPU使用率
    約1/3減少 約1/7減少

    View Slide

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

    View Slide

  33. © ZOZO, Inc.
    33
    まとめ/学んだこと
    まとめ
    ● 速度改善の一環で検索APIにキャッシュを導入
    ● 殆どのエンドポイントで50~100msほどレイテンシが低下
    ● GZIPによるキャッシュ圧縮/解凍の実装方法を紹介
    ● ストレージやネットワーク使用量が低下
    学んだこと
    ● Java完全理解
    ○ ほぼ未経験でしたが、実装をある程度任せてもらえたので理解が深まった
    ● レイテンシをより意識するように
    ● 闇雲な改善は良くない
    ○ 計測→仮説→実装の流れが大切

    View Slide

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

    View Slide

  35. © ZOZO, Inc.
    35
    おまけ(フロントエンドリプレイスの話)
    これまでのZOZOTOWNの課題
    ● Webサーバの技術スタックがレガシー
    ○ Classic ASP・jQuery・ES5
    ○ 他言語でよくある便利機能は自作が必要で開発速度が鈍化
    ● ビューロジックが独自テンプレートエンジンで実現
    ○ コードが独特で癖があり実装コストが高い
    ○ ビューとAPI側にビジネスロジックが分散
    リプレイス後のZOZOTOWN
    ※ 説明のため簡略化しています

    View Slide

  36. © ZOZO, Inc.
    36
    最後に
    「検索のバックエンドに興味ある方」や「リプレイスに興味ある方」を募集しています
    カジュアル面談もあるので気軽にどうぞ!
    求人ページ:https://hrmos.co/pages/zozo/jobs/0000034

    View Slide