Aiming飲み会 1-rails におけるコネクション数とシャーディングのお話
-
Upload
hidenori-doi -
Category
Software
-
view
833 -
download
0
Transcript of Aiming飲み会 1-rails におけるコネクション数とシャーディングのお話
Rails におけるコネクション数と シャーディングのお話
株式会社 Aiming エンジニア 土井 英範
About: 土井 英範• 株式会社 Aiming 開発グループマネージャーリードソフトウェアエンジニア
• エンジニアになって10年弱 • かかわったゲームタイトル4本くらいクライアントからサーバまで全般を経験してきた
• コンシューマゲーム、ブラウザゲーム、スマホのゲーム
• サーバ・クライアントプログラム
Rubyist 編
Active Record
水平分割したい
水平分割したい
•際限なく増えていくレコード •インデックスサイズの増加 •ユーザー増加に伴うクエリ回数の増加 •クエリ性能の低下
User Table
User Table 1 User Table 2 User Table 3
分割基準 Range (ID: 1~100, 101~200 …)List (CountryCode: JP, US …) Hash ( ID mod 3 )
一つのテーブルを特定のルールで 複数のDBに分散する
↓分割↓
Q. ActiveRecord で水平分割ってできるの?
A. 一筋縄にはいかない
Active Record のコネクションスイッチング
•establish_connection というメソッドがありますが
•能動的に接続を確立するためのものではなく実際の接続は行わない
• 指定されたクラスをキーに (クラス・メソッド) コネクションプールを作成するだけのもの
establish_connection の挙動
•クラス定義の段階で指定するためスイッチングの用途に使えない
•安直に呼び出して切り替えるのも危険
class User < ActiveRecord::Base establish_connection :user_db # database.yml で定義されているとする … end
水平分割するためのGem があります
水平分割に利用できる Gem
•octopus • https://github.com/tchandy/octopus • 昔ある有名な Gem • @user = User.using(:shard1).find_by_name(“Joao") • こんな書き方ができる
水平分割に利用できる Gem
•ActiveRecord::Turntable • https://github.com/drecom/activerecord-turntable • 高機能 •シャード間で ActiveRecord の id をキーとして分散できる •自動的にどのシャードでクエリを投げる必要があるかを解決してくれる
水平分割に利用できる Gem
•Sengiri • https://github.com/mewlist/sengiri • ActiveRecordの挙動にあまり手をいれない作り •低機能、シンプル •土井の自作
ActiveRecord とコネクション数の話
too many connections
見積もり方法
•プロセスベースのサーバならスレッド数は 基本 1 •※コード内に Ruby スレッド処理などがない前提 • Passenger ※Enterprise版だと Thread モデルも可能らしい • Unicorn
• スレッドベースのサーバ • Puma (ワーカープロセスも複数設定できる)
見積もり方法
•サーバ台数 x プロセス数 x スレッド数 • 20台 x 5 process x 2 thread • = 200 connection
その他
•管理ツールからのコネクション •バッチ処理・キュー処理からのコネクション
•これらも忘れずに接続数として見積もっておく
database.yml•pool: 5 •プールサイズの設定はスレッドを利用する際の設定
• unicorn, passenger などのプロセスベースのサーバだと1 process に付き 1 connection
水平分割した時の話
•Multi-DB アクセスする場合 •基本的に全てのDBにコネクションが張られると考えたほうが良い
• 5分割したら5つのDBに接続を張る可能性がある •各 Gem でどのような実装になっているかは未確認 •※Sengiriはつなぎっぱなしになっちゃいます
DB1 DB2 DB3 DB4 DB5
イメージweb web
admin bat
コネクション数が増加すると
•MySQLの場合 • http://dev.mysql.com/doc/refman/5.6/ja/thread-pool-plugin.html
http://www.oracle.com/technetwork/jp/ondemand/database/mysql/mysql-perftun-1484759-ja.pdf
コネクションプーリングの回避
•activerecord-refresh_connection • https://github.com/sonots/activerecord-refresh_connection
•ardisconnector • https://github.com/mewlist/ardisconnector • 自作 sengiri と連動
コネクションは切断したほうが良いか?
•結論 • RDB側のスレッドプーリングが使えるならコネクション数の増加については気にする必要は無いのかもしれない
•最大コネクション数は上限を常に意識した設定を行う