Successfully reported this slideshow.
Your SlideShare is downloading. ×

Sansanがメッセージング (SQS) でスケーラビリティを手に入れた話

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
AWSからのメール送信
AWSからのメール送信
Loading in …3
×

Check these out next

1 of 48 Ad

More Related Content

Slideshows for you (20)

Similar to Sansanがメッセージング (SQS) でスケーラビリティを手に入れた話 (20)

Advertisement

Recently uploaded (20)

Sansanがメッセージング (SQS) でスケーラビリティを手に入れた話

  1. 1. Sansanがメッセージング (SQS) で スケーラビリティを手に入れた話 using C# on Windows; 神原 淳史 @atsukanrock 2017-05-31 AWS Dev Day Tokyo 2017
  2. 2. 自己紹介 • 神原 淳史 @atsukanrock • Development Manager at • Interested in • Domain-Driven Design • C# / .NET • Enterprise Integration Patterns
  3. 3. 目次 • Sansanサービスの説明 • メッセージングとは • メッセージングによる課題解決の実例 • メッセージングの注意点 • まとめ
  4. 4. Sansanサービスの説明 名刺を企業の資産に変える
  5. 5. サービス全体像 Scanner データ化サービス (Digitization Service) 精度99% 社内の別組織が開発・運用 API Call Callback API API Call
  6. 6. マルチテナント型クラウドサービス tenant_id biz_card_id given_name family_name email … xxx 11111 太郎 山田 … … xxx 22222 二郎 鈴木 … … xxx 33333 三郎 佐藤 … … xxx 44444 四郎 田中 … … yyy 55555 五郎 高橋 … … yyy 66666 六郎 山本 … … yyy 77777 花子 中村 … … テナント (≒組織) 内で データ共有 DBテーブルをテナント毎に分割
  7. 7. サービス規模の拡大 2014 2015 2016 2017 Tenants 2014 2015 2016 2017 Users 2014 2015 2016 2017 Biz Cards 2014 2015 2016 2017 Maximum Users Per Tenant 2014 2015 2016 2017 Maximum Biz Cards Per Tenant スケーラビリティの 課題が次々に発生
  8. 8. メッセージングとは 前提知識を早巡り
  9. 9. メッセージングとは Message Queue Web App Web API Batch Message Consumer Server Message Message Message Message Database メッセージキューを介し、 プロセス間やアプリケーション間で データや制御を伝達する
  10. 10. 特徴 • メッセージは単なるテキスト • 処理失敗したメッセージはリトライされる • 厳密には、再度処理対象となる • 一定回数失敗し続けたメッセージは別キューに退避 される (Dead Letter Queue)
  11. 11. ミドルウェア Amazon SQS Standard Queue Amazon SQS FIFO Queue Azure Storage Azure Service Bus MSMQ PaaS Yes Yes Yes Yes No Transaction No No No Local Distributed At-most-once No Yes No Yes Yes FIFO Best effort Yes Best effort Yes (w/ session) Yes 現Sansanで採用
  12. 12. メッセージングによる 課題解決の実例 スケーラビリティを手に入れる
  13. 13. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  14. 14. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  15. 15. 巨大なトランザクション 所有名刺の参照・更新可否を ユーザ単位で設定可能 0 5,000,000 10,000,000 15,000,000 20,000,000 25,000,000 30,000,000 35,000,000 40,000,000 0 1,000 2,000 3,000 4,000 5,000 6,000 権限設定レコード数 ユーザ数 権限設定レコードの洗い替え処理を 1トランザクションで処理すると、 指数関数的にトランザクションが巨大化
  16. 16. Scalable Design トータルで処理するレコード数は変 わらないが、並列処理によりスルー プットが向上 Transaction A Transaction B Transaction C Transaction D 並列処理
  17. 17. 実装例 Web Server Consumers Amazon SQS Queue A Database User Consumer Amazon SQS Queue B メッセージ分割 並列処理
  18. 18. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  19. 19. 終わらないバッチ処理 0 500,000 1,000,000 1,500,000 2,000,000 2,500,000 3,000,000 3,500,000 4,000,000 4,500,000 DIGITIZATIONS/MONTH DIGITIZATION VOLUME TREND
  20. 20. Non-scalable Design var targetBizCards = GetBizCardsByDigitizedTimestamp(from, to); foreach (var targetBizCard in targetBizCards) { DoSomething(targetBizCard); } 0 500,000 1,000,000 1,500,000 2,000,000 2,500,000 3,000,000 3,500,000 4,000,000 4,500,000 2016-05 2016-06 2016-07 2016-08 2016-09 2016-10 2016-11 2016-12 2017-01 2017-02 2017-03 2017-04 DIGITIZATIONS/MONTH DIGITIZATION VOLUME TREND 処理時間がデータ化の量に比例
  21. 21. Scalable Design 1件のデータ化 後続処理B後続処理A 1日中、並列処理されている 1件ずつすぐに後続処理を起動 (Domain Event) • バッチウィンドウが1日中に • 後続処理が並列化
  22. 22. Domain Eventとは NOT Domain Event Domain Event Operation A Operation C Operation A A Completed Event Operation B Operation C B Request C Request Aは後続処理を 知らない Operation B Aは次にBなことを 知っている Event Aggregator 事前にEvent AggregatorにSubscribe
  23. 23. Domain Eventの実装例 Publisher Amazon SNS Topic Amazon SQS Subscriber Queue A Subscriber A Subscriber B push pull Amazon SQS Subscriber Queue B
  24. 24. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  25. 25. 急激に変化するデータベース負荷 0 10,000 20,000 30,000 40,000 50,000 60,000 70,000 80,000 90,000 100,000 110,000 120,000 WRITES/HOUR DIGITIZATION THROUGHPUT
  26. 26. データベース負荷を安定させる 0 10,000 20,000 30,000 40,000 50,000 60,000 70,000 80,000 90,000 100,000 110,000 120,000 WRITES/HOUR DIGITIZATION THROUGHPUT 平均値 「後回し」にできれば 負荷が安定
  27. 27. データ化処理のアーキテクチャ Web API Server Consumer Amazon SQS Queue Database Digitization Service Consumerの並列度の制御 により負荷を均す メッセージキューにより 「後回し」を実現
  28. 28. 並列度の制御 Consumer Database • インスタンス並列度 • Auto Scaling等を利用すれば手軽 • スレッド並列度 • .NETであればSemaphoreSlim クラス等を利用して自前実装 Consumerの並列度の制御 により負荷を均す
  29. 29. while (true) { IDisposable throttlingToken = null; try { throttlingToken = await ThrottlingPolicy.EnterAsync(); var message = await MessageChannel.ReceiveAsync(); if (message == null) { throttlingToken.Dispose(); var interval = IdleRetryPolicy.GetRetryInterval(++idleCount); await Task.Delay(interval, cancellationToken); continue; } idleCount = 0; Task.Run(async () => SemaphoreSlimクラス等を 利用してスレッド並列度を制御 Channelからメッセージを取得 ワーカースレッドを起動 ※イメージです
  30. 30. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  31. 31. メンテナンス前 (従来) データ化サービス (Digitization Service) Developers Developers 停止依頼 停止
  32. 32. メンテナンス前 (現在) データ化サービス (Digitization Service) Developers
  33. 33. メンテナンス中 Web API Server Amazon SQS Queue Digitization Service データ化サービスから 見ると平常運転 メッセージが処理されず 溜まっていく
  34. 34. メンテナンス完了時 Web API Server Consumer Amazon SQS Queue Database Digitization Service メンテナンス中に溜まった メッセージを処理
  35. 35. 抱えていた課題 • 巨大なトランザクション • 終わらないバッチ処理 • 急激に変化するデータベース負荷 • 低いメンテナンス自由度 • リカバリ不可能な処理
  36. 36. リカバリ不可能な処理 メッセージングなし • リトライは自前実装 • 落ちた箇所によっては リカバリ不可能 メッセージングあり • リトライは標準装備 • リトライしても失敗し続けた 処理はDead Letter Queueへ • 処理内容がテキストで表現さ れているので、必ずリカバリ 可能 タイムアウト、外部サービス障害等による処理失敗時
  37. 37. メッセージングの注意点 銀の弾丸はない
  38. 38. 注意点 • 冪等性を保証する必要がある • 順序は保証されない (Amazon SQS Standard Queue) • 結果整合性モデルになることが多い
  39. 39. 注意点 • 冪等性を保証する必要がある • 順序は保証されない (Amazon SQS Standard Queue) • 結果整合性モデルになることが多い
  40. 40. 冪等性 (べきとうせい) とは ある操作を何回行っても結果が同じこと REST API設計の議論で HTTP POST (冪等でない) とHTTP PUT (冪等) の意味の違い インフラ界隈で ChefやAnsibleで実現されている
  41. 41. メッセージングと冪等性 • Amazon SQSは基本、At-Least-Once Delivery (Standard Queue) Exactly-Once ProcessingモデルのFIFO Queueもあるが、 遅い & Tokyoに来ていない • 例外発生等によりメッセージの処理に失敗した場合、 該当処理はリトライされる 冪等性を保証する必要がある 強い一貫性モデル (ACID) を持つRDB等で保証するのが基本
  42. 42. 注意点 • 冪等性を保証する必要がある • 順序は保証されない (Amazon SQS Standard Queue) • 結果整合性モデルになることが多い
  43. 43. 順序は保証されない • Amazon SQSは基本、順序保証なし (Standard Queue) FIFOを保証するFIFO Queueもあるが、遅い & Tokyoに来てい ない 順序保証は自前で行う必要がある メッセージの処理の最後に次のメッセージを送信する等
  44. 44. 注意点 • 冪等性を保証する必要がある • 順序は保証されない (Amazon SQS Standard Queue) • 結果整合性モデルになることが多い
  45. 45. 結果整合性モデルになる例 Transaction A Transaction B Transaction C Transaction D 並列処理 Transaction AとBしか終わっていな い時点では、ビジネストランザク ションとして整合性が取れていない 許容できない場合、分割後の全ての メッセージ処理が完了するまで処理 結果を見せない等の制御が必要
  46. 46. まとめ 伝えたいことを改めて
  47. 47. まとめ • メッセージングを使うことで以下を向上できる • スケーラビリティ • 堅牢性 • 運用性 • 反面、設計難易度・複雑度は上がる傾向にある 特性を知り、適切な場面・方法で使用すべし

Editor's Notes

  • C#成分はほとんど入っておらず、言語非依存の技術であるメッセージングに関するお話
  • ユーザが名刺をスキャナーでスキャンすると、Web APIでSansanに名刺画像が送信される
    Sansanは受け取った名刺画像をテキストデータにするため、データ化サービスにWeb APIで送信する ※データ化サービスは社内の別組織が開発・運用しており、ユーザが触れる部分のSansanサービスとは疎結合
    Sansanはデータ化サービスからCallback APIで、名刺テキストデータを受け取る
  • ポイントは、個人の名刺管理ではなく、テナント単位で名刺データベースを構築できる点
    右側はDBテーブルのイメージ
    他のマルチテナントの設計パターン
    データベースごと分ける
    データベース内のスキーマを分ける
  • 非公開の数値を含むため縦軸は伏せているが、雰囲気は掴める
    Maximum Users Per Tenantの極端な拡大ぶりは特にすごい
  • Messageは
  • Sansanサービスの特徴的な仕様として、細やかなセキュリティ設定機能がある
    名刺というのは個人情報であり、同じテナント内であっても参照制限、更新制限をかけたいという要求が頻繁に出るが、Sansanはそれに対応している
    特に企業規模が大きくなればなるほど出やすい要件だが、例えば役員が交換した名刺を一般社員の誰でも参照可能とはしづらい。逆方向は参照可能としたかったりする
    左側の図
    中央の四角い枠の両側に並んでいるのはユーザで、両方共上からユーザA, B, C, D
    中央の四角い枠の中の矢印が、DBの権限設定レコード1レコード分
    右側のグラフ
    テナント内のユーザ数が増えると、対応するための権限設定レコードは指数関数的に増える
    1テナント内の権限設定レコード洗い替え処理が発生することがあったが、整合性を保って処理するために1つのDBトランザクション内で処理していた
    結果、そのDBトランザクションが指数関数的に巨大化していた
  • 注意すべきなのは、この設計でスループットが向上するかどうかはDBのパフォーマンス特性に依るので、計測が重要
    SansanのDBでは、スループットが向上した
    この設計だと、一部は完了、一部は未完了と状態が混在することがあるが、その辺りは後ほど触れる
  • これは、メッセージングを活用した分散並列処理の設計の基本形
  • いずれもネットワーク越しにアプリケーションを連携するPaaSだが、Amazon SNSはpushベース、Amazon SQSはpullベース
    SNSは、モバイルプッシュ通知やSMSメッセージ送信等が可能だが、SQSキューへのメッセージ送信も可能
  • 個人的な想像だが…
    データ化サービスでは、精度の維持向上のため、人力入力に頼っている部分がある
    現時点ではデータ化のほとんどは日本語の名刺なので、日本語を理解できる人が入力している
    自ずと、日本時間の日中にデータ化の量がピークを迎える
  • 急激に変化するデータベース負荷は、データベースに優しくない
    データ化処理は、それほど高い即時性は求められない
  • 図にしてしまうと非常に当たり前な感じだが、ポイントは3つ
    Digitization Serviceから見ると、Web API Serverは常に即時処理している
    実際にはAmazon SQS Queueに溜まっていて、後回しにされることもある
    Consumerの並列度制御により、データベース負荷が高くなりすぎない
  • FIFO遅い: 300 transactions / sec ( http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html#FIFO-queues-moving )

×