inside mixiソーシャルネットワークを支える技術              Daichi Hiroki
廣木 大地(@hiroki_daichi)株式会社mixiシステム本部技術部たんぽぽ開発G 刺身にたんぽぽを乗せる仕事を無くす部隊 火を消したり、火の用心の見回りしたりする2008年新卒入社 アプリケーションアーキテクチャ 広告関連/技術教育/...
Social Graph       Diary        Voice       Calendar               CheckPC向け           スマートフォン向け    フィーチャフォン向け   API Servi...
mixi                 2004development歴史の長いコード機能間連携多い       2010同一のコードベース開発者数増         ついにメガプログラミングに
2つのスケーラビリティ
2つのスケーラビリティPerformance : アクセス数の増加や変動に耐えるDevelopment : 機能追加や多人数開発に耐える
memcached揮発するKVS汎用キャッシュLRU
Cacheとは?         Cache    DataSource更新に対して参照が多いデータの参照を高速に いつ、キャッシュにいれるか、更新されるか なにを、キャッシュにいれるか データ参照のホットスポットを発見して適応
通常データ             参照量の多い共通データ         write                write                                      複数台に同時書き込みkeyからketam...
Cache戦略の考え方 Cache方式   Cache対象レイヤリードスルー     カラムレベルライトスルー     レコードレベル変則ライトスルー   ドメインレベル  (1)(2)   サービスレベル
Cache戦略の考え方 Cache方式   Cache対象レイヤリードスルー     カラムレベルライトスルー     レコードレベル変則ライトスルー   ドメインレベル  (1)(2)   サービスレベル
リードスルー読み込み時にキャッシュに追加  client memcached data source 読み込み要求           キャッシュ問い合わせ キャッシュから                   特徴:           データ...
ライトスルー書き込み時にキャッシュに書き込む  client memcached data source  書き込み時           キャッシュ書き込み           データソース書き込み  読み込み要求   読み込み時は、リードス...
変則ライトスルー(1)DBに書き込んでから、マスターを読み出す   client memcached data source  書き込み時           データソース書き込み           データソース読み込み           ...
変則ライトスルー(2)incrをうまく使い数を管理する    client memcached data source  書き込み時           incr命令で加算する           データソース書き込み  読み込み要求   読み...
Cache戦略の考え方 Cache方式   Cache対象レイヤリードスルー     カラムレベルライトスルー     レコードレベル変則ライトスルー   ドメインレベル  (1)(2)   サービスレベル
Cache戦略の考え方 Cache方式   Cache対象レイヤリードスルー     カラムレベルライトスルー     レコードレベル変則ライトスルー   ドメインレベル  (1)(2)   サービスレベル
カラム単位キャッシュデータ保存の最小単位/粒度最小                         id   名前      年齢user:1:name   大野         1    大野          29             ...
行単位キャッシュレコード単位でキャッシュ                       id    名前        年齢user:1 {name:”大野”,     1     大野        29          age:29}   ...
粒度と意味行単位でキャッシュする分には代替できるケースが多い。ホットスポットを分析して、キャッシュの粒度は意味に依存するほうがよい
ドメイン単位のキャッシュ一つのモデル領域でデータを保存            Userid                       名前        年齢user:1   {                          1    大...
サービス単位複数のドメイン領域で横断的にデータを保持                 Us                 日記サービスid                        1                        2  ...
粒度と抽象化           View/Controller                                       Cacheポイント                  Service      Model1     ...
memcached揮発するKVSキャッシュ以外の使い方
リリース時/復旧時にオペレータが制御リリースと暖めと アクティベーション                                                                    write             ...
memcached以外のcache cacheの種類       CPAN Module                        備考                                         ketamaが実装され...
memcached以外のcache cacheの種類       CPAN Module                        備考                                         ketamaが実装され...
コードの複雑さを防ぐキレイなコードが必要になる瞬間。今そこにある危機にmixiが取り組んでいること
Model/                         Social Graph Service              Diary       Voice       Calendar         Check       PC向け...
Profile                   Customer                    Support      Diary                       Calendar     News     Social...
凝集度             結合度 1つの責任対してモジュールのカバー モジュールのカバーしている責任が、 している範囲が広いか、狭いか。    どの程度結合しているか。 高いほうが良い。           低いほうが良い。凝集度を高く結...
コンポーネント間の連携を定義する原則• ADP (The Acyclic Dependencies Principle)   – 非循環依存の法則• REP(Release Reuse Equivalency Principle)   – 再利...
システムコンポーネント  抽象度/安定度                    基礎ライブラリ       高                            use                             フレームワーク...
システムコンポーネントコンポーネント横断で利用できるAPIを制限するJobQueueサーバを利用してユーザの行動をフック 個別のアプリケーション の機能を他のアプリケーションから     サービス 利用する方法を制限して、 アプリケーション毎の...
仲介者を通じて公開APIを定義                                        Apps        Apps                 Apps Apps                    Apps ...
Broker(内部Procedure)コンポーネント横断で利用できるAPIを制限する  --- diary.yaml  getEntityTitle : Diary::Adapter::Entity  getEntity      : Diar...
JobQueueの使いどころシェーピング 突発的な負荷を緩衝して、スパイクを避けるJoinの代替   論理/物理 複数ソースにまたがっている関連情報を一貫させる副次的な要件の処理 異なる責務領域で必要になる処理
JobQueueのシステム構成 Job  Job WorkerWorkerWorker   WorkerWorkerWorker   WorkerWorkerWorker   WorkerWorkerWorker      Q4M       ...
JobQueueでPub-Sub副次的要件の処理                        sub   add_diary {                              # 本来的な処理 sub   add_diary { ...
Publisher-SubscriberBrokerの一種で、1つのトピックに                               健全化系モジュール処理複数のサブスクライバが存在し                      Subsc...
ModelのCRUDにフック アプリケーション外から シンプルに見えるように  Create  Read  Update  Delete個別コードの事情や構成に詳しくなくても利用できる
CRUDを捕捉したサービスUs                                                                     赤文字のようにシステム日記     id        1        2...
まとめ2つのスケーラビリティアクセスに耐える構成/機能追加に耐える構成両方とも最終的には似てくる。責務の分散構成≒負荷の分散構成早く(速く)実装したければキレイに書く設計の負債、ご利用は計画的に。
このひとを探しています。      http://career.mixi.co.jp/
ご清聴ありがとうございました
YAPC::Asia 2010 Inside Mixi
YAPC::Asia 2010 Inside Mixi
Upcoming SlideShare
Loading in …5
×

YAPC::Asia 2010 Inside Mixi

5,925 views
5,811 views

Published on

mixi内部でのアプリケーションアーキテクチャ。複雑な依存、多人数開発、パフォーマンスを両立するためにどのようにアプリケーションを構成しているか。その考え方を紹介します。Perlという軽量言語で如何にコンポーネント凝集などを考えるかという珍しいテーマだと思います。

Published in: Technology, Business
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,925
On SlideShare
0
From Embeds
0
Number of Embeds
2,083
Actions
Shares
0
Downloads
53
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • YAPC::Asia 2010 Inside Mixi

    1. 1. inside mixiソーシャルネットワークを支える技術 Daichi Hiroki
    2. 2. 廣木 大地(@hiroki_daichi)株式会社mixiシステム本部技術部たんぽぽ開発G 刺身にたんぽぽを乗せる仕事を無くす部隊 火を消したり、火の用心の見回りしたりする2008年新卒入社 アプリケーションアーキテクチャ 広告関連/技術教育/JavaScript開発支援など
    3. 3. Social Graph Diary Voice Calendar CheckPC向け スマートフォン向け フィーチャフォン向け API Servicemixiについて多様なデバイスに多様なサービスを2102万ユーザ(1430万)、297.7億PV/月 (2010/7)
    4. 4. mixi 2004development歴史の長いコード機能間連携多い 2010同一のコードベース開発者数増 ついにメガプログラミングに
    5. 5. 2つのスケーラビリティ
    6. 6. 2つのスケーラビリティPerformance : アクセス数の増加や変動に耐えるDevelopment : 機能追加や多人数開発に耐える
    7. 7. memcached揮発するKVS汎用キャッシュLRU
    8. 8. Cacheとは? Cache DataSource更新に対して参照が多いデータの参照を高速に いつ、キャッシュにいれるか、更新されるか なにを、キャッシュにいれるか データ参照のホットスポットを発見して適応
    9. 9. 通常データ 参照量の多い共通データ write write 複数台に同時書き込みkeyからketamaで一意のノードから読み書き プロセスごとに異なるノードに問い合わせ read read read
    10. 10. Cache戦略の考え方 Cache方式 Cache対象レイヤリードスルー カラムレベルライトスルー レコードレベル変則ライトスルー ドメインレベル (1)(2) サービスレベル
    11. 11. Cache戦略の考え方 Cache方式 Cache対象レイヤリードスルー カラムレベルライトスルー レコードレベル変則ライトスルー ドメインレベル (1)(2) サービスレベル
    12. 12. リードスルー読み込み時にキャッシュに追加 client memcached data source 読み込み要求 キャッシュ問い合わせ キャッシュから 特徴: データソース問い合わせ 実装が簡単。 Aspect 戻り値をキャッシュに保存 Moose::Role ソースから Class::Method::Modifier などで関数に透過的に 実装できる。更新時に 書き込み要求 複数の読み込みの キャッシュ削除 問い合わせがデータ データソース更新 ソースにいく可能性アリ
    13. 13. ライトスルー書き込み時にキャッシュに書き込む client memcached data source 書き込み時 キャッシュ書き込み データソース書き込み 読み込み要求 読み込み時は、リードスルーと同様の実装 特徴:書き込み粒度と読み込み粒度を一致させる必要がある。 共通リソースへの同時書き込みがほぼないデータに有効 キャッシュが存在しない期間がほぼ無い
    14. 14. 変則ライトスルー(1)DBに書き込んでから、マスターを読み出す client memcached data source 書き込み時 データソース書き込み データソース読み込み キャッシュデータ書き込み 読み込み要求 読み込み時は、リードスルーと同様の実装 特徴:書き込み粒度と読み込み粒度を一致させる必要が無い Master/Slave構成のDBの場合、Masterで読み書きの必要 キャッシュが存在しない期間がほぼ無い 社内オペレーションで操作する共通データなど
    15. 15. 変則ライトスルー(2)incrをうまく使い数を管理する client memcached data source 書き込み時 incr命令で加算する データソース書き込み 読み込み要求 読み込み時は、リードスルーと同様の実装 特徴:とりあつかえるのは数量のみ(select countの結果など) キャッシュが存在しない期間がほぼ無い
    16. 16. Cache戦略の考え方 Cache方式 Cache対象レイヤリードスルー カラムレベルライトスルー レコードレベル変則ライトスルー ドメインレベル (1)(2) サービスレベル
    17. 17. Cache戦略の考え方 Cache方式 Cache対象レイヤリードスルー カラムレベルライトスルー レコードレベル変則ライトスルー ドメインレベル (1)(2) サービスレベル
    18. 18. カラム単位キャッシュデータ保存の最小単位/粒度最小 id 名前 年齢user:1:name 大野 1 大野 29 2 櫻井 28 3 二宮 27特徴: 削除タイミング:個別に参照頻度が高いデータ。 該当カラムが更新get_multiなどで必要なカラムを収 データソース系モジュールで削除集して柔軟に使いたいケース。set_by_keyなど使えると局所性もコントロールできて高速に。
    19. 19. 行単位キャッシュレコード単位でキャッシュ id 名前 年齢user:1 {name:”大野”, 1 大野 29 age:29} 2 櫻井 28 3 二宮 27特徴: 削除タイミング:個別に参照頻度が高いテーブル 該当レコードが更新カラム追加できない状況だと、 データソース系モジュールで削除仕様変更に弱い
    20. 20. 粒度と意味行単位でキャッシュする分には代替できるケースが多い。ホットスポットを分析して、キャッシュの粒度は意味に依存するほうがよい
    21. 21. ドメイン単位のキャッシュ一つのモデル領域でデータを保存 Userid 名前 年齢user:1 { 1 大野 29  name:”大野”, 2 櫻井 28  age:29, 3 二宮 27  program:  [{id:1,’歌のおにいさん’}, id owner_id 出演作品  {id:2,”怪物くん”}] 1 大野(1) 歌のおにいさん } 2 大野(1) 怪物くん 3 二宮(3) フリーター家をかう特徴: 更新タイミング: サービス上のモデル分析の 該当エンティティが更新 妥当性が重要。 モデル管理モジュールで更新 大きすぎる粒度に注意。 その範囲では仕様変更につよい
    22. 22. サービス単位複数のドメイン領域で横断的にデータを保持 Us 日記サービスid 1 2 3 名前 大野 櫻井 年齢 29 28 27history:1 二宮 id owner_id 出演作品 1 大野(1) 歌のおにいさん 2 大野(1) 怪物くん Us 3 二宮(3) フリーター家を ユーザデータid 1 2 3 名前 大野 櫻井 年齢 29 28 27 二宮アプリケーション単位の id 1 owner_id 大野(1) 出演作品 歌のおにいさん 2 大野(1) 怪物くん表示、リストデータなど Us 3 二宮(3) フリーター家を 通知履歴 id 1 2 3 名前 大野 櫻井 年齢 29 28 27 二宮 id owner_id 出演作品 1 大野(1) 歌のおにいさん 2 大野(1) 怪物くん 3 二宮(3) フリーター家を特徴: 削除タイミング:参照データ頻度が大きく Expireのみを期待する。キャッシュやDBを複数個経由 ドメインごとの更新タイミングにして出来上がるデータ。 フックポイントを仕込む(後述)削除タイミングが難しい
    23. 23. 粒度と抽象化 View/Controller Cacheポイント Service Model1 Model2 DB1 KVS DB1 Web API アクセス数や更新頻度に応じて適切に選択 http://blog.nomadscafe.jp/2010/08/re-kazuho-handlersocket-plugin-mycached-memcached-10.html
    24. 24. memcached揮発するKVSキャッシュ以外の使い方
    25. 25. リリース時/復旧時にオペレータが制御リリースと暖めと アクティベーション write read read service [追加時刻,回復時間] アプリケーション側でユーザ毎に 有効かどうかを計算 キャッシュヒーティング100 決まった時間で線形にユーザの有効率を キャッシュ搭載率 有効ユーザ数 あげていき、DB負荷を安定稼働状態まで 75 DB負荷 キャッシュをあたためさせる。 50 25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
    26. 26. memcached以外のcache cacheの種類 CPAN Module 備考 ketamaが実装されるのが デーモン Cache::Memcached::Fast 早かった mixiでは未使用/ プロセス間 Cache::Swifty/TC Coherencyを保つの面倒 memcachedコネクション プロセス内 Class::Data (Inheritable) 一部memoizeとして DBコネクション/ リクエスト mod_perl2 pnotes Singleton/Flyweight/ memcached戻り値 スコープ内 Scope::Session script/plack/job worker
    27. 27. memcached以外のcache cacheの種類 CPAN Module 備考 ketamaが実装されるのが デーモン Cache::Memcached::Fast 早かった mixiでは未使用/ プロセス間 Cache::Swifty/TC Coherencyを保つの面倒 memcachedコネクション プロセス内 Class::Data (Inheritable) 一部memoizeとして DBコネクション/ リクエスト キャッシュ値が一時的 Singleton/Flyweight/ mod_perl2 pnotes memcached戻り値 にずれるのを許容 スコープ内 Scope::Session script/plack/job worker
    28. 28. コードの複雑さを防ぐキレイなコードが必要になる瞬間。今そこにある危機にmixiが取り組んでいること
    29. 29. Model/ Social Graph Service Diary Voice Calendar Check PC向け スマートフォン向け フィーチャフォン向け API Service View/Controller
    30. 30. Profile Customer Support Diary Calendar News Social Graph複雑に各コンポーネントが依存し合うサービス要件 Check Voice Ad / Analysis API Service Home
    31. 31. 凝集度 結合度 1つの責任対してモジュールのカバー モジュールのカバーしている責任が、 している範囲が広いか、狭いか。 どの程度結合しているか。 高いほうが良い。 低いほうが良い。凝集度を高く結合度を低く保つためのアーキテクチャ 凝集度の低い状態 結合度の高い状態 モジュール モジュール モジュール モジュール
    32. 32. コンポーネント間の連携を定義する原則• ADP (The Acyclic Dependencies Principle) – 非循環依存の法則• REP(Release Reuse Equivalency Principle) – 再利用・リリース等価原則• SDP(The Stable Dependencies Principle ) – 安定依存原則• SAP(The Stable Abstractions Principle ) – 安定度抽象度等価原則• CRP(The Common Reuse Principle ) – 全再利用原則• CCP(The Common Closure Principle) – 閉鎖性共通原則
    33. 33. システムコンポーネント 抽象度/安定度 基礎ライブラリ 高 use フレームワーク 低 useコンポーネントの機能単位の特徴から依存関係や用途などを サービス決める。 use use use use依存性が広範囲で再帰的に register/callなる状態を避け、影響範囲を限定的にする。 アプリケーション アプリケーション
    34. 34. システムコンポーネントコンポーネント横断で利用できるAPIを制限するJobQueueサーバを利用してユーザの行動をフック 個別のアプリケーション の機能を他のアプリケーションから サービス 利用する方法を制限して、 アプリケーション毎の清潔さを保つ register/call アプリケーション アプリケーション
    35. 35. 仲介者を通じて公開APIを定義 Apps Apps Apps Apps Apps Broker Apps Resource File Apps Appsすべてのモジュールの公開メソッド BrokerにおしえたAPIだけ保守すれを保守する必要がある ばよい。O(n)個のAPInamespaceが別途ある言語なら、public interfaceと同義
    36. 36. Broker(内部Procedure)コンポーネント横断で利用できるAPIを制限する --- diary.yaml getEntityTitle : Diary::Adapter::Entity getEntity : Diary::Adapter::Entity createFeedback : Diary::Adapter::Feedback登録したAPIはそれを構成するモジュールよりも安定させる。
    37. 37. JobQueueの使いどころシェーピング 突発的な負荷を緩衝して、スパイクを避けるJoinの代替 論理/物理 複数ソースにまたがっている関連情報を一貫させる副次的な要件の処理 異なる責務領域で必要になる処理
    38. 38. JobQueueのシステム構成 Job Job WorkerWorkerWorker WorkerWorkerWorker WorkerWorkerWorker WorkerWorkerWorker Q4M Q4M Q4M Q4M Job Job WebServer WebServer WebServer
    39. 39. JobQueueでPub-Sub副次的要件の処理 sub add_diary { # 本来的な処理 sub add_diary { 日記作成イベントの発火 } # 本来的な処理 健全化系モジュール処理 JobQueue経由で 関連要件を実行 ニュース系処理 健全化系モジュール処理 広告系処理 ニュース系処理 サービスキャッシュ削除 } 広告系処理 サービスキャッシュ削除単純な処理に対して、複数の関連する要件が 積み重なりコードが肥大化しやすい
    40. 40. Publisher-SubscriberBrokerの一種で、1つのトピックに 健全化系モジュール処理複数のサブスクライバが存在し Subscriberそれぞれを知らずに責務を果たす ニュース系処理 Subscriber 日記作成イベント Publisher Topic 広告系処理 Subscriber サービスキャッシュ削除 Subscriber
    41. 41. ModelのCRUDにフック アプリケーション外から シンプルに見えるように Create Read Update Delete個別コードの事情や構成に詳しくなくても利用できる
    42. 42. CRUDを捕捉したサービスUs 赤文字のようにシステム日記 id 1 2 名前 大野 櫻井 年齢 29 28 日記コメント 3 二宮 27 横断的に利用されるものも id 1 owner_id 大野(1) 出演作品 歌のおにいさん 日記イイネ!削除 2 3 大野(1) 二宮(3) 怪物くん フリーター家を それぞれのアプリケーション Us のCRUDを捕捉できれば、Usフォト 赤文字通知 id 名前 年齢 id 名前 年齢 1 2 大野 櫻井 29 28 1 2 大野 櫻井 29 28 高い粒度のキャッシュを 3 二宮 27 3 二宮 27 id 1 owner_id 大野(1) 出演作品 歌のおにいさん id 1 owner_id 大野(1) 出演作品 歌のおにいさん シンプルに実現できる。 2 大野(1) 怪物くん 2 大野(1) 怪物くん 3 二宮(3) フリーター家を 3 二宮(3) フリーター家をUs 通知用DB書き込みカレンダー id 名前 年齢 1 大野 29 2 櫻井 28 3 27 id 二宮 owner_id 出演作品 通知用サービスキャッシュ 1 大野(1) 歌のおにいさん 2 大野(1) 怪物くん 3 二宮(3) フリーター家を 通知用サービスキャッシュクリアUs 通知用DB更新ボイス id 1 2 名前 大野 櫻井 年齢 29 28 3 二宮 27 id owner_id 出演作品 1 大野(1) 歌のおにいさん 2 大野(1) 怪物くん 3 二宮(3) フリーター家を
    43. 43. まとめ2つのスケーラビリティアクセスに耐える構成/機能追加に耐える構成両方とも最終的には似てくる。責務の分散構成≒負荷の分散構成早く(速く)実装したければキレイに書く設計の負債、ご利用は計画的に。
    44. 44. このひとを探しています。 http://career.mixi.co.jp/
    45. 45. ご清聴ありがとうございました

    ×