Download - Handlersocket etc. 20110906
HandlerSocket HandlerSocket について について + α+ α
2011/09/06 tokyoLinuxStudy #32011/09/06 tokyoLinuxStudy #3 @@ 四谷 四谷
株式会社ディー・エヌ・エー システム統括本部 株式会社ディー・エヌ・エー システム統括本部 ITIT 基盤部基盤部樋口 証樋口 証
HandlerSocket pluginHandlerSocket plugin とはとは
MySQLMySQL のの NoSQLNoSQL なインタフェーなインタフェースス
○ ○ NoSQLNoSQL× NoRDB× NoRDB
構成構成
Handler Interface
Innodb MyISAM Other storage engines …
SQL Layer HandlerSocket Plugin
Listener for libmysql
libmysql libhsclient
Applications
mysqld
client app
概要概要
► InnoDBInnoDB 等のストレージエンジンへの非等のストレージエンジンへの非 SQLSQL インタフェースインタフェースを提供を提供
► TCP/IPTCP/IP でリクエストを受け、ストレージエンジンを直接叩でリクエストを受け、ストレージエンジンを直接叩くく
► 独自プロトコルを喋る独自プロトコルを喋る► C++C++ とと PerlPerl のクライアントライブラリを用意のクライアントライブラリを用意
PHP, Java, Python, Ruby, JavaScript(node.js), ScalaPHP, Java, Python, Ruby, JavaScript(node.js), Scala のライブラリが存のライブラリが存在在
► Linux/FreeBSD/MacOSLinux/FreeBSD/MacOS で動作で動作 LinuxLinux に最もチューニングされているに最もチューニングされている
► BSDBSD ライセンスライセンス► ソースソース : : https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQLhttps://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL
入手&インストール方法入手&インストール方法
►ソースからビルドソースからビルド https://github.com/ahiguti/HandlerSocket-Plugihttps://github.com/ahiguti/HandlerSocket-Plugi
n-for-MySQLn-for-MySQL►Spider For MySQLSpider For MySQL に同梱されているに同梱されている
http://spiderformysql.com/http://spiderformysql.com/ 斯波さんによる様々な機能追加有り斯波さんによる様々な機能追加有り
►Percona ServerPercona Server に同梱されているに同梱されている http://www.percona.com/software/percona-servhttp://www.percona.com/software/percona-serv
er/downloads/er/downloads/
メリットメリット
►速い速い MySQLMySQL はは SQLSQL をパースする処理周辺が性能のをパースする処理周辺が性能の
ネックになることがあるネックになることがある HandlerSocketHandlerSocket はリクエストを集約実行できるはリクエストを集約実行できる HandlerSocketHandlerSocket はリクエストをパイプライン化ではリクエストをパイプライン化で
きるきる クライアントライブラリも速いクライアントライブラリも速い
►同時接続数がほとんど無制限に同時接続数がほとんど無制限に 6553665536 本くらいまでいける本くらいまでいける
►通信量が減る通信量が減る
HandlerSocketHandlerSocket に向いているケーに向いているケースス
►データサイズが十分小さくメモリに乗るデータサイズが十分小さくメモリに乗る►単純なクエリ、サーバの単純なクエリ、サーバの CPUCPU がネックがネック►単純なクエリ、トラフィックがネック単純なクエリ、トラフィックがネック►同時接続数が多すぎて同時接続数が多すぎて MySQLMySQL の持続接続の持続接続
が使えないが使えない
HandlerSocketHandlerSocket に不向きなケースに不向きなケース
►クエリが複雑でクエリが複雑で HandlerSocketHandlerSocket で実現困難で実現困難►クエリ一回あたりのクエリ一回あたりの CPUCPU 使用量が多く使用量が多く CPUCPU
ネックネック►データサイズが大きくデータサイズが大きく Disk IODisk IO がネックがネック
性能の目安性能の目安 (( 参照系参照系 ))
► 8 Core CPU with HT8 Core CPU with HT 、、 1Gb1Gb のの NIC x1NIC x1 、、 InnoDB pluInnoDB plugingin 、単純な参照クエリの処理性能、単純な参照クエリの処理性能 libmysql: libmysql: ~~ 100,000 qps100,000 qps
►CPUCPU ネックネック HandlerSocket: HandlerSocket: ~~ 300,000 qps300,000 qps
►ネットワーク周りがネックになるネットワーク周りがネックになる►CPUCPU は頭打たないは頭打たない
HandlerSocket(pipelined): HandlerSocket(pipelined): ~~ 800,000 qps800,000 qps►CPUCPU ネックネック
HandlerSocket(pipelined) AHIHandlerSocket(pipelined) AHI 有効有効 : : ~~ 3,000,000 qps3,000,000 qps►CPUCPU ネックネック
性能の目安性能の目安 (( 更新系更新系 ))►前提前提 ::
同期同期 (durable)(durable) 書き込み書き込み► sync_binlog = 1sync_binlog = 1► innodb_flush_log_at_trx_commit = 1innodb_flush_log_at_trx_commit = 1► innodb_support_xa = 1innodb_support_xa = 1
バッテリ付きバッテリ付き write-back cache write-back cache 又は又は SSDSSD►性能性能 ::
mysql: mysql: ~~ 1000 qps1000 qps► innodb plugin innodb plugin で で sync_binlog = 0 sync_binlog = 0 だとだと group commitgroup commit が効いてが効いて
さらに速くなるが、レプリするとスレーブが追いつかないさらに速くなるが、レプリするとスレーブが追いつかない HandlerSocket: HandlerSocket: ~~ 30000 qps30000 qps
►書き込みはシリアライズされるので、レプリしても常にス書き込みはシリアライズされるので、レプリしても常にスレーブが追いつくレーブが追いつく
HandlerSocketHandlerSocket の主な機能の主な機能 (( 参照系参照系 ))
► IndexIndex を使った行取得を使った行取得 IndexIndex を使った取得しかできないを使った取得しかできない
►範囲取得範囲取得 比較条件に使える演算子は比較条件に使える演算子は =, >=, >, <=, <=, >=, >, <=, <
►SQLSQL の’の’ IN’IN’のような複数行取得のような複数行取得►範囲取得 範囲取得 + + フィルタフィルタ
条件を満たす行だけを取得条件を満たす行だけを取得
HandlerSocketHandlerSocket の主な機能の主な機能 (( 更新系更新系 ))
►参照クエリで得た行の参照クエリで得た行の UPDATEUPDATEとと DELETEDELETE►行の行の INSERTINSERT►AtomicAtomic なな Increment/DecrementIncrement/Decrement►トランザクションはサポートしないトランザクションはサポートしない►リクエストを跨いだレコードロックを取リクエストを跨いだレコードロックを取
ることはできないることはできない つまりつまり select ... for updateselect ... for update
SQLSQL クエリとの共存クエリとの共存○ ○ 同じ同じ DBDB をを SQLSQL とと HandlerSocketHandlerSocket の両方からアクセスできるの両方からアクセスできる○ ○ バイナリログバイナリログ
HandlerSocketHandlerSocket による更新はによる更新は row baserow base のバイナリログエントリとしてのバイナリログエントリとして記録される記録される
○ ○ レプリケーションレプリケーション○ ○ SQLSQL クエリキャッシュクエリキャッシュ
HandlerSocketHandlerSocket で更新するとクエリキャッシュが破棄されるで更新するとクエリキャッシュが破棄される 古い古い HandlerSocketHandlerSocket では破棄されない問題があったでは破棄されない問題があった
○ ○ ACIDACID特性特性○ ○ AUTO_INCREMENTAUTO_INCREMENT
HandlerSocketHandlerSocket でで NULLNULL をセットすると一意な値が生成されるをセットすると一意な値が生成される× TIMESTAMP× TIMESTAMP型型
HandlerSocketHandlerSocket での更新では値がセットされないでの更新では値がセットされない× × トリガトリガ
HandlerSocketHandlerSocket での更新ではトリガは実行されないでの更新ではトリガは実行されない
はまりどころはまりどころ (1)(1)
►HandlerSocketHandlerSocket の接続を切るまでテーブルの接続を切るまでテーブルが閉じられないが閉じられない ALTER TABLEALTER TABLEとか打つときは接続を全部閉じるとか打つときは接続を全部閉じる必要がある必要がある
はまりどころはまりどころ (2)(2)
►SQLSQL とと HandlerSocketHandlerSocket の両方から同じの両方から同じ DBDBを更新するとデッドロックすることがあるを更新するとデッドロックすることがある SQLSQL で更新する際に次のように排他処理するとで更新する際に次のように排他処理すると
デッドロックしないデッドロックしない SELECT GET_LOCK(‘handlersocket_wr’, 5);SELECT GET_LOCK(‘handlersocket_wr’, 5); (SQL(SQL による更新処理による更新処理 )) SELECT RELEASE_LOCK(‘handlersocket_wr’);SELECT RELEASE_LOCK(‘handlersocket_wr’);
libhsclientlibhsclient
►HandlerSocketHandlerSocket 用クライアントライブラリ用クライアントライブラリ C++C++ 低水準インタフェース低水準インタフェース
Net::HandlerSocketNet::HandlerSocket
►PerlPerl 用クライアントライブラリ用クライアントライブラリ xsxs経由で経由で libhsclientlibhsclient を呼んでいるを呼んでいる
my $cli = new Net::HandlerSocket({host => ‘localhost’, port => 9999});
$cli->open_index(1, ‘db1’, ‘table1’, ‘PRIMARY’, ‘k,v’);my $res = $cli->exec_multi([
[ 1, ‘=‘, [ ’33’ ], 1, 0 ],[ 1, ‘=‘, [ ’44’ ], 1, 0, ‘U’, [ ’44’, ‘hoge’ ] ],[ 1, ‘>=‘, [ ’55’ ], 10, 20 ],
]);
その他の言語用クライアントライブその他の言語用クライアントライブラリラリ
► PHPPHP http://openpear.org/package/Net_HandlerSockethttp://openpear.org/package/Net_HandlerSocket http://github.com/tz-lom/HSPHPhttp://github.com/tz-lom/HSPHP httphttp://code.google.com/p/php-handlersocket/://code.google.com/p/php-handlersocket/
► JavaJava http://code.google.com/p/hs4j/http://code.google.com/p/hs4j/ httphttp://code.google.com/p/handlersocketforjava/://code.google.com/p/handlersocketforjava/
► PythonPython http://pypi.python.org/pypi/python-handler-sockethttp://pypi.python.org/pypi/python-handler-socket httpshttps://code.launchpad.net/~songofacandy/+junk/pyhandlersocket://code.launchpad.net/~songofacandy/+junk/pyhandlersocket
► RubyRuby https://github.com/winebarrel/ruby-handlersockethttps://github.com/winebarrel/ruby-handlersocket https://github.com/miyucy/handlersockethttps://github.com/miyucy/handlersocket
► JavaScriptJavaScript https://github.com/koichik/node-handlersockethttps://github.com/koichik/node-handlersocket
► ScalaScala https://github.com/fujohnwang/hs2clienthttps://github.com/fujohnwang/hs2client
MobageMobage での負荷分散と冗長化での負荷分散と冗長化
► サーバリストの各エントリには重みが指定可能サーバリストの各エントリには重みが指定可能 少しずつサービスに入れるようなことができる少しずつサービスに入れるようなことができる 性能の異なるサーバを混ぜられる性能の異なるサーバを混ぜられる
► サーバリストはサーバリストは 1010秒に一回程度の頻度で取得秒に一回程度の頻度で取得► ランダム又はランダム又は consistent hashingconsistent hashing でサーバを決定すでサーバを決定す
るる► DBDB 接続はなるべく持続接続はなるべく持続
HandlerSocketHandlerSocket ではでは 3030秒間繋ぎっぱなし秒間繋ぎっぱなし► アプリ自体がリトライする仕組みを持っているアプリ自体がリトライする仕組みを持っている
DBDB サーバが一台死んでも即エラーにはならないサーバが一台死んでも即エラーにはならない► DBDB サーバ以外も同じ仕組みで負荷分散&冗長化サーバ以外も同じ仕組みで負荷分散&冗長化
MobageMobage での負荷分散と冗長化での負荷分散と冗長化
►MobageMobage で使っている仕組みの一部がで使っている仕組みの一部が HandlerSocHandlerSocketket のソースに入っていますのソースに入っています perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pmperl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm 持続接続、エラー時のリトライ処理など持続接続、エラー時のリトライ処理など
まとめまとめ
►HandlerSocketHandlerSocket を使えばを使えば MySQLMySQL のデータのデータベースアクセスを高速化できることがありベースアクセスを高速化できることがありますます
►性能を引き出すには負荷分散・冗長化の仕性能を引き出すには負荷分散・冗長化の仕組みも重要です組みも重要です