More Related Content Similar to Handlersocket 20140218 Similar to Handlersocket 20140218 (20) Handlersocket 201402182. 3 行でまとめると
• HandlerSocket は、 MariaDB ・ MySQL の
「非 SQL 」フロントエンド
• 性能向上、通信量削減、メモリ使用量削減
等の効果がある
• version 2 でクエリ解釈ロジックを外部モ
ジュールで定義できるようになり、従来よ
りも複雑なクエリをサポート
3. 1 200000
SELEC T q u e r y
SELEC T q u e r y (t h r e a d p o o l)
Ha n d le r So c k e t
800000
600000
400000
200000
# o f c o n c u rre n t c o n n e c t io n s
32768
1 6384
81 92
4096
2048
1 024
51 2
256
1 28
64
32
16
8
4
2
0
1
q u e rie s p e r s e c o n d
1 000000
4. HandlerSocket 開発のねらい
• DB キャッシュ用サーバを置くことによる
システムの複雑化や不整合問題を回避する
こと
• 予測可能で安定した性能を出すことで、性
能問題起因のシステム障害を起こさないよ
うにすること
• 同時接続数や通信量などのネックを回避し
、システム全体のスケーラビリティを確保
すること
6. HandlerSocket を使うには
• MariaDB 5.3 以降に含まれている
– MariaDB のサイトにドキュメントもある
https://mariadb.com/kb/en/handlersocket/
• インストール手順概略 :
– my.cnf にいくつか設定を書く
– 以下のクエリを実行し plugin をロード
install plugin handlersocket soname ‘handlersocket.so’
– telnet でポート 9998 に繋ぎ、改行を打つと反
応が返ってくれば ok
9. 実行例
• create table db1.table1 (k int key, v char(20))
• insert into db1.table1 values (234, 'foo'), (678, ‘bar’)
$ telnet localhost 9998
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
P
0
db1 table1 PRIMARY k,v
0
1
0
=
1
234
0
2
234 foo
0
=
1
678
0
2
678 bar
db1.table1 の PK を開く
k = 234 を検索
k = 678 を検索
11. HandlerSocket の主な機能 ( 参照
系)
• Primary Key や Unique Key を使った行取
得
• 範囲取得
– 比較条件に使える演算子は =, >=, >, <=, <
12. HandlerSocket の主な機能 ( 更新
系)
• 参照クエリで得た行の UPDATE と DELETE
• 行の INSERT
• Atomic な Increment/Decrement
• 更新系クエリは row-based の形式でバイナリロ
グに記録される
– MySQL のレプリケーション機能を使える
• ACID 特性は MySQL と同じ
– 書き込みは同期的、 ( 設定によるが )durable
14. MySQL で通信内容が冗長になるケース
SELECT column0, column1, column2, column3, column4
FROM db_1.table_1 where k = 15
libmysqlclient/mysqld でこのクエリを実行すると…
write(3, "L0003select
column0,column1,column2,column3,column4 from db_1.table_1
where k=15", 80) = 80
read(3,
"100100560023def4db_17table_17table_17column0
7column0fr0<00037520000000060033def4db_17
table_17table_17column17column1fr0<00037520000
000060043def4db_17table_17table_17column27column
2fr0<00037520000000060053def4db_17table_1
7table_17column37column3fr0<0003752000000006
0063def4db_17table_17table_17column47column4fr0
<0003752000000500737600"0n001000100
011001200130014500t37600"0", 16384) = 327
16. MySQL で通信内容が冗長になるケース
• 結果セットメタデータが大きい
– 各列について、 DB 名、テーブル名、テーブル別名、列名、列の
別名がメタデータに含まれる
http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#F
– mysql 4.0 までのプロトコルではメタデータが少し小さい。 4.1 以
降で大きくなった。
• 列が多く行が少ないとき相対的に大きい
– メタデータは結果セットに一つだけ付くから
• HANDLER クエリや SSPS を使っても減らすこと
ができない
18. MariaDB の thread pool につい
て
• MariaDB には thread pool の実装がある ( 既定
では off)
thread-handling=pool-of-threads
• 有効にすると SQL クエリについても同時接続
数を増やしたときの性能劣化が小さくなる
– HandlerSocket を使った場合と似た特性になる
• 但し HandlerSocket を使うときは thread pool 無
効にしておいたほうがよいかもしれない
– sleep しうる処理は one-thread-per-connection のほう
が向いている
19. 200000
1 80000
1 40000
1 20000
1 00000
80000
60000
40000
SELEC T q u e r y
20000
SELEC T q u e r y (t h r e a d p o o l)
# o f c o n c u rre n t c o n n e c t io n s
32768
1 6384
81 92
4096
2048
1 024
51 2
256
1 28
64
32
16
8
4
2
0
1
q u e rie s p e r s e c o n d
1 60000
23. 2500000
S EL EC T q u e r y
S EL EC T q u e r y (t h r e a d p o o l)
Ha n d le r S o c k e t
Ha n d le r S o c k e t (p ip e lin in g x 5)
HANDL ER q u e r y (t h r e a d p o o l)
HANDL ER q u e r y S S PS (t h r e a d p o o l)
1 500000
1 000000
500000
# o f c o n c u rre n t c o n n e c t io n s
32768
1 6384
81 92
4096
2048
1 024
51 2
256
1 28
64
32
16
8
4
2
0
1
q u e rie s p e r s e c o n d
2000000
24. ベンチマークについて
• Xeon E5-2670 2.6GHz, 16core 32 論理 CPU の
半分を mysqld, 半分をクライアントに割り当て
• internet domain socket で通信
• innodb テーブル
• innodb_adaptive_hash_index = 1
• handlersocket_threads = 16
26. version 2.0 の変更点
• クエリ解釈ロジックを外部モジュールで
定義できるようになる
– 従来サポートしていなかった種類のクエリを
外部モジュールで実装可能
• 外部モジュールは、サービスを停止せず
に更新可能
– 古いバージョンの外部モジュールは参照が無
くなった時点でアンロードされる
27. ねらい
• Stored procedure のように手軽に
HandlerSocket へ機能追加できるようにしたい
• SQL に代わるクエリ言語を外部モジュールとし
て実装する
– 従来の HandlerSocket クエリは拡張性に乏しいので
抜本的に直したい
• 将来的には SQL も HandlerSocket 上に実装する
かもしれない
– SQL であっても現在の HandlerSocket と同等の性能
を出すことは可能
29. hs module
hsmod_module
モジュールがロードされたときに 1 つだけ作成される
hsmod_worker
ワーカースレッドにつき 1 つ作成される
hsmod_conn
クライアント接続につき 1 つ作成される
hsmod_stmt
ステートメントが prepare されるごとに作成される
クエリが実行されると execute メソッドが呼ばれる
create
create
prepare
30. API for hs modules
関数
コンテキスト
動作
hs_open_index
prepare
テーブルと索引を開く
hs_get_field_num
prepare, execute
指定された名前のフィールドを捜し、その番号を
返す
hs_find_first
hs_find_next
hs_find_finish
execute
索引から条件にマッチするレコードを探す
hs_field_get
execute
現在選択されている行の指定された列の値を取得
hs_update_row
execute
現在選択されている行を指定された値で更新
hs_delete_row
execute
現在選択されている行を削除
hs_insert_row
execute
行を作成
hs_push_response
prepare, execute
クライアントへレスポンスを返す
32. HS2.0 クエリ ( 仮 ) – 単純なク
エリ
(do (open hstestdb hstesttbl PRIMARY idx0)
(foreach idx0 = (?0) 1
(response (idx0.v))))
テーブル hstestdb.hstesttbl の PK を開き、 idx0 という名前をつ
ける。 idx0 のキーが実行時引数の 0 番に一致する行に対
し、その行のフィールド v の値を返す。
これは以下の SQL クエリと同等の結果を返す
SELECT v from hstestdb.hstesttbl where k = ?
33. HS2.0 クエリ ( 仮 ) – inner join
(do (open hstestdb hstesttbl PRIMARY idx0)
(open hstestdb hst2 PRIMARY idx1)
(foreach idx0 = (?0) 1
(foreach idx1 = (idx0.v) 1
(response (idx0.k idx0.v idx1.k idx1.v)))))
これは以下の SQL クエリと同等の結果を返す
SELECT t0.k, t0.v, t1.k, t1.v
FROM hstestdb.hstesttbl t0
INNER JOIN hstestdb.hst2 t1
ON t0.v = t1.k
WHERE t0.k = ?
34. 1 200000
HS2.0, s im p le q u e r y
HS2.0, in n e r jo in
800000
600000
400000
200000
# o f c o n c u rre n t c o n n e c t io n s
1 6384
81 92
4096
2048
1 024
51 2
256
1 28
64
32
16
8
4
2
0
1
q u e rie s p e r s e c o n d
1 000000
35. version 2.0 でもできないこと
• 自動コミットを抑制はできない
– HandlerSocket ではレスポンスが返った時点
で必ずコミット済み
– lock を保持したまま sleep することが無いよ
うにしている
• rollback はできない
– 複数リクエストを一つのトランザクションの
中で実行しているから
36. SQL をサポート?
• SQL をパースし、実行戦略を決めて
HS2.0 クエリ ( 仮 ) を組み立てればよい
• 変換は prepare 段階で行えるの
で、 execute の性能には影響しない
– したがって SQL であっても現在の
HandlerSocket と同等の性能を出すことがで
きる
• 実装するかどうか未定