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

DynamoDB RCU Tunning

Quang Hoàng
July 18, 2024
36

DynamoDB RCU Tunning

Quang Hoàng

July 18, 2024
Tweet

Transcript

  1. HOANG MINH QUANG (クアン) •Joined CyberAgent / Hanoi DevCenter in

    2023/08 •アプ運用カンパニー / 大福山チーム Backend Engineer •Ramen / RDBMS / Go / Design •パフォーマンスチューニング About me @minhquang4334 @Quang4334 #times-hanoi-devcenter ref ref
  2. DynamoDBのRCUとは • 「1RCUで4KBの項目を1秒当たり結果整合性なら 2個を読み込める」 一個は1 Item(レコード)である → 1RCUはMAX 2 Items

    読み込める 読み込めるデータはQueryのレスポンスのデータじゃなくて、スキャンされたデータになる もしfull スキャンになってしまうと、全量データのサイズ・数で計算されてしまう
  3. RCUを減らす、基本的な考え方 1RCUで4KBの項目を1秒当たり結果整合性なら 2個のアイテムを読み込める RCU = f(num_read_requests, total_scan_item_size_per_request) Minimize num_read_requests Minimize

    total_scan_item_size_per_request num_read_requests: DynamoDBのテーブルに読み取りリクエストの数 total_scan_item_size_per_request: 一回の読み取りリクエストでスキャンされるデータ容量
  4. 今の設計の構成 Aurora MySQL DynamoDB Primary Key id is_public is_targeting begin_at

    end_at CampaignMasterTable Partition Key user_id Sort Key campaign_id created_at updated_at TargetingUserCampaignTable データは異なるデータストアに保 存されている
  5. 現状の実装 公開中のキャンペーン一 覧を取得する Aurora MySQL DynamoDB ユーザーにターゲティン グされているユーザーを 絞る ※

    公開中かどうかの情報はAuroraにあり どのユーザーにターゲティングされているか DynamoDBにあるので両方見る必要 課題:あるユーザーに公開中ターゲッティングされているキャンペーン一 (aka Campaign) 覧を取得したい
  6. 現状の実装 公開中のキャンペーン一 覧を取得する SELECT id as public_campaign_ids FROM CampaignMasterTable WHERE

    …… Aurora MySQL DynamoDB ユーザーにターゲティン グされているユーザーを 絞る
  7. 現状の実装 DynamoDBで絞って、 結果返す SELECT campaign_id FROM TargetingUserCampaignTable WHERE CampaignID IN

    (${public_campaign_ids}) AND userId = ? 公開中のキャンペーン一 覧を取得する SELECT id as public_campaign_ids FROM CampaignMasterTable WHERE …… Aurora MySQL DynamoDB ユーザーにターゲティン グされているユーザーを 絞る
  8. 現状の実装 どうやってこのクエリをDynamoDBに叩けるか SELECT campaign_id FROM TargetingUserCampaignTable WHERE CampaignID IN (${public_campaign_ids})

    AND userId = ? 公開中のキャンペーン一 覧を取得する SELECT id as public_campaign_ids FROM CampaignMasterTable WHERE …… Aurora MySQL DynamoDB ユーザーにターゲティン グされているユーザーを 絞る
  9. PartiQLを使用している • a SQL-compatible query language for Amazon DynamoDB なので、複雑なクエリでもDynamoDBでいい感じに叩ける

    WHERE … IN, OR, BETWEEN, ><=><= などで • DB上でページネーション可能 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html
  10. PartiQLを並列化する PartiQLはWHERE INにあるplaceholdersの数の上限は 100であり、場合によっては50個で、 同時に公開中のキャンペーンが非常に多いため、分割して並列した。 SELECT campaign_id FROM TargetingUserCampaignTable WHERE

    CampaignID IN (${public_campaign_ids_1}) AND userId = ? DynamoDB ユーザーにターゲティン グされているユーザーを 絞る SELECT campaign_id FROM TargetingUserCampaignTable WHERE CampaignID IN (${public_campaign_ids_2}) AND userId = ? SELECT campaign_id FROM TargetingUserCampaignTable WHERE CampaignID IN (${public_campaign_ids_n}) AND userId = ? …… public_campaign_ids = (public_campaign_ids_1, public_campaign_ids_2, .. ,public_campaign_ids_n)
  11. どんどんシステム品質が悪化された • 対象のテーブルの RCU = 5000/s 以上で高い • たまに throttling

    error 発生、サービス不安定 • DynamoDBのコストが高い • APIやシステム全体に P90 Latency が遅い (〜150ms)
  12. 改善策 DynamoDBで結果絞るのではなく、 OnMemoryやる方針にしました DynamoDBで結果絞る SELECT campaign_id FROM TargetingUserCampaignTable WHERE CampaignID

    IN (${public_campaign_ids}) AND userId = ? 公開中のキャンペーン一 覧を取得する SELECT id as public_campaign_ids FROM CampaignMasterTable WHERE …… Aurora MySQL DynamoDB ユーザーにターゲティン グされているユーザーを 絞る 改善前
  13. 改善策 DynamoDBで結果絞るのではなく、 OnMemoryやる方針にしました 公開中のキャンペーン一 覧を取得する Aurora MySQL DynamoDB ユーザーの全ターゲティ ングキャンペーン取得す

    る 公開中かどうか関わらず それぞれ実行して、On MemoryでOverlap された データ(共通部分)を結果 にする 改善策 SELECT id as public_campaign_ids FROM CampaignMasterTable WHERE …… DynamoDB.GetItem by userID partition key つまり userIDのpartitionの全データをとる
  14. RCU最適 1RCUで4KBの項目を1秒当たり結果整合性なら 2個を読み込める RCU = f(num_read_requests, total_scan_item_size_per_request) Minimize num_read_requests Minimize

    total_scan_item_size_per_request 並列化をやめて、一回の Queryだけで行う Queryで必要なデータだけ読 み込める
  15. EOF