Slide 1

Slide 1 text

Copyright © RevComm Inc. 【供養】DynamoDBでも部分一致検索したかった 2024.03.15@Ya8 大谷紗良

Slide 2

Slide 2 text

Copyright © RevComm Inc. ● 大谷 紗良(Sara Ohtani) ● Software Engineer, Backend ○   ● RevComm Inc. ●   @sara_ohtani_mt2 ● #ya8 #ya8B 自己紹介 2

Slide 3

Slide 3 text

Copyright © RevComm Inc. 練馬で祭りを!? 😳 祭りやってるなぁと思って来ました 3

Slide 4

Slide 4 text

Copyright © RevComm Inc. awsのNoSQL DB、DynamoDBはスピードやコストの点で期待が高い でもなかなか利用シーンが限られているようで・・・ でもでもよく調べると色々できそうで・・・ でもでもでも試したらやはりちょっとできなかった、という話 今日の話 この資料は slide share公開済みです https://tech.revcomm.co.jp/partial-match-search-with-dynamodb 4

Slide 5

Slide 5 text

Copyright © RevComm Inc. DynamoDB使ったことあるひとー? 質問 5

Slide 6

Slide 6 text

Copyright © RevComm Inc. DynamoDBのGSI使ったことあるひとー? (GSI: グローバルセカンダリインデックス) 質問 6

Slide 7

Slide 7 text

Copyright © RevComm Inc. ● DynamoDBは気になるけど 実際に使ってサービス開発をしたことはない方 ● シンプルにKeyと一致するデータを取得したことはあるけど DynamoDBのさらなる可能性について知りたい方 想定聴講者 7

Slide 8

Slide 8 text

Copyright © RevComm Inc. 今日のみんなのGOAL DynamoDBで できそうなこと DynamoDBでできなさそうなこと 8

Slide 9

Slide 9 text

Copyright © RevComm Inc. 今日のみんなのGOAL DynamoDBでできないこと DynamoDBで できそうなこと DynamoDBで できること 9

Slide 10

Slide 10 text

Copyright © RevComm Inc. 1. 今回検証するにいたった背景 2. DynamoDBでできることできないこと 3. テーブルとデータ取得コードの例 4. まとめ アジェンダ 10

Slide 11

Slide 11 text

Copyright © RevComm Inc. 1. 今回検証するにいたった背景 2. DynamoDBでできることできないこと 3. テーブルとデータ取得コードの例 4. まとめ アジェンダ 11

Slide 12

Slide 12 text

Copyright © RevComm Inc. コミュニケーションを再発明し 人が人を想う社会を創る 12

Slide 13

Slide 13 text

Copyright © RevComm Inc. 電話営業や顧客応対を自動録音、AIが文字 起こし、解析・可視化することにより、顧 客と担当者が「何を」「どのように」話し ているか分からない、というブラックボッ クス問題を解消し、商談獲得率・成約率の 向上やセルフコーチングを後押しします。 Service トーク解析AI 13

Slide 14

Slide 14 text

Copyright © RevComm Inc. 連絡先情報を一覧で表示する画面があり キーワード検索する機能がある 電話機能があり、電話帳機能がある 14

Slide 15

Slide 15 text

Copyright © RevComm Inc. 連絡先情報を一覧で表示する画面があり キーワード検索する機能がある 電話機能があり、電話帳機能がある リニューアル中! 15

Slide 16

Slide 16 text

Copyright © RevComm Inc. データ量の多さとそれを起因とする遅さ ● 1テナントにつき最大50万件の連絡先 ※現在最大75万件 ● できれば1秒以下で取得したい 📞 🐢... 📇  リニューアルするにあたって意識している課題 16

Slide 17

Slide 17 text

Copyright © RevComm Inc. リニューアルにあたり、DBの分割も検討している このあたりの話は盛り上がりすぎてしまうので今日はしない とにかく検討しているんだ!!!!! そして何を使うか改めて考えている DB選定を改めてする 17

Slide 18

Slide 18 text

Copyright © RevComm Inc. 速い!安い!楽!(※) DynamoDBの魅力のイメージ 18

Slide 19

Slide 19 text

Copyright © RevComm Inc. データ規模にかかわらず処理速度が速いらしい 速い速いと聞くけど実感としてどの程度速いかわかってない これを機に知りたいという動機もあって検証してみた DynamoDBを使って早くならないものか・・・ 19

Slide 20

Slide 20 text

Copyright © RevComm Inc. 1. 今回検証するにいたった背景 2. DynamoDBでできることできないこと 3. テーブルとデータ取得コードの例 4. まとめ アジェンダ 20

Slide 21

Slide 21 text

Copyright © RevComm Inc. DynamoDBのデータ { "id": { "N": “1” }, "name": { "S": "John" }, "type": { "S": "dog" } } Partition Key Sort Key (※option) その他 Attributes id name 1 John type dog item 21

Slide 22

Slide 22 text

Copyright © RevComm Inc. Scan検索でなくQuery検索を使う ● Query検索は全体のデータ量にあまり影響を受けず速い ● しかしQuery検索は柔軟な検索ができない ● 余談 ○ Query検索で一度に取得できるデータは1MBまで ○ 一度で取得できなかったときには LastEvaluatedKeyに値が入ってくる 速さを活かすためには 22

Slide 23

Slide 23 text

Copyright © RevComm Inc. Scan検索でなくQuery検索を使う ● Query検索は全体のデータ量にあまり影響を受けず速い ● しかしQuery検索は柔軟な検索ができない ● 余談 ○ Query検索で一度に取得できるデータは1MBまで ○ 一度で取得できなかったときには LastEvaluatedKeyに値が入ってくる 速さを活かすためには 23

Slide 24

Slide 24 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索とは Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ item 24

Slide 25

Slide 25 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索 Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ item Query検索の場合、絞り込み条件として Partition Keyは必ず指定しなければならない 完全一致検索のみ 25

Slide 26

Slide 26 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索 Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ idわからないけどnameが Johnのデータが欲しいな 26

Slide 27

Slide 27 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索 Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ idわからないけどnameが Johnのデータが欲しいな 27

Slide 28

Slide 28 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索 Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ item Sort KeyはPKを指定した上であれば 「EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN」で絞り込める (Sort Keyの指定はオプション) 28

Slide 29

Slide 29 text

Copyright © RevComm Inc. Keyで絞り込んで該当itemが取得できる DynamoDBのQuery検索 Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ item KeyとKey以外はQuery検索で扱う上で 全く別物といっていい 29

Slide 30

Slide 30 text

Copyright © RevComm Inc. もっと柔軟に検索したい!!! 😵 でも・・・ 30

Slide 31

Slide 31 text

Copyright © RevComm Inc. そこで GSI じゃ 󰩂 テーブルに対して自由に追加できるインデックスを使うんじゃ 31

Slide 32

Slide 32 text

Copyright © RevComm Inc. 1item内にフラットに情報を並べるのではなく、 情報を縦に持つ GSIを活用する前提の設計の考え方 PK, GSI-SK Sort Key その他Attributes ID DataType 1 Name DataValue John ・・・ ・・・ ・・・ ・・・ ・・・ 1 Type dog ・・・ ・・・ GSI-PK Primary Table 32

Slide 33

Slide 33 text

Copyright © RevComm Inc. 1item内で横に情報を持つイメージ DynamoDBのQuery検索とは Partition Key Sort Key その他Attributes id name 1 John type dog ・・・ ・・・ ・・・ ・・・ ・・・ 2 Paul cat ・・・ ・・・ item 33

Slide 34

Slide 34 text

Copyright © RevComm Inc. 1item内にフラットに情報を並べるのではなく、 情報を縦に持つ GSIを活用する前提の設計の考え方 PK, GSI-SK Sort Key その他Attributes ID DataType 1 Name DataValue John ・・・ ・・・ ・・・ ・・・ ・・・ 1 Type dog ・・・ ・・・ GSI-PK Primary Table 34

Slide 35

Slide 35 text

Copyright © RevComm Inc. 1item内にフラットに情報を並べるのではなく、 情報を縦に持つ 使うとどうなる? GSI-PK GSI-SK Projected Attributes DataValue ID John 1 DataType Name ・・・ ・・・ ・・・ ・・・ ・・・ dog 1 Type ・・・ ・・・ (PK) dog 3 Type GSI Table 35

Slide 36

Slide 36 text

Copyright © RevComm Inc. Query検索の考え方は同じ 使うとどうなる? GSI-PK GSI-SK Projected Attributes DataValue ID John 1 DataType Name ・・・ ・・・ ・・・ ・・・ ・・・ dog 1 Type ・・・ ・・・ (PK) dog 3 Type GSI Table idわからないけどnameが Johnのデータが欲しいな ⭕ 36

Slide 37

Slide 37 text

Copyright © RevComm Inc. Query検索の考え方は同じ 使うとどうなる? GSI-PK GSI-SK Projected Attributes DataValue ID John 1 DataType Name ・・・ ・・・ ・・・ ・・・ ・・・ dog 1 Type ・・・ ・・・ (PK) dog 3 Type GSI Table dogのデータ・・・⭕ 37

Slide 38

Slide 38 text

Copyright © RevComm Inc. 50万件の連絡先を縦に展開してみたら サンプルデータは2000万件ほどに 😇 縦に持つということはデータ量はさらに増える・・・ 38

Slide 39

Slide 39 text

Copyright © RevComm Inc. それでも1秒未満で検索できた!※ 🚀 爆速 39

Slide 40

Slide 40 text

Copyright © RevComm Inc. Primary TableのPK以外での検索はできた でもKeyの検索だと部分一致検索ができない😢 where name like ‘%hoge%’ … 40

Slide 41

Slide 41 text

Copyright © RevComm Inc. それはそう でも部分一致検索したい 完全一致か 前方一致じゃ だめですよね? 😉 PO: それはちょっと・・・ 😉 41

Slide 42

Slide 42 text

Copyright © RevComm Inc. DynamoDBで部分一致検索はできないのか? 42

Slide 43

Slide 43 text

Copyright © RevComm Inc. Key検索+α ならできそう? なんかできそう・・・? https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.FilterExpression.html 43

Slide 44

Slide 44 text

Copyright © RevComm Inc. Key検索+α ならできそう? なんかできそう・・・? https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.FilterExpression.html できるけどScan同様、 データ量に応じて遅くなることがわかった 44

Slide 45

Slide 45 text

Copyright © RevComm Inc. フィルター条件を指定するとデータ量に応じて遅くなる 実質Scan 45

Slide 46

Slide 46 text

Copyright © RevComm Inc. 残念ながら要件を満たせなかったので 今回はDynamoDB採用を見送りました でも良いシチュエーションがあったら全然使いたい 結果としては 46

Slide 47

Slide 47 text

Copyright © RevComm Inc. どんなシチュエーションならよかったか? 47

Slide 48

Slide 48 text

Copyright © RevComm Inc. 1. データ抽出条件が完全一致、あるいは前方一致で良い 2. データ件数が多く、今後もさらに増加が予想される 3. アクセスパターンや要件がはっきりしている 4. データ検索する際の絞り込み条件となる項目が多くない 5. 基本的にテーブルをjoinする必要がない 6. 並び順は問わない DynamoDBがマッチすると思われるユースケース 48

Slide 49

Slide 49 text

Copyright © RevComm Inc. これらの条件と一致するサンプルケースで設計してみる 49

Slide 50

Slide 50 text

Copyright © RevComm Inc. ここで甘い飲み物を飲みます 50

Slide 51

Slide 51 text

Copyright © RevComm Inc. 後半!🛎 51

Slide 52

Slide 52 text

Copyright © RevComm Inc. 1. 今回検証するにいたった背景 2. DynamoDBでできることできないこと 3. テーブルとデータ取得コードの例 4. まとめ アジェンダ 52

Slide 53

Slide 53 text

Copyright © RevComm Inc. 1. 業務分析とデータのモデリング 2. アクセスパターン設計 3. テーブルとインデックス設計 4. クエリ条件設計 DynamoDBのテーブル設計の流れ 53

Slide 54

Slide 54 text

Copyright © RevComm Inc. 中の人 @_kensh さんより https://speakerdeck.com/_kensh/dynamodb-design-practice?slide=49 54

Slide 55

Slide 55 text

Copyright © RevComm Inc. 業務分析 RDRAでやってみました 誰に価値を与え、 そのために誰が関わるのか ? 関わる人が価値を出すための 仕事の流れ 55

Slide 56

Slide 56 text

Copyright © RevComm Inc. データモデルの形に整理 ※実際のシステムとは異なります 56

Slide 57

Slide 57 text

Copyright © RevComm Inc. アクセスパターン→ユースケースリストを出す システムに関わる登場人物と システムの接点 誰がどんなI/Fで何を? 57

Slide 58

Slide 58 text

Copyright © RevComm Inc. テーブル・インデックス設計 58

Slide 59

Slide 59 text

Copyright © RevComm Inc. テーブル・インデックス設計 RDBならテーブル分割するようなものもキャパシティを効率的に使うため できるだけ1つのテーブルで表現する データを重複なく保管し、 ホットパーティションが発生しないようにするための PK, SKを設定 59

Slide 60

Slide 60 text

Copyright © RevComm Inc. 特定のデータ範囲に対してアクセスが集中すると 「ホット」なパーティションが作成される場合がある これにより、スロットリングが発生することや、 プロビジョニングされた I/O 容量が効率的に 使用されないことがある ホットパーティションとは 60

Slide 61

Slide 61 text

Copyright © RevComm Inc. 1処理ずつのアクセスだけでなく、 バッチ処理でそれぞれのアクセスが パーティションに集中してもホットになる ホットパーティションとは ID DataType 1 Name DataValue John 1 Type dog 2 Paul cat batchWriter AWS Lambda Amazon DynamoDB 61

Slide 62

Slide 62 text

Copyright © RevComm Inc. ❌ Tenant_{account_tenant_id}   #Contacts ⭕ Contacts   #Tenant_{account_tenant_id}   #Contact_{contact_id} ホットパーティションとは 62

Slide 63

Slide 63 text

Copyright © RevComm Inc. テーブル・インデックス設計 検索のためのPK, SKをGSI用に設定 GSIでは全カラムをもつ必要がないため、 検索とソートに必要な項目だけ基本テーブルから射影 GSIは増やすとその分書き込みコストがあがるため 数を抑えたい 63

Slide 64

Slide 64 text

Copyright © RevComm Inc. テーブル・インデックス設計 検索のためのPK, SKをGSI用に設定 GSIでは全カラムをもつ必要がないため、 検索とソートに必要な項目だけ基本テーブルから射影 GSIは増やすとその分書き込みコストがあがるため 数を抑えたい 64

Slide 65

Slide 65 text

Copyright © RevComm Inc. テーブル・インデックス設計 DataType: なんのデータ#どのテナントと紐づいてるか #どの連絡先と紐づいてるか 65

Slide 66

Slide 66 text

Copyright © RevComm Inc. テーブル・インデックス設計 DataType: なんのデータ#どの連絡先と紐づいてるか SearchType: 検索の種類#テナントid SearchValue: "なんのデータ"の値 CreatedAt(ソートしたい項目): id取得のための検索itemと基本情報itemにだけセットすればいい 66

Slide 67

Slide 67 text

Copyright © RevComm Inc. テーブル・インデックス設計 DataType: なんのデータ#どの連絡先と紐づいてるか #紐づくデータ SearchType: 検索の種類#どのデータと紐付けるか( ON的な)#紐付ける値 67

Slide 68

Slide 68 text

Copyright © RevComm Inc. このクエリ条件をもとに実際に動かしてテストしていく クエリ条件設計 機能 Entity UseCase Lookup parameters order by Table/Index Key Filter 一覧表示 contacts, contact_sample getContactsByTenantId, getContactSampleByContactId 1. {tenant_id}, 2. {contact_id} created_at (DESC) 1. GSI 2. Primary Table 1. SearchType = “FreeWord#Tenant_{acco unt_tenant_id}” 2. ID = :contact_id and DataType = “Tenant_{account_tenant _id}#Contacts” - 一覧表示 (検索) contacts, contact_sample getContactsByTenantId, getContactSampleByContactId 1. {tenant_id}, 2. {contact_id} created_at (DESC) 1. GSI 2. Primary Table 1. SearchType = “FreeWord#Tenant_{acco unt_tenant_id}” and SearchValue BEGINS_WITH :tenant_id”#”:param 2. ID = :contact_id and DataType BEGINS_WITH “Contacts#Tenant_{acco unt_tenant_id}#Contact_” - 個別表示 contacts, contact_sample ・ ・ ・ 電話発信 contacts 商談後情報入力 contact_sample ・ ・ ・ 68

Slide 69

Slide 69 text

Copyright © RevComm Inc. このクエリ条件をもとに実際に動かしてテストしていく クエリ条件設計 機能 Entity UseCase Lookup parameters order by Table/Index Key Filter 一覧表示 contacts, contact_sample getContactsByTenantId, getContactSampleByContactId 1. {tenant_id}, 2. {contact_id} created_at (DESC) 1. GSI 2. Primary Table 1. SearchType = “FreeWord#Tenant_{acco unt_tenant_id}” 2. ID = :contact_id and DataType = “Tenant_{account_tenant _id}#Contacts” - 一覧表示 (検索) contacts, contact_sample getContactsByTenantId, getContactSampleByContactId 1. {tenant_id}, 2. {contact_id} created_at (DESC) 1. GSI 2. Primary Table 1. SearchType = “FreeWord#Tenant_{acco unt_tenant_id}” and SearchValue BEGINS_WITH :tenant_id”#”:param 2. ID = :contact_id and DataType BEGINS_WITH “Contacts#Tenant_{acco unt_tenant_id}#Contact_” - 個別表示 contacts, contact_sample ・ ・ ・ 電話発信 contacts 商談後情報入力 contact_sample ・ ・ ・ テーブル設計とクエリ条件設計を往復・・・ 69

Slide 70

Slide 70 text

Copyright © RevComm Inc. 一覧表示(検索)のサンプルコードはこちら 主な流れ 1. GSI経由で検索用データから条件に一致する contact_id一覧を取得する 2. 取得したcontact_id一覧から基本データを取得する ● 部分一致検索の書き方を検索していると今は非推奨の古い書き方例がかなりよく出てくるので注意 ● SDKのresourceは古いため非推奨となっており、代わりにclientを使うことが推奨されている データ取得イメージ 70

Slide 71

Slide 71 text

Copyright © RevComm Inc. 1. 今回検証するにいたった背景 2. DynamoDBでできることできないこと 3. テーブルとデータ取得コードの例 4. まとめ アジェンダ 71

Slide 72

Slide 72 text

Copyright © RevComm Inc. 1. データ抽出条件が完全一致、あるいは前方一致で良い 2. データ件数が多く、今後もさらに増加が予想される 3. アクセスパターンや要件がはっきりしている 4. データ検索する際の絞り込み条件となる項目が多くない 5. 基本的にテーブルをjoinする必要がない 6. 並び順は問わない あらためてDynamoDBがマッチすると思われるユースケース 72

Slide 73

Slide 73 text

Copyright © RevComm Inc. 今回DynamoDBを採用しなかった一番の理由 部分一致だと大量データの検索がスピーディにできない 完全一致、あるいは前方一致でなら 高パフォーマンスを発揮できる 1. データ抽出条件が完全一致、あるいは前方一致で良い 73

Slide 74

Slide 74 text

Copyright © RevComm Inc. データ数が多くてもユースケースがマッチしていて 設計がうまくいけばかなり速い 50万件のitemに対する検索でも、 2000万件のitemに対する検索でも 同じくらいのスピードで結果が返ってくる🤩 2. データ件数が多く、今後もさらに増加が予想される 74

Slide 75

Slide 75 text

Copyright © RevComm Inc. 事前の設計がかなり大事 アクセスパターンがはっきり決まっていない状態で GSIを活用した検索の仕組みにするのはおすすめできない 特にホットパーティションが生まれないように注意 3. アクセスパターンや要件がはっきりしている 75

Slide 76

Slide 76 text

Copyright © RevComm Inc. 今回のような設計にすると項目が多ければ多いほど 1件の連絡先あたりのitem数が増えることになり 書き込み・読み込み時のコストも増えていくことになる 4. データ検索する際の絞り込み条件となる項目が多くない 76

Slide 77

Slide 77 text

Copyright © RevComm Inc. これもEntityとリレーションを貼るテーブルが多いほど 1件の連絡先あたりのitem数が増えることになる 全体のクエリも複雑になるのでできればない方がいい 5. 基本的にリレーションがない 77

Slide 78

Slide 78 text

Copyright © RevComm Inc. SQLでいうところのorder byがない Sort Key順以外の並び順にしたいときは 一度全検索結果のidと並び順条件の情報を取得した上で アプリ側でソートすることになる そうすると本当は1MBまでで取れるデータだけでいいところが 全結果を取得しないといけなくなる 並び順はいっそ選べないと思っていたほうが良さそう 6. 並び順は問わない 78

Slide 79

Slide 79 text

Copyright © RevComm Inc. 最終的に2000万件のitemの検証になり、 かなり大規模な検証となりました 個人ではここまで試しきれなかったと思います 今回DynamoDB採用には至りませんでしたが せめて得たものを広く共有することで供養になればと思います 🙏 RIP🙏 79

Slide 80

Slide 80 text

Copyright © RevComm Inc. Thank you!

Slide 81

Slide 81 text

Copyright © RevComm Inc. おまけ

Slide 82

Slide 82 text

Copyright © RevComm Inc. ● 特に参考にした記事 ○ https://speakerdeck.com/_kensh/dynamodb-design-practice ○ https://speakerdeck.com/handslabinc/dynamodbdemojian-suo-sitai ● DynamoDBのテーブル設計における多対多の考え方 ○ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-adja cency-graphs.html ○ https://hack-le.com/dynamodb-many-to-many/ ● ホットパーティションについて ○ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-part ition-key-uniform-load.html ● クエリのパフォーマンスと継続した負荷に対してDynamoDBはどのように対応するか検証記事 ○ https://aws.amazon.com/jp/blogs/news/part-2-scaling-dynamodb-how-partitions-ho t-keys-and-split-for-heat-impact-performance/ 参考