Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Mobageを支える
November 11th, 2014
!
Naotoshi Seo @sonots

DeNA Co., Ltd.
Rubyの技術
~複数DB編~
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
2
自己紹介
・瀬尾 直利 @sonots
・DeNA, Co., Ltd
・インフラの Dev
・Rubyist
・OSS 活動家
・Fluentd コミッタ
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
背景
3
!
Perl の会社と名高いこの DeNA でも
Ruby (on Rails) のプロジェクトが立ち
上がり始めている
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
インフラ要件の壁
4
!
• ホットデプロイ
• カスタムフォーマットのロガー
• デプロイサーバでビルドした gem を web
サーバにアプリコードと共に撒く
• 社内 rubygems ミラー
• Q4M 非同期ジョブキュー
• プロファイリングツール、調査ツール
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
複数DB対応
5
!
• Rails で複数DBに対応する必要性
• 冗長化・高速化
• 既存のインフラの仕組みにのっかる必要性
• 今回はここに特化した話
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
目次
6
!
• DB接続を都度接続に
• クライアントサイドDNSキャッシュ
• DBパスワード一元管理
• DBスキーマ一元管理ツール
• 複数DB接続
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DB接続を都度接続にすべし
7
要件1
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DeNAでの複数DB構成
8
!
• MySQL: Master/Slave
• DNSラウンドロビンでSlaveを振り分ける
• MHA で Master の高可用化
• DNS サーバには MyDNS を使用
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 1
MySQL
Slave 2
MySQL
Slave 3
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.4
10.1.1.2
sample_r
1回目
| 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 |
2回目
Slave参照: DNSラウンドロビン
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 1
MySQL
Slave 2
MySQL
Slave 3
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.4
2回目
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 |
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 1
MySQL
Slave 2
MySQL
Slave 3
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.4
10.1.1.3sample_r
2回目
Slave参照: 都度接続
1/3 の確率
| 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 |
Good
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 2
MySQL
Slave 3
MySQL
Master 1
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.1
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
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 2
MySQL
Slave 3
MySQL
Master 1
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.1
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
都度接続
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DBWeb
DBを再起動
restart
再接続 or
都度接続
※ ただし、ActiveRecord の reconnect は正しく動かなかったり
※ そのため、アプリの再起動が必要だったりして、ツライ
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 1
MySQL
Slave 2
MySQL
Slave 3
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.4
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 |
10.1.1.3sample_r
再接続 or
都度接続
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
すべて都度接続で解決
16
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
しかしActiveRecord
には都度接続オプションがない
17
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
18
なんだってーーーΩΩΩ
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
作りました
19
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
activerecord-
refresh_connection
20
Rack レイヤーでリクエスト毎に接続を切るやつ
1行追加でおk
# config/application.rb
class Application < Rails::Application
config.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement,
"ActiveRecord::ConnectionAdapters::RefreshConnectionManagement"
end
https://github.com/sonots/activerecord-refresh_connection
http://blog.livedoor.jp/sonots/archives/38797925.html
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
クライアントDNSキャッシュ
21
要件2
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
クライアントDNSキャッシュ
22
!
• ruby 実装
• キャッシュしないと名前解決遅い
• 重み0なmasterへのfallback
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Slave 1
MySQL
Slave 2
MySQL
Slave 3
MySQL
Master 1
MyDNS
Web
10.1.1.2
10.1.1.3
10.1.1.1
10.1.1.4
テーブルを
キャッシュ
select
DNSキャッシュ
| 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 |
10.1.1.2
ファイルに落とす
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
MySQL
Master 2
MySQL
Slave 2
MySQL
Slave 3
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キャッシュを使えない。
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
ResolverMyDNS
25
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
MyDNSのテーブルエントリをクライアントサイド
でキャッシュして名前解決するやつ
@Spring_MT
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
26
@ryopeko
これアプリコード内でIPアドレス取得
して establish_connection に渡
す必要あるけど、めんどいよね?
そうすな∼
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
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,!
)
Rubyの名前解決を挿げ替えるやつ
https://github.com/sonots/resolver_replace
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
ResolverReplace
28
!
• ぶっちゃけると ruby が持っている
resolv-replace のパクリ
• resolv-replace は ruby の名前解決を
libc から Resolv クラスに置き換えるやつ
• 任意のクラスに置き換えられるように拡張
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
ResolverMyDNS
欲しい人???
29
ResolverReplace は
OSS になってる
https://github.com/sonots/resolver_replace
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DBパスワード管理
30
要件3
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DeNAでのDBパスワード管理
31
!
• yaml で一元管理(インフラ管理. アプリ毎に管
理させない)
• DBIx::DBHResolver という perl モジュール
を通して取得する
• stage, sandbox など環境毎にパスワードが違
うが、同じコードで取得できる
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') %>
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
マイグレーション
33
要件4
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
DeNAでのスキーマ管理
34
!
• git レポジトリで一元管理(インフラ管理. アプリ
毎に管理させない)
• SQL::Translator::Diff という perl モ
ジュールを使って実際のDBスキーマとの diff を
とった alter 文を作ってもらいマイグレーション
• ruby である必要はないのでそのまま利用
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
複数DB接続
35
要件5
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
複数DB接続
36
!
• read/write 用モデルそれぞれ作ってゴ
リゴリ実装することもできる
• が、良い仕組みを使って実装を楽にしたい
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
37
ク社どうやってるの?
octopus辛みありそう...
switch_pointという
のがあってだな @sora_h
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
完全に実用段階!!!
38
SwitchPoint
詳しくはeagletmt先生の資料をご参照ください
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
SwitchPoint
39
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
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
Adminsbar
40
http://admins.bar/3/
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
まとめ 複数DB編
41
!
• DB接続を都度接続に
• activerecord_refresh_connection
• クライアントサイドDNSキャッシュ
• resolver_mydns / resolver_replace
• DBパスワード一元管理
• DBスキーマ一元管理ツール
• 複数DB対応
• switch_point
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
その他インフラ要件の壁
42
!
• ホットデプロイ
• カスタムフォーマットのロガー
• デプロイサーバでビルドした gem を web
サーバにアプリコードと共に撒く
• 社内 rubygems ミラー
• Q4M 非同期ジョブ
• プロファイリングツール、調査ツール
Copyright (C) 2014 DeNA Co.,Ltd. All Rights Reserved.
We're hiring!!
43

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

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