Mobage を支える Ruby の技術 ~ 複数DB編 ~
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Mobage を支える Ruby の技術 ~ 複数DB編 ~

on

  • 245 views

 

Statistics

Views

Total Views
245
Views on SlideShare
55
Embed Views
190

Actions

Likes
0
Downloads
2
Comments
0

4 Embeds 190

http://blog.livedoor.jp 217
http://feedly.com 1
http://news.google.com 1
http://getpocket.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Mobage を支える Ruby の技術 ~ 複数DB編 ~ Presentation Transcript

  • 1. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Mobageを支える Rubyの技術 ~ 複数DB編 ~ November 11th, 2014 ! Naotoshi Seo @sonots DeNA Co., Ltd.
  • 2. 2 自己紹介 ・瀬尾 直利 @sonots ・DeNA, Co., Ltd ・インフラの Dev ・Rubyist ・OSS 活動家 ・Fluentd コミッタ Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 3. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 背景 3 ! Perl の会社と名高いこの DeNA でも Ruby (on Rails) のプロジェクトが立ち 上がり始めている
  • 4. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. インフラ要件の壁 4 ! • ホットデプロイ • カスタムフォーマットのロガー • デプロイサーバでビルドした gem を web サーバにアプリコードと共に撒く • 社内 rubygems ミラー • Q4M 非同期ジョブキュー • プロファイリングツール、調査ツール
  • 5. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 複数DB対応 5 ! • Rails で複数DBに対応する必要性 • 冗長化・高速化 • 既存のインフラの仕組みにのっかる必要性 • 今回はここに特化した話
  • 6. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 目次 6 ! • DB接続を都度接続に • クライアントサイドDNSキャッシュ • DBパスワード一元管理 • DBスキーマ一元管理ツール • 複数DB対応
  • 7. DB接続を都度接続にすべし 7 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 要件1
  • 8. DeNAでの複数DB構成 8 ! • MySQL: Master/Slave • DNSラウンドロビンでSlaveを振り分ける • MHA で Master の高可用化 • DNS サーバには MyDNS を使用 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 9. Slave参照: DNSラウンドロビン MySQL Slave 1 MySQL Slave 2 MySQL Slave 3 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. | id | zone | name | data | aux | |----|------|----------|----------|-----| | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 10.1.1.2 sample_r 1回目 2回目
  • 10. Slave参照: 永続接続 MySQL Slave 1 MySQL Slave 2 MySQL Slave 3 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. | id | zone | name | data | aux | |----|------|----------|----------|-----| | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 2回目 ずっとココ!! ダメ!
  • 11. Slave参照: 都度接続 MySQL Slave 1 MySQL Slave 2 MySQL Slave 3 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. | id | zone | name | data | aux | |----|------|----------|----------|-----| | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 1/3 の確率 sample_r 10.1.1.3 2回目 Good
  • 12. MySQL Master 1 MySQL Slave 2 MySQL Slave 3 10.1.1.1 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 sample_w MHA | id | zone | name | data | aux | |----|------|----------|----------|-----| | 1 | 1 | sample_w | 10.1.1.1 | 100 | | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MySQL Slave 1
  • 13. MySQL Master 1 MySQL Slave 2 MySQL Slave 3 10.1.1.1 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 sample_w MHA | id | zone | name | data | aux | |----|------|----------|----------|-----| | 1 | 1 | sample_w | 10.1.1.1 | 100 | | 2 | 1 | sample_w | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MySQL Master 2 再接続 or 都度接続
  • 14. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. DBを再起動 Web DB restart 再接続 or 都度接続 ※ ただし、ActiveRecord の reconnect は正しく動かなかったり ※ そのため、アプリの再起動が必要だったりして、ツライ
  • 15. Slaveダウン検知(check_slave) | id | zone | name | data | aux | |----|------|----------|----------|-----| | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MySQL Slave 1 MySQL Slave 2 MySQL Slave 3 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 sample_r 10.1.1.3 再接続 or 都度接続
  • 16. すべて都度接続で解決 16 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 17. しかしActiveRecord には都度接続オプションがない 17 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 18. 18 なんだってーーーΩΩΩ Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 19. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 作りました 19
  • 20. activerecord-refresh_ connection 20 Rack レイヤーでリクエスト毎に接続を切るやつ 1行追加でおk # config/application.rb class Application < Rails::Application config.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement, "ActiveRecord::ConnectionAdapters::RefreshConnectionManagement" Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. end https://github.com/sonots/activerecord-refresh_connection http://blog.livedoor.jp/sonots/archives/38797925.html
  • 21. クライアントDNSキャッシュ 21 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 要件2
  • 22. クライアントDNSキャッシュ 22 ! • ruby 実装 • キャッシュしないと名前解決遅い • 重み0なmasterへのfallback Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 23. DNSキャッシュ MySQL Master 1 MySQL Slave 1 MySQL Slave 2 MySQL Slave 3 10.1.1.1 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. | id | zone | name | data | aux | |----|------|----------|----------|-----| | 1 | 1 | sample_w | 10.1.1.1 | 100 | | 2 | 1 | sample_r | 10.1.1.2 | 100 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 テーブルを select キャッシュ 10.1.1.2 ファイルに落とす
  • 24. MySQL Master 2 MySQL Slave 2 MySQL Slave 3 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. MyDNS Web 10.1.1.2 10.1.1.3 10.1.1.4 重み0へのfallback | id | zone | name | data | aux | |----|------|----------|----------|-----| | 1 | 1 | sample_w | 10.1.1.1 | 100 | | 2 | 1 | sample_w | 10.1.1.2 | 0 | | 3 | 1 | sample_r | 10.1.1.3 | 100 | | 4 | 1 | sample_r | 10.1.1.4 | 100 | MySQL Master 1 10.1.1.1 weight:100 weight: 0 DNSプロトコルで引くと重み0のエントリが見えない。 Unbound などのDNSキャッシュを使えない。
  • 25. ResolverMyDNS 25 MyDNSのテーブルエントリをクライアントサイド でキャッシュして名前解決するやつ resolver = ResolverMyDNS.new( zone: 'mobage.local',! cache_dir: "cache_dir/",! host: 'localhost',! username: 'root',! passowrd: nil,! database: 'mydns',! )! resolver.get_server 'foo.mobage.local' #=> 10.1.1.10 @Spring_MT Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 26. 26 これアプリコード内でIPアドレス取得 して establish_connection に渡 す必要あるけど、めんどいよね? @ryopeko Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. そうすな~
  • 27. ResolverReplace 27 resolver = ResolverMyDNS.new(...)! # Resolver を resolver_mydns にすげかえる! ResolverReplace.load_plugin('mysql2')! ResolverReplace.register!(! getaddress: resolver.method(&:get_server),! getaddresses: resolver.method(:get_server_list),! error_class: ResolverMyDNS::Error,! ) Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Rubyの名前解決を挿げ替えるやつ https://github.com/sonots/resolver_replace
  • 28. ResolverReplace 28 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. ! • ぶっちゃけると ruby が持っている resolv-replace のパクリ • resolv-replace は ruby の名前解決を libc から ResolvDNS クラスに置き換え るやつ • 任意のクラスに置き換えられるように拡張
  • 29. ResolverReplace は OSS になってる https://github.com/sonots/resolver_replace ResolverMyDNS 欲しい人??? 29 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 30. DBパスワード管理 30 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 要件3
  • 31. DeNAでのDBパスワード管理 31 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. ! • yaml で一元管理(インフラ管理. アプリ毎に管 理させない) • DBIx::DBHResolver という perl モジュール を通して取得する • stage, sandbox など環境毎にパスワードが違 うが、同じコードで取得できる
  • 32. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. dbhresolver 32 ! • 既存の yaml を処理して ActiveRecord が受け 取る形式で吐き出してくれる ruby gem production: <<: *default <%= dbh.connect_spec('SAMPLE_R') %> sample_r_production: <<: *default <%= dbh.connect_spec('SAMPLE_R') %> sample_w_production: <<: *default <%= dbh.connect_spec('SAMPLE_W') %>
  • 33. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. マイグレーション 33 要件4
  • 34. DeNAでのスキーマ管理 34 Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. ! • git レポジトリで一元管理(インフラ管理. アプリ 毎に管理させない) • SQL::Translator::Diff という perl モ ジュールを使って実際のDBスキーマとの diff を とった alter 文を作ってもらいマイグレーション • ruby である必要はないのでそのまま利用
  • 35. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 複数DB接続 35 要件5
  • 36. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 複数DB接続 36 要件5
  • 37. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 複数DB接続 37 ! • read/write 用モデルそれぞれ作ってゴ リゴリ実装することもできる • が、良い仕組みを使って実装を楽にしたい
  • 38. 38 ク社どうやってるの? octopus辛みありそう... switch_pointという のがあってだな@sora_h Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 39. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. 完全に実用段階!!! 39 SwitchPoint 詳しくはeagletmt先生の資料をご参照ください
  • 40. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. SwitchPoint 40 SwitchPoint.configure do |config| config.define_switch_point :db1, readable: :db1_readonly, writable: :db1_writable, config.define_switch_point :db2, readonly: :db2_readonly end class Book1 < ActiveRecord::Base use_switch_point :db1 end class Book2 < ActiveRecord::Base use_switch_point :db2 end https://github.com/eagletmt/switch_point
  • 41. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. Adminsbar 41 http://admins.bar/3/
  • 42. まとめ ~ 複数DB編 ~ 42 ! • DB接続を都度接続に • activerecord_refresh_connection • クライアントサイドDNSキャッシュ • resolver_mydns / resolver_replace • DBパスワード一元管理 • DBスキーマ一元管理ツール • 複数DB対応 • switch_point Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 43. その他インフラ要件の壁 43 ! • ホットデプロイ • カスタムフォーマットのロガー • デプロイサーバでビルドした gem を web サーバにアプリコードと共に撒く • 社内 rubygems ミラー • Q4M 非同期ジョブ • プロファイリングツール、調査ツール Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
  • 44. Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved. We're hiring!! 44