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

スケーラビリティのためのSansanアプリケーション基盤

 スケーラビリティのためのSansanアプリケーション基盤

Sansan×gloops インフラ合同勉強会
http://connpass.com/event/33442/

Junya Wada

July 28, 2016
Tweet

Other Decks in Technology

Transcript

  1. Copyright © 2014 Sansan, Inc. All rights reserved. > 自己紹介

    1 • 和田潤也 • 某SIerで8年弱 ⇒ SansanにJOIN • C#、JavaScript 辺り • 主にUI基盤とかを開発していた • 情弱 GitHub: chocolamint
  2. Copyright © 2014 Sansan, Inc. All rights reserved. > え?「インフラ勉強会」…?

    2 • インフラの話とはちょっと違います。。。 • アプリケーション基盤の話をします • インフラ要素とも多少絡められたらいいな…
  3. Copyright © 2014 Sansan, Inc. All rights reserved. > スケーラビリティのための仕組み

    3 • DBの垂直・水平分散 • 垂直分散 • 役割によってDBを分割 • 水平分散 • ShardingKey によってDBを分割 • ユーザーごとに使うDBを分散するイメージ • メッセージ基盤 • Pub-Sub 型の分散処理基盤 • キューイングサービスを利用
  4. Copyright © 2014 Sansan, Inc. All rights reserved. > 水平・垂直分散

    5 Query Shard Mapping Common Database Use Main data Databases Shard1 Shard3 Shard2 Shard4 News Databases
  5. Copyright © 2014 Sansan, Inc. All rights reserved. > Sansan.Data

    6 using (new ShardingScope(shardingKey)) { // ここでの接続は指定されたシャードにいく ... }
  6. Copyright © 2014 Sansan, Inc. All rights reserved. > Sansan.Data

    7 Webにおいては ActionFilterAttribute を継承した ShardingFilterAttribute を使って ShardingScope の生成・破棄(Dispose)をしている using (var cn = await ConnectionHelper.OpenDataAsync()) { // 勝手に現在のユーザーが繋ぐべきシャードに繋がる return await cn.Connection.QueryAsync<string>(sql); }
  7. Copyright © 2014 Sansan, Inc. All rights reserved. > ちょっと前までのツラみ

    9 • 統一的な非同期処理基盤がない • Webアプリのボタンクリックで数分かえって来ない • 同時実行できない • 古い自作基盤が並列処理で死ぬ :yami: • リトライで成功するのにアラート • リレー式の処理の滞留具合がわからない • メンテナンス時の停止と開始がツラい
  8. Copyright © 2014 Sansan, Inc. All rights reserved. > 非同期処理基盤がない

    10 • Webアプリで数分かかるボタンクリック • 非同期処理するには個別にバッチ開発が必要 Button Click Insert Record with status = 0 Polling with Task Scheduler FooBar.exe FooBarJob Batch Server Web Server
  9. Copyright © 2014 Sansan, Inc. All rights reserved. > 同時実行できない

    11 status = 0 を取得 ↓ 何か処理 ↓ status = 1 に更新 複数台(プロセス)で 対象データを取り合うと死ぬ ↓ 複雑な排他制御が必要(しんどい) ↓ スケールしない Batch Server 1 Batch Server 2
  10. Copyright © 2014 Sansan, Inc. All rights reserved. > リトライで成功するのにアラート

    12 タスクマネージャーによる プロセスの定期起動 1分後 アクセス失敗 成功 アラート発砲
  11. Copyright © 2014 Sansan, Inc. All rights reserved. > メッセージ基盤

    16 Message Queue Web Server Batch Server Enqueue Dequeue Message Server Execute message concurrency SaaS の キューサービスを利用 Message
  12. Copyright © 2014 Sansan, Inc. All rights reserved. > メッセージ基盤のいいところ

    17 • スケールできる • 1プロセス内でマルチスレッドによる並列処理 • キューの種類ごとに並列数を調整可能 • ノードを増やせばさらにスケール可能 • 自動リトライ • 複数回の exponential な自動リトライ • リトライに成功しない場合は dead letter 行き • 自動でアラートメール発砲 • 各処理は冪等であるべき
  13. Copyright © 2014 Sansan, Inc. All rights reserved. > メッセージ基盤のいいところ

    18 • 負荷が安定する • セマフォで並列数制御 • メッセージ毎に異なるキューにルーティング • キューの滞留を監視可能 • グラフでモニタリングも出来る • SaaS でアラームを定義できるので滞留を監視できる
  14. Copyright © 2014 Sansan, Inc. All rights reserved. > メッセージ基盤で出来ること

    19 • 1つのメッセージに複数の Subscriber を定義可能 • システムイベントに対する複数処理を割り当て • ex) 新しい名刺が登録されたら… • ◦◦処理を実行 • △△処理を実行 • 全て完了したら××処理を実行 • 安全に停止できる • Windows サービスとして実装 • OnStop でキャンセル要求 • 優先度の高いものから処理できる • キューの種類ごとに優先度別のキューを用意できる
  15. Copyright © 2014 Sansan, Inc. All rights reserved. 20 Mail

    Queue (High) Mail Queue (Normal) Mail Queue (Low) News Queue (High) News Queue (Normal) News Queue (Low) 4 parallel 8 parallel
  16. Copyright © 2014 Sansan, Inc. All rights reserved. > コードのイメージ

    21 MessageQueue queue; while (true) { var message = queue.ReceiveMessage(); if (message != null) Task.Run(() => DispatchMessage(message)); } var msg = new SendMailMessage("title", "body"); await msg.SendAsync(priority: MessagePriority.Background); 標準で用意されているメッセージ • SendMailMessage • SendAllMailMessage • EventMessage
  17. Copyright © 2014 Sansan, Inc. All rights reserved. > Next...

    22 • 実際に基盤に乗っかった処理はまだ一部 • 随時効果の高いところから乗せ換え中 • 現状はメッセージ基盤/バッチのログがテキスト • ツラい • fluentd で Elasticsearch に送り込み Kibana で見れる ように • 絶賛対応中