More Related Content What's hot (20)
PPTX
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
hiroi10
PDF
COD2012 C3 : SQL Server 2012で振り返る、SQLOSのスレッド スケジューリング
Masayuki Ozawa
PDF
Guide to Cassandra for Production Deployments
smdkk
Similar to Handlersocket 20110517 (20)
PDF
MySQL Technology Cafe #12 MDS HA検証 ~パラメータからパフォーマンスまで~
オラクルエンジニア通信
PDF
hs_spider_hs_something_20110906
Kentoku
PDF
Percona ServerをMySQL 5.6と5.7用に作るエンジニアリング(そしてMongoDBのヒント)
Colin Charles
PDF
カジュアルにMySQL Clusterを使ってみよう@MySQL Cluster Casual Talks 2013.09
Mikiya Okuno
Recently uploaded (6)
PPTX
2025_7_25_吉祥寺_設計ナイト_ADR運用におけるデータ利活用の考え方.pptx
ssuserfcafd1
PDF
Google Driveハブ型Obsidian同期環境:PC編集とモバイル閲覧を安全・効率的に実現するクロスデバイス構築ガイド
honeshabri
Handlersocket 201105171. HandlerSocket plugin for MySQL 2011/05/17 NoSQL セミナー @ 渋谷 株式会社 DeNA システム統括本部 IT 基盤部 樋口 証 <higuchi dot akira at dena dot jp> 4. HandlerSocket plugin の概要 InnoDB 等のストレージエンジンへの非 SQL インタフェースを提供 TCP/IP でリクエストを受け、ストレージエンジンを直接叩く 独自プロトコルを喋る C++ と Perl のクライアントライブラリを用意 PHP, Java, Python, Ruby, JavaScript(node.js), Scala のライブラリが存在 Linux/FreeBSD/MacOS で動作 Linux に最もチューニングされている BSD ライセンス https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL 5. 構成 mysqld client app Handler Interface Innodb MyISAM Other storage engines … SQL Layer HandlerSocket Plugin Listener for libmysql libmysql libhsclient Applications 6. ねらい 単純な CRUD 処理を高速に実行したい。 SQL 処理を省略 単純な処理に適用可能な最適化 しかも同じデータを MySQL でも処理できるようにしたい。 単純かつ速度が必要な部分だけを非 SQL に置き換えたい SQL から少しずつ移行したい 7. 参考 : 非 SQL for MySQL (HandlerSocket 以前のもの ) mycached http://developer.cybozu.co.jp/kazuho/2009/08/mycached-memcac.html HandlerSocket と同様に handler インタフェースを叩く memcached プロトコルを喋る NDB API http://dev.mysql.com/doc/ndbapi/en/index.html ndbcluster 専用 HandlerSocket より下の層 ( ストレージエンジン内部 ) を叩く 8. 時系列 2010/03 このころ開発を始める 2010/04 最初のバージョンが完成 2010/06 DeNA Technology Seminar #2 で社外に初めて公開 2010/08 github でソースを公開 2010/08 mobage で本格利用開始 9. その後の動向 (1) Percona Server に HandlerSocket が取り込まれる Percona Server now both SQL and NOSQL http://www.mysqlperformanceblog.com/2010/12/14/percona-server-now-both-sql-and-nosql/ 10. その後の動向 (2) 2011/04 MySQL Conference & Expo 2011 DeNA 松信が HandlerSocket について講演 DeNA が Corporate Contributor of the Year 2011 を受賞 DeNA is Japan's biggest social game provider and run hundreds of MySQL servers to provide their services. So it is not surprising they also employ some of Japan's best and world famous MySQL experts to work on their LAMP stack. This team produced one of the most interesting innovations MySQL has seen for a while: HandlerSocket is MySQL's answer to the NoSQL trend, and with a vengeance. With read-transactions now running over 700% faster, it makes MySQL the fastest NoSQL key-value solution out there. And you get best of both worlds: MySQL and NoSQL in the same package. -> MySQL + HandlerSocket で KVS と同等以上の 性能が出せることを示した 11. その後の動向 (3) 2011/04 MySQL の memcached インタフェース NoSQL to MySQL with Memcached http ://dev.mysql.com/tech-resources/articles/nosql-to-mysql-with-memcached.html ... The HandlerSocket development at DeNA is a great example of community innovation, with a solution implemented as a custom plug-in and protocol for the MySQL server daemon. -> MySQL の NoSQL インタフェースが流行? 13. mobage への導入 2010/08 mobage で本格利用開始 サービスを停止せずに移行 導入以降トラブルは一度も無し 導入時と同じ mysqld プロセスが動き続けている 一度 HandlerSocket プラグインを更新 mysqld は停止せずにプラグインだけを入れ替え 14. 最初の適用箇所 MySQL + memcached で構成されていた クエリは単純だが数が膨大 既存構成の問題 : 同時接続数の問題で、 mysql の持続接続の利用が難しかった memcached とのデータ同期のための仕組みが複雑で運用に負担がかかっていた ネットワークトラフィックが必要以上に出てしまっていた 15. 導入効果 MySQL と memcached サーバの負荷削減 アプリケーションの CPU 負荷削減 20% ~ 35% 程度削減 ネットワークトラフィックの削減 適用箇所の 70% 程度削減 17. 利点 (libmysql と比較して ) CPU を喰わない サーバ側、クライアント側のいずれも効果あり 特に単純なクエリで差が大きい ネットワークトラフィックが減らせる 特に単純なクエリで差が大きい 同時接続数がほぼ無制限 少なくとも 65000 本までは可能 同時接続数を増やしても性能劣化が殆ど無い 21. HandlerSocket の機能 ( 参照系 ) Primary Key や Unique Key を使った行取得 範囲取得 比較条件に使える演算子は =, >=, >, <=, < SQL の’ IN’ のような複数行取得 22. HandlerSocket の機能 ( 更新系 ) 参照クエリで得た行の UPDATE と DELETE 行の INSERT トランザクションはサポートしない 更新系クエリは row-based の形式でバイナリログに記録される MySQL のレプリケーション機能を使える 書き込みは durable 23. 実行例 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 を検索 26. おおよその性能 8 Core HT 付きのサーバ、 1Gb の NIC 一個、 InnoDB 、 adaptive hash index 有効 libmysql: ~ 100,000 qps CPU が頭打つ HandlerSocket: ~ 300,000 qps ネットワーク周りがネックになる CPU は頭打たない HandlerSocket(pipelined): ~ 3,000,000 qps CPU が頭打つ 30. oprofile – libmysql/mysqld SELECT v from table where k = ? を大量に実行し、 oprofile で CPU 消費量をしらべる samples| %| ------------------ 9669940 53.1574 mysqld 4438098 24.3970 vmlinux 1835976 10.0927 libpthread-2.5.so 1680656 9.2389 libc-2.5.so 397970 2.1877 e1000e 89136 0.4900 oprofiled 42881 0.2357 oprofile 31. oprofile – libmysql/mysqld mysqld 内の CPU 消費 samples % symbol name 748022 7.7355 MYSQLparse(void*) 219702 2.2720 my_pthread_fastmutex_lock 205606 2.1262 make_join_statistics(JOIN*, TABLE_LIST*, 198234 2.0500 btr_search_guess_on_hash 180731 1.8690 JOIN::optimize() 177120 1.8317 row_search_for_mysql 171185 1.7703 lex_one_token(void*, void*) 162683 1.6824 alloc_root 131823 1.3632 read_view_open_now 122795 1.2699 mysql_select(THD*, Item***, TABLE_LIST*, 100276 1.0370 open_table(THD*, TABLE_LIST*, st_mem_root*, 99575 1.0297 mem_pool_fill_free_list 96434 0.9973 build_template(row_prebuilt_struct*, THD*, 86349 0.8930 get_hash_symbol(char const*, unsigned int, 32. oprofile – libmysql/mysqld カーネル内の CPU 消費 samples % symbol name 204393 4.6054 schedule 118648 2.6734 tcp_sendmsg 115832 2.6099 tcp_recvmsg 106537 2.4005 tcp_v4_rcv 103915 2.3414 tcp_ack 103534 2.3328 system_call 93864 2.1150 dev_queue_xmit 86831 1.9565 __mod_timer 85891 1.9353 tcp_rcv_established 84083 1.8946 .text.task_rq_lock 34. oprofile – HandlerSocket 先の SQL クエリと同等の処理を HandlerSocket で実行し、 oprofile で CPU 消費量をしらべる samples| %| ------------------ 1919039 51.0453 vmlinux 811998 21.5987 mysqld 421215 11.2041 libpthread-2.5.so 207166 5.5105 e1000e 191566 5.0955 HandlerSocket.so 188618 5.0171 libc-2.5.so 13622 0.3623 oprofiled 5707 0.1518 oprofile 35. oprofile – HandlerSocket mysqld 内の CPU 消費 samples % symbol name 119684 14.7394 btr_search_guess_on_hash 58202 7.1678 row_search_for_mysql 46946 5.7815 mutex_delay 38617 4.7558 my_pthread_fastmutex_lock 37707 4.6437 buf_page_get_known_nowait 36528 4.4985 rec_get_offsets_func 34625 4.2642 build_template(row_prebuilt_struct*, THD*, TABLE*, 20024 2.4660 row_sel_store_mysql_rec 19347 2.3826 btr_cur_search_to_nth_level 16701 2.0568 row_sel_convert_mysql_key_to_innobase 13343 1.6432 cmp_dtuple_rec_with_match 11381 1.4016 ha_innobase::index_read(unsigned char*, 11176 1.3764 dict_index_copy_types 10762 1.3254 mtr_memo_slot_release 10734 1.3219 ha_innobase::init_table_handle_for_HANDLER() 36. oprofile – HandlerSocket カーネル内の CPU 消費 samples % symbol name 129038 6.7241 tcp_sendmsg 80080 4.1729 tcp_v4_rcv 69658 3.6298 dev_queue_xmit 66171 3.4481 .text.skb_release_data 63316 3.2994 __qdisc_run 60279 3.1411 tcp_recvmsg 59703 3.1111 ip_output 58462 3.0464 .text.skb_release_head_state 48876 2.5469 tcp_ack 48733 2.5394 __alloc_skb 45660 2.3793 ip_queue_xmit 44671 2.3278 tcp_transmit_skb 37. oprofile – HandlerSocket HandlerSocket 使用時の CPU 消費 : カーネルが最も多く CPU を使用 カーネル内では network 周りで CPU 使用 mysqld 内では innodb の中が使用量多い 特に adaptive hash index 検索処理 43. 更新処理の性能について 前提 : 同期書き込み (durable) sync_binlog = 1 innodb_flush_log_at_trx_commit = 1 innodb_support_xa = 1 バッテリ付き write-back cache 又は SSD 性能 : mysql: ~ 1000 qps innodb plugin で sync_binlog = 0 だと group commit が効いてさらに速くなるが、スレーブが追いつかない HandlerSocket: ~ 30000 qps 書き込みはシリアライズされるので、常にスレーブが追いつく 44. HandlerSocket の排他制御 MyISAM ならテーブルロックがかかる shared-exclusive lock InnoDB ならテーブルロックはかからない。ただし更新系トランザクションは一度に一つだけ実行されるよう排他制御される。 そうしないとレコードロックを持ち合ってデッドロックするから 更新系スレッドは参照系スレッドをブロックしない HandlerSocket のリクエスト自体はデッドロックフリー そもそも単純なリクエストしかサポートしていないので。 46. C/S プロトコル比較 write(3, "L\0\0\0\3select column0,column1,column2,column3,column4 from db_1.table_1 where k=15", 80) = 80 read(3, "\1\0\0\1\0056\0\0\2\3def\4 db_1 \7 table_1 \7 table_1 \7 column0 \7 column0 \f\r\0<\0\0\0\375\200\0\0\0\0006\0\0\3\3def\4 db_1 \7 table_1 \7 table_1 \7 column1 \7 column1 \f\r\0<\0\0\0\375\200\0\0\0\0006\0\0\4\3def\4 db_1 \7 table_1 \7 table_1 \7 column2 \7 column2 \f\r\0<\0\0\0\375\200\0\0\0\0006\0\0\5\3def\4 db_1 \7 table_1 \7 table_1 \7 column3 \7 column3 \f\r\0<\0\0\0\375\200\0\0\0\0006\0\0\6\3def\4 db_1 \7 table_1 \7 table_1 \7 column4 \7 column4 \f\r\0<\0\0\0\375\200\0\0\0\0\5\0\0\7\376\0\0\"\0\n\0\0\10\001 0 \001 1 \001 2 \001 3 \001 4 \5\0\0\t\376\0\0\"\0", 16384) = 327 libmysql/mysqld でこのクエリを実行すると… SELECT column0, column1, column2, column3, column4 FROM db_1.table_1 where k = 15 47. C/S プロトコル比較 write(3, "1\t=\t1\t15\n", 9) = 9 read(3, "0\t5\t0\t1\t2\t3\t4\n", 8192) = 14 HandlerSocket で同等のクエリを実行すると… 14 bytes 327 bytes response 9 bytes 80 bytes request HandlerSocket libmysql 48. mysqld/libmysql のプロトコル 結果セットのメタデータが大きい 各列について、 DB 名 、 テーブル名 、 テーブル別名 、 列名 、 列の別名 がメタデータに含まれる http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Field_Packet mysql 4.0 までのプロトコルではメタデータが少し小さい。 4.1 以降で大きくなった。 列が多く行が少ないとき相対的に大きい メタデータは結果セットに一つだけ付くから HANDLER クエリでも同様にメタデータが付く server-side prepared statement を使っても同様 プロトコル圧縮を使うと 1/3 程度になる。ただし CPU を喰う。 51. DB::HandlerSocket Perl 用クライアントライブラリ xs 経由で libhsclient を呼んでいる my $cli = new DB::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 ], ]); 53. HandlerSocket の設定 HandlerSocket_threads = 16 参照系ワーカスレッド数 CPU コア数の 2 倍程度を推奨 HandlerSocket_thread_wr = 1 更新系ワーカスレッド数 増やしても余りメリットなさそう HandlerSocket_port = 9998 参照系ワーカスレッド用ポート HandlerSocket_port_wr = 9999 更新系ワーカスレッド用ポート 54. その他の設定 innodb_buffer_pool_size を限界まで大きく それでも参照が Disk ネックになるならデータ分割 innodb_log_file_size, innodb_log_files_in_group 大きいとテーブルスペースへの書き戻しが減る 更新系を速くしたいなら限界まで大きく innodb_thread_concurrency = 0 innodb 内の並列度の上限。 0 にすると無効。 open_files_limit = 65535 mysql が開けるファイルディスクリプタ数 HandlerSocket 接続一本あたり 1 つ消費するので大きく 56. durability に関連する設定 sync_binlog = 1 binlog を同期書き込み innodb_flush_log_at_trx_commit = 1 innodb の WAL を同期書き込み innodb_support_xa = 1 内部的に XA を使って binlog と innodb を同期 58. ベンチマーク サーバ Core2Quad Q6600 CentOS 5.4 EXPI9301CT(e1000e) Intel X25-E (write-back cache disabled) クライアントとは 1000base 接続 クライアントのほうが高速のため、全てのワークロードでクライアント側はボトルネックになっていない スキーマ : CREATE TABLE table1 (k varchar(32) KEY, v varchar(32)) engine = INNODB; read テスト : 1000 万レコード SELECT v from table1 where k = ? ランダムアクセスするようキーは乱数で生成 write テスト : 1000 万レコード UPDATE table SET v = ? where k = ? ランダムアクセスするようキーは乱数で生成 binlog 有効 動機的 (durable) 書き込み 64. 課題 ビルドが多少面倒 mysql のソースコードがビルド時に必要 mysql バイナリ互換性問題 mysql のバージョンやビルドオプションの違いによって plugin のバイナリ互換性が無くなる