Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

AWS Dev Day Tokyo 2018 | Amazon DynamoDB Backed な テレコムコアシステムを構築・運用してる話

10,718 views

Published on

AWS Dev Day Tokyo 2018
Amazon DynamoDB Backed な テレコムコアシステムを構築・運用してる話

株式会社ソラコム CTO
安川 健太

Published in: Technology

AWS Dev Day Tokyo 2018 | Amazon DynamoDB Backed な テレコムコアシステムを構築・運用してる話

  1. 1. Amazon DynamoDB Backed な テレコムコアシステムを構築・運用してる話 SORACOM: You Create, We Connect Kenta Yasukawa, Ph. D. Cofounder & CTO, SORACOM, Inc. 2018/11/1
  2. 2. ©2017 SORACOM, INC 2 自己紹介 安川 健太 Cofounder & CTO, SORACOM Inc. 略歴: Researcher at Ericsson Research AWS Solutions Architect AWS NoSQL Developer & SA Twitter: @thekentiest Facebook: fb.me/kenta.yasukawa LinkedIn: linkedin.com/in/kenta-y 好きなAWSのサービス: VPC、DynamoDB 居住地: Mountain View, CA, USA
  3. 3. ©2017 SORACOM, INC 3
  4. 4. ©2017 SORACOM, INC 4 IoTシステムに共通の形 ©2016 SORACOM, INC 4 Internet CloudThings IntelligenceConnected Devices
  5. 5. あのボタンだって そうですよね?
  6. 6. ©2016 SORACOM, INC 7 シンプルに見えてたくさんの課題が Internet CloudThings セキュリティ デバイスの 制約 ネットワーク接続 デバイスの 管理 クラウド側 の構成
  7. 7. デバイスを直接クラウドに繋ぐ SORACOM Air 通信事業者様 交換局 3G/LTE 外部から侵入できない安全な通信路 お客様と作る安全な通信路 お客様の クラウド Public Endpoints お客様 ①SIMをインストール Webコンソール ②Webから操作 API ③APIで自動化
  8. 8. ©2017 SORACOM, INC 9 IoTシステムに共通の形 ©2016 SORACOM, INC 9 Internet CloudThings IntelligenceConnected Devices
  9. 9. ©2016 SORACOM, INC 10 SORACOM Airが可能にする構成 CloudThings IntelligenceConnected Devices Internet The Internet is accessible, but optional
  10. 10. • Amazon VPCとプライベート接続  SORACOM Canal • プライベートクラウドと専用線/VPN接続  SORACOM Direct/Door • デバイスとサーバを単一の仮想L2サブネットに接続  SORACOM Gate 閉域網を構築する各種サービス The Internet VPG IoTバックエンド お客様のシステム Virtual Private Gateway (VPG)を通してお客様のシステムと接続
  11. 11. Public Endpoints SORACOM Beam デバイスとクラウドの橋渡しをする各種サービス SORACOM Funnel Amazon Kinesis Family Microsoft Azure EventHubs AWS IoT Google Cloud Pub/Sub • Publicエンドポイントにセキュアに接続  SORACOM Beam • クラウドサービスにデータを送信  SORACOM Funnel • データ収集&可視化  SORACOM Harvest & Lagoon 簡易で省電力なプロトコル - TCP / UDP raw socket - HTTP, MQTT - LoRaWAN, Sigfox 高機能でセキュアなプロトコル - TCP over TLS - HTTPS, MQTTS SORACOM Airが 提供する安全な通信路 SORACOM Harvest SORACOM Lagoon
  12. 12. SORACOM Krypton SIMで認証し、接続情報をセキュアにプロビジョニング SORACOM Krypton SIM認証 ログイン要求 クレデンシャル Amazon Cognito Kinesis Video Streamセルラー WiFi
  13. 13. ©2017 SORACOM, INC 14 SORACOM Airの裏側
  14. 14. 通信キャリアとMVNO インターネットモノ 基地局 データセンター MVNO(L2契約) MVNO ISP パケット交換 帯域制御 顧客管理 課金・・・ ブランド 販売網 通信キャリア 専 用 線 接 続
  15. 15. SORACOM Airの裏側 インターネットモノ 基地局 データセンター MVNO ISP パケット交換 帯域制御 顧客管理 課金・・・ ブランド 販売網 通信キャリア クラウドネイティブ設計な GGSN/PGW, HLR/HSS 専 用 線 接 続
  16. 16. Session Management Authentication & Authorization Billing API Gateway API API Polaris: Cellular Core Interfaces implemented as distributed system Amazon DynamoDB Cellular Core Network reinvented on AWS Availability Zone Availability Zone IoT Devices 3G/ LTE MNO AWS Direct Connect Dipper: Set of micro services that enable Polaris and API
  17. 17. ©2017 SORACOM, INC 18 アーキテクチャ全体についてはTMAで tma soracom
  18. 18. Session Management Authentication & Authorization Billing API Gateway API API Polaris: Cellular Core Interfaces implemented as distributed system Cellular Core Network reinvented on AWS Availability Zone Availability Zone IoT Devices 3G/ LTE MNO AWS Direct Connect Dipper: Set of micro services that enable Polaris and API Amazon DynamoDB 今日の本題
  19. 19. なぜDynamoDBを選んだのか?
  20. 20. •SORACOMにとって大事な特性 • Availability •Scalability • Durability •SORACOMにとって妥協できる特性 • Transactionサポート •SQLサポート 求める特性を最もよく満たすから
  21. 21. •やりたいのは信頼性の高いサービスの提供 ≠ 信頼性の高いDBシステムの構築運用そのもの DBを運用しなくていい! 自分たちで運用する DBシステム SORACOMを支えるDBシステムを 支える人たちが必要!!  AWSが運用してくれてる!! Amazon DynamoDB
  22. 22. 1. KVSだけでどうやって実装してるんですか? 2. Eventual Consistencyじゃシステムに不整合状態 起きませんか? 3. トランザクションなしで辛くないですか? とはいえ、よく聞かれること
  23. 23. •DynamoDBはKVSではありません • Partition Keyだけ使えば確かにKVS的 • Partition KeyとSort Keyも使えば範囲指定してク エリも可 • Indexも使えば任意のAttributeでクエリ可 Q1. KVSだけでどうやって実装してるんですか?
  24. 24. DynamoDBのキー 引用元: https://www.slideshare.net/AmazonWebServicesJapan/20170809-black-belt-dynamodb/21
  25. 25. DynamoDBのIndex 引用元:https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html
  26. 26. • Strong Consistencyを指定して読むことも可 • Strong consistency • Eventual consistency • Conditional Updateを使えば楽観的ロックも可 2. Eventual Consistencyじゃシステムに不整 合状態起きませんか? Increment version iff version == 1 Version = 1 -> 2 Increment version iff version == 1
  27. 27. •単一アイテムの更新はアトミック • 1回の更新を1アイテムにまとめるように設計 •どうしても複数アイテム更新が必要なときは •DynamoDB Stream + Lambda活用 • 冪等性をもたせてエラーが起きたらリトライ 3.トランザクションなしで辛くないですか?
  28. 28. •SORACOMがAmazon DynamoDBを使う理由 • 求める特性を最もよく満たすから •DBを運用しなくていいから • 安川が元DynamoDBチームにいたから •SQLなDBとは設計時の考え方が違う • 限られた関係性の表現 •アトミック更新が出来るのは1アイテムまで ここまでのまとめ
  29. 29. NoSQL (DynamoDB) Firstでの開発
  30. 30. • 対象のModelの属性を決める • Modelの更新/クエリの仕方を考える • 更新は1アイテムに収められるか • クエリはどの属性値で行うか • Modelに対応するテーブルとそのスキーマを決める • 出来るだけModelとテーブルの関係を1:1に • スキーマとして設定するのはKeyとIndexだけ テーブルの設計
  31. 31. SORACOM SIM管理の例で見てみる
  32. 32. Subscriberを扱うユースケースの例
  33. 33. • Subscriber Modelの特徴 • IMSIというIDを持つ • 最初は特定のOperatorに紐づいて いない • 購入して登録するとそのOperator に紐づく • 更新/クエリの仕方の例 • IMSIだけで特定して更新/クエリ • 特定のOperatorに紐づく一覧を取 得 SORACOMのSubscriber (≒ SIM) Subscriber s = { imsi: “xyz”, operatorId: “OP…”, status: “active”, … }
  34. 34. • IMSIは単独でPrimary Key • Partition Keyのみのスキーマを選択 • OperatorIDを持つ複数のSubscriber • OperatorIDにIndexを作成 Subscriber (≒ SIM)のスキーマ設計 IMSI (Part) OperatorID Status … 1234567890000001 OP0012345678 active … 1234567890000002 OP0012345678 ready … 1234567890000003 instock … OperatorID (Part) IMSI (Sort) Status … OP0012345678 1234567890000001 active … OP0012345678 1234567890000002 ready …
  35. 35. •Javaで書くならModelとテーブルの関係はAnnotation で記述可 •AWS Java SDKのDynamoDBMapperを活用 ちなみに @DynamoDBTable(tableName=“subscriber”) public class Subscriber { @DynamoDBHashKey public String getImsi(){ … } @DynamoDBAttribute public String getOperatorId(){ ... } }
  36. 36. •DynamoDB Streamを活用してTriggerを実装すると 簡単 更新履歴を保存したいような時は? Stream PutItem Subscriber table Subscriber History table Lambda function
  37. 37. さらにSubscriberのGroupを実装したい
  38. 38. • Group Modelの特徴 • 任意の数のSubscriberが所属 • Subscriberが所属するGroupは1つ • 更新/クエリの仕方 • Group IDで属性を更新/クエリ • 指定したSubscriberをGroupに追加・削 除 • 特定のGroupに所属するSubscriber一覧 を取得 • 指定したSubscriberの所属するGroupを 取得 Groupの設計 Group g = { id: “dead-beaf-cafe”, operatorId: “OP…”, configuration: { … }, … }
  39. 39. • Groupの属性としてSubscriber IDのリ ストを持つ • 問題: • アイテムサイズの上限で頭打ち • Groupに追加する際、Groupと Subscriber双方のアイテムの更新が 必要 • Groupに所属するSubscriberの情報 を取得するのにSubscriberの数分の クエリが必要 ナイーブな実装(1) Group g = { id: “dead-beaf-cafe”, operatorId: “OP…”, configuration: { … }, subscribers: [ “imsi1”, “imsi2”, … ] }
  40. 40. • Group IDから所属する Subscriber一覧を引くテーブ ルを用意する • 問題: • Groupに追加する際、 GroupとSubscriber双方の アイテムの更新が必要 • Subscriber更新時もGroup 側のテーブルの更新が必要 ナイーブな実装(2) IMSI (Part) OperatorID Status Group ID 1234567890000001 OP0012345678 active … 1234567890000002 OP0012345678 ready … 1234567890000003 instock … OperatorID (Part) Group ID (Sort) IMSI OP0012345678 1234-5678-… 1234567890000001 OP0012345678 abcd-cafe-… 1234567890000002 OP0012345679 cdef-beef-… 1234567890000004 Subscribers Table Group Table
  41. 41. 1アイテム更新だけで出来ない?
  42. 42. • IMSIは単独でPrimary Key • Partition Keyのみのスキーマを選択 • GroupIdのGSIを作成 SubscriberテーブルにIndexを張る IMSI (Part) OperatorID Status Group ID 1234567890000001 OP0012345678 active 1234-5678-… 1234567890000002 OP0012345678 ready abcd-cafe-… 1234567890000003 instock cdef-beef-… Group ID (Part) IMSI (Sort) Status … 1234-5678-… 1234567890000001 active … abcd-cafe-… 1234567890000002 ready … Subscribers Base Table Group ID Index OperatorID (Part) Group ID (Sort) OP0012345678 1234-5678-… OP0012345678 abcd-cafe-… OP0012345679 cdef-beef-… Group Table
  43. 43. • Partition-Sort KeyとIndexを使ってモデルを表現 • Index / Sort Key クエリ以外はフルスキャンなのでご 注意 • 出来るだけ1回の更新で済むように設計 • テーブルは分けずにむしろまとめていく方向で • Indexや複合キーをうまく活用 • 値のProjectionは必要に応じて調整 テーブル設計で大事なこと
  44. 44. より複雑な処理をDynamoDBで 実現するためのテクニック
  45. 45. •二段階のソートキーがあるなら複合キーにIndex •例:Product Typeで一覧しつつ、特定のSerial Numberの範囲をクエリしたりしたい 複数属性で範囲指定クエリしたい場合 User ID (Part) Product Type Serial Number 1234567890000001 Button 0000001 1234567890000001 Button 0000002 1234567890000001 Modem 0000001 あるUserのButtonの一覧を取りたければ SortKey BEGINS_WITH “Button_” あるUserのButtonの中からSerial Numberがある範囲のクエリしたければ SortKey BETWEEN “Button_xxx” AND “Button_yyy” ProductType_SerialNumber (Sort) Camera_0000001 Camera_0000002 Modem_0000003
  46. 46. •全体のサイズが1アイテムに収まるならいっそ 全部の値をアイテム内に収めてアトミック更新 複数の値を一度に更新したい場合の対処法 Product Line Products (Map) LastUpdatedTime brandA {product1: 100, product2: 300, product3: 103, …} 2018-11-01-17:20 brandB {product1: 48, product2: 52, product3: 1231,…} 2018-10-31-09:30 brandC {product1: 1400, product2: 152, product3:1231, …} 2018-10-29-19:15 商品の在庫を管理する例: brandA で product1が5個、product3が10個売れたとしたら 1. GetItemで brandA のアイテムを読む 2. Product1から5個、product3から10個差し引いてConditionalUpdate(lastUpdatedTime == 2018-11-01-17:20)
  47. 47. •複数アイテムに跨るなら処理に冪等性をもたせて、 エラーが起きたらリトライで復旧できるようにする 複数の値を一度に更新したい場合の対処法 Coupon Code Coupon Amount Coupon Usage History (Map) 1234-5678 1000 { 2018-09: 125, 2018-10: 300, 2018-11: 100 } 9abc-def0 500 { 2018-09: 50, 2018-10: 100, 2018-11: 200} 5678-9abc 2000 { 2018-09: 10, 2018-10: 500, 2018-11: 200} 毎月利用した分を差し引くクーポンを管理する例 クーポンの残額そのものを管理するのではなくて、月ごとの利用料を記録していく(途中状態の管理)  特定月の締め処理にエラーが発生しても再度やり直すことで正しい状態に収束させられる(冪等性)
  48. 48. • Conditional Updateを使った楽観的ロック 楽観的ロックもうまく使うと強力です Increment version iff version == 1 Version = 1 -> 2 Increment version iff version == 1 @DynamoDBTable(tableName=“subscriber ”) public class Subscriber { @DynamoDBHashKey public String getImsi(){ … } @DynamoDBAttribute public String getOperatorId(){ ... } @DynamoDBVersion public Long getVersion() {…} }DynamoDBMapperなら モデルクラスに @DynamoDBVersion アノテーションをつけるだけ!
  49. 49. 楽観的ロックを活用したJobスケジューラ • ある時刻になったら一度だけ発火 するJobスケジューラが欲しい • Workerが1台じゃ心配だから複 数台にしたい • けど複数のWorkerがJobを取り に行ったら同時に実行しちゃう かもしれない
  50. 50. 楽観的ロックを活用したJobスケジューラ Job ID (Part) Time to Fire Status 1234-5678 2018-11-01-17:20 notStarted 9abc-def0 2018-10-31-09:30 Executing 5678-9abc 2018-10-29-19:15 Finished 1. Fetch a job to execute 2. Update status iff status == notStarted 3. Execute Job because step 2 succeeds Status = notStarted -> Executing 1. Fetch a job to execute 2. Update status iff status == notStarted 3. Skip the job because step failed •Jobテーブルを複数WorkerでPollingして未実行のイ ベントを見つけたらStatusを更新して実行
  51. 51. 楽観的ロックを活用したJobスケジューラ Job ID (Part) Time to Fire Status PartitionId 1234-5678 2018-11-01-17:20 notStarted 1 9abc-def0 2018-10-31-09:30 Executing 5678-9abc 2018-10-29-19:15 Finished def0-9abc 2018-11-02-19:39 notStarted 10 • 未実行の処理を並列に効率よく見つけるためにSparse Index • 各Jobに一定範囲 (e.g. 1〜10) の乱数をPartitionIdとして設定してGSI • 各Workerは乱数の範囲をそれぞれクエリしてJob取得 • 終わったらPartitionIdを消す( Sparse Indexから消える) Partiction ID (Part) Time to Fire (Sort) Status Job ID 1 2018-11-01-17:20 notStarted 1234-5678 10 2018-11-02-19:39 notStarted def0-9abc Job登録 1からい きまーす 自分は5 から
  52. 52. DynamoDBを使ったシステムの運用
  53. 53. •DynamoDBにはBuilt-inのバックアップやレプリ ケーションの仕組みはありません •DynamoDBにはキャパシティをAuto Scalingする仕 組みはありません •DynamoDBにはRegionを超えてテーブルをレプリ ケーションする仕組みはありません 昔は、、、 でした でした でした
  54. 54. •DynamoDBにはPITRもバックアップもあります! •DynamoDBには設定するだけでテーブルのAuto Scalingができます! •DynamoDBのGlobal Tableを作ればデータは自動的 にRegion間レプリケーションされます! 今は!
  55. 55. • Throttling発生時のアプリの挙動 • 並列処理をEvent loopで実現なら そんなに心配ない • Javascriptとかlibeventとか • 並列処理がThreadベースなら要注意 • JavaのSDKとか • 場合によってはアプリ全体に波及も とはいえ気をつけた方がいい大事なこと Photo from https://pxhere.com/en/photo/203547 (cropped to fit)
  56. 56. 実際Throttling発生をテストしてみると 3回リトライして諦めるようにしても10秒間 に100+リクエストしか完了してない  完了してない多くのリクエストは Thread Poolの空き待ち 全リクエストがThrottledエラーになるテスト
  57. 57. なのでNon BlockingなClient書きました 8.924秒で全リクエストが Throttled Exceptionで終了 全リクエストがThrottledエラーになるテスト
  58. 58. おわりに • SORACOMはAmazon DynamoDBを使う理由 • 求める特性に最も合っていたから • NoSQL Firstでの設計・開発 • 制約を知って設計すれば高可用で スケーラブルなシステムに自然となっていく • DynamoDBの運用面も近年急速に改善! • もうバックアップやキャパシティ調整で 悩まない • Throttling時の挙動にだけは気をつけて
  59. 59. One more thing…
  60. 60. • SORACOMのエンジニア • DevOps • 開発を中心に運用まで実施 • OpsDev • 運用を中心に見据えて開発を実施 • Support • お客様を中心に見据えて技術力を 発揮 We are hiring!! D DevOps OpsDev
  61. 61. 業務の様子は社員紹介ブログにて https://careers.soracom.jp/
  62. 62. ご興味をお持ちの方
  63. 63. 《 株式会社ソラコムのビジョン 》 世界中のヒトとモノをつなげ 共鳴する社会へ

×