Handler socket测试报告 - 20110422
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Handler socket测试报告 - 20110422

  • 864 views
Uploaded on

MySQL Handler socket测试报告

MySQL Handler socket测试报告

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
864
On Slideshare
864
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
3
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. HandlerSocket 测试报告 HandlerSocket 测试报告 作者:叶金荣 编写日期: 2011-04-22 目录 1 测试说明........................................................................................................................... 2 1.1 HandlerSocket 简介..................................................................................................... 2 1.2 HandlerSocket 体系结构............................................................................................. 2 1.2.1 关于 HandlerSocket 性能........................................................................................ 3 1.2.2 HandlerSocket 特色................................................................................................. 6 1.3 HandlerSocket 读写线程模型..................................................................................... 7 1.4 HandlerSocket 客户/服务器协议............................................................................... 8 2 HandlerSocket 使用........................................................................................................ 9 2.1 下载、安装.................................................................................................................... 9 2.2 配置.............................................................................................................................. 10 2.3 HandlerSocket API 案例........................................................................................... 11 2.3.1 随机读取记录.......................................................................................................... 12 2.3.2 顺序写入记录.......................................................................................................... 13 2.3.3 更新记录.................................................................................................................. 15 2.3.4 删除记录.................................................................................................................. 16 3 API 简介.......................................................................................................................... 17 4 结语................................................................................................................................. 18 5 参考信息......................................................................................................................... 19
  • 2. HandlerSocket 测试报告 6 附件................................................................................................................................. 21 1 测试说明 本次测试了 HandlerSocket 这个 NOSQL 产品在数据分析中的表现,考察其在 公司业务生产环境中实施的可行性及其性能。 1.1 HandlerSocket 简介 简言之,HandlerSocket 是一个基于 MySQL InnoDB 引擎的 NOSQL 产品,采 用原生态 API 方式操作 InnoDB 引擎表空间文件。作者 Akira Higuchi 是日本人, 2010 年 8 月离开 Oracle,加盟日本社交游戏公司 DeNA。它最重要的特点就是绕 过 MySQL 的 SQL 解析层、查询优化器、缓存层,直接用原生 API 存取 InnoDB 引 擎表空间文件,因此获得了性能上的 N 个数量级提升。 1.2 HandlerSocket 体系结构 HandlerSocket 的体系结构如下图所示:
  • 3. HandlerSocket 测试报告 如简介中提到的,libhsclient 直接访问 Handlersocket Plugin,绕过了 listener 和 SQL Layer,从而获得了性能上的极大提升。 1.2.1 关于 HandlerSocket 性能 这是作者迚行的对比测试结果: HandlerSoket 效率非常高的原因是:
  • 4. HandlerSocket 测试报告 1. 绕过 SQL 解析层,大大降低了 CPU 消耗 2. 将分散的请求转化成批量操作,降低了 CPU、磁盘 IO 消耗 3. 采用自定义的服务/客户协议,降低了网络 IO 消耗 下面是用 Oprofile 工具对比探测的结果,测试方法是在客户端并发执行多 次类似操作操作 SELECT v from table where k = ? 1. 采用原始的 libmysql 接口 明显的看到,mysqld 迚程消耗了大量 CPU 资源。 看下 mysqld 迚程内部的详细情况:
  • 5. HandlerSocket 测试报告 可以看到,SQL 解析层消耗了最多的 CPU 资源。 再看下 linux 内核的具体情况: Schedule 调用消耗了最多的 CPU 资源。 2. 采用 HandlerSocket 专用接口 明显的看到,mysqld 迚程消耗了大量 CPU 资源。 看下 mysqld 迚程内部的详细情况:
  • 6. HandlerSocket 测试报告 可以看到,MySQL 内部消耗 CPU 资源最多的是 InnoDB 相关的调用。 再看下 linux 内核的具体情况: Schedule 调用已经不是消耗 CPU 资源最多的了。 1.2.2 HandlerSocket 特色 1. 集成到 InnoDB 引擎中,和传统的引擎管理一样,无需了解太多新知识, 很快就能投入使用
  • 7. HandlerSocket 测试报告 2. 目前只支持等值操作(=, >=, >, <=, <),不支持范围检索(t1 > N and t1 < M)查询 3. 支持插入、更新、删除 4. 不支持事务控制,但底层是支持的 5. 启用 binlog 的话,数据变更采用 row-based 格式 6. 所有的操作都是永久性的,不能回滚 7. 传统的 MySQL 是每个连接创建一个线程的模式,计划在 MySQL 6 采用线 程池的机制;在 HandlerSocket 中多个连接只启用一个线程,采用 epoll 调用,效率更高 8. HandlerSocket 比传统的 mysql 快了 7.5 倍,而且%us 的 cpu 使用率为 mysql 的 3/4 1.3 HandlerSocket 读写线程模型 1. 读线程模型
  • 8. HandlerSocket 测试报告 2. 写线程模型 1.4 HandlerSocket 客户/服务器协议 传统的 MySQL 客户/服务器协议用 tcpdump 结果如下: 相比之下,HandlerSocket 协议就简单了很多:
  • 9. HandlerSocket 测试报告 相应的网络 IO 统计差别非常大: 2 HandlerSocket 使用 2.1 下载、安装 登录官网:http://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL,下载 相应版本的源码包,同时还需要下载 MySQL 5.1 或更高版本源码,分别加压缩后, 采用类似下面的参数迚行编译: ./configure --with-mysql-source=../Percona-Server-5.5.10-rc20.1 --with-mysql-bindir=/usr/local/mysql/bin&& make 然后就可以在 handlersocket/.libs 目录下找到编译完后的动态库文件: 将 这 些 动 态 库 文 件 拷 贝 到 mysql 的 动 态 库 加 载 目 录 下 , 例 如 : /usr/local/mysql/lib/mysql/plugin 目录下。 登录到 MySQL 服务器上,安装 HandlerSocket 插件: mysql>INSTALL PLUGIN HandlerSocket SONAME 'handlersocket.so';
  • 10. HandlerSocket 测试报告 执行”SHOW PLUGINS” 指令查看是否安装成功。 另外,如果还想要安装 Perl 客户端 API 库的话,还需要多做点: cd perl-Net-HandlerSocket perl Makefile.PL&& make && make install 就可以把客户端 API 库安装到 Perl 库目录下。 2.2 配置 安装完插件后,接下来修改下 MySQL 配置文件/etc/my.cnf,例如: #HandlerSocket #设置 handlersocket 读数据专用端口,默认值即可 loose_handlersocket_port = 9998 #设置 handlersocket 写数据专用端口,默认值即可 loose_handlersocket_port_wr = 9999 #设置 handlersocket 读数据并发线程数,可根据实际情况进行调整 loose_handlersocket_threads = 16 #设置 handlersocket 写数据并发线程数,默认值 1 即可 loose_handlersocket_threads_wr = 1 重启 MySQL 迚程后,若无意外,就可以看到确实启用这些端口监听了: 同时,MySQL 的线程中也能看到正在运行:
  • 11. HandlerSocket 测试报告 其中,线程 ID 号为 17 的是 HandlerSocket 的写线程,当前有 4 个连接,4 个活动写操作;线程号为 15 的是读线程,当前有 3 个连接,3 个活动读请求。 2.3 HandlerSocket API 案例 目前官方只发布了 Perl/C++/JAVA 三种语言的 API,同时也支持 SOCKET 协 议,因此也可以用其他语言来实现,甚至用 telnet 都可以。 HandlerSocket 读写模式一般是: 1. 创建连接 2. 打开主键索引,open_index 3. 读写记录, execute_single/execute_find/insert/update/delete 4. 关闭连接 其中,最重要的一个调用方法是:execute_single,如: execute_single(3, '=', [ 'foo' ], 1, 0) execute_single 方法的第一个参数需要跟之前 open_index 方法的第一个参 数一致。第二个参数'='指定了检索条件,目前支持'=', '>=', '<=', '>'和'<'。 第三个参数[ 'foo' ]为一个 arrayref,指定了检索的 key,其长度必须小于或 者等于对应索引的列数。第四个和第五个参数指定了查询的 limit 和 offset。
  • 12. HandlerSocket 测试报告 2.3.1 随机读取记录 #!/usr/bin/perl use strict; use warnings; use Net::HandlerSocket; #1. 创建连接 my $args = { host => '127.0.0.1', port => 9998 }; my $hs = new Net::HandlerSocket($args); #2. 打开索引 #数值 0 是程序中打开句柄编号,可以自定义; #test 是数据库名 #t1 是数据表名 #PRIMARY 是主键名 #id,k,c,pad 是后续要进行存取的列名 my $res = $hs->open_index(0, 'test', 't1', 'PRIMARY', 'id,k,c,pad'); die $hs->get_error() if $res != 0; while (1)
  • 13. HandlerSocket 测试报告 { #3. 随机读取记录 my $tmp_i = sprintf("%d", rand() * 10000000); $res = $hs->execute_single(0, '=', [ "$tmp_i" ], 1, 0); die $hs->get_error() if $res->[0] != 0; shift(@$res); for (my $row = 0; $row < 1; ++$row) { my $id = $res->[$row + 0]; my $k = $res->[$row + 1]; my $c = $res->[$row + 2]; my $pad = $res->[$row + 3]; #print "tmp_i:$tmp_i, $id, $k, $c, $padn"; } } #5. 关闭连接 $hs->close(); 2.3.2 顺序写入记录 #!/usr/bin/perl
  • 14. HandlerSocket 测试报告 use strict; use warnings; use Net::HandlerSocket; #1.1 establishing a connection my $args = { host => '127.0.0.1', port => 9999 }; my $hs = new Net::HandlerSocket($args); #1.2 open index my $res = $hs->open_index(0, 'test', 't1', 'PRIMARY', 'id,k,c,pad'); die $hs->get_error() if $res != 0; #2. insert while (1) { my $tmp_i = sprintf("%d", rand() * 10000000); $res = $hs->execute_insert(0, [ '0',"$tmp_i",'abcy','aasfasdyyy' ]); my $insert_id = $res->[1]; my $ret = $res->[0]; } #4. closing the connection
  • 15. HandlerSocket 测试报告 $hs->close(); 2.3.3 更新记录 #!/usr/bin/perl use strict; use warnings; use Net::HandlerSocket; #1.1 establishing a connection my $args = { host => '127.0.0.1', port => 9999 }; my $hs = new Net::HandlerSocket($args); #2 open index my $res = $hs->open_index(0, 'test', 't1', 'PRIMARY', 'k'); die $hs->get_error() if $res != 0; #3. update #$hs->execute_single(0, '=', [ '270337481' ] , 1, 0, 'U', [ '1806176' ]); #或者 $hs->execute_update(0, '=', [ '270337481' ] , 1, 0, [ '1806177' ]);
  • 16. HandlerSocket 测试报告 #4. closing the connection $hs->close(); 2.3.4 删除记录 #!/usr/bin/perl use strict; use warnings; use Net::HandlerSocket; #1 establishing a connection my $args = { host => '127.0.0.1', port => 9999 }; my $hs = new Net::HandlerSocket($args); #2 open index my $res = $hs->open_index(0, 'test', 't1', 'PRIMARY', 'k'); die $hs->get_error() if $res != 0; #3. delete #$hs->execute_single(0, '=', [ '270337481' ] , 1, 0, 'D');
  • 17. HandlerSocket 测试报告 #或者 $hs->execute_delete(0, '=', [ '270337480' ] , 1, 0); #4. closing the connection $hs->close(); 3 API 简介 上面已经提到了,HandlerSocket 官方目前提供了 C++、PERL、JAVA 这 3 种 API 接口,其他开发语言的 API 需要自己开发,不过也很简单。下面是 HandlerSocket 协议的几个要点: 1. 基于简单的文本交互模式,每次命令以 LF(0x0a)结束 2. 每行文本由多部分标记组成,由 HT(0x09)连接起来 3. 每个标记不是 NULL 就是编码后的字符串,如果标记内容为空,必须要用 NULL 来表示,而不是像普通数据库那样不用额外指定 4. NULL 对应的字符是 NUL(0x00) HandlerSocket 采用了简单的请求/响应协议模式,建立连接后,客户端发 出请求,然后得到响应。主要的几种操作模式有: 1. 建立完连接后,所有的请求都是以 open_index 开始。也就是必须打开一 个主键索引后,才能迚行后续的操作,包括:检索、删除、写入、更新 等。Open_index 语法格式为: P <indexid><dbname><tablename><indexname><columns> 2. 建立完连接后,就可以迚行相应的数据操作了,例如检索数据:find。
  • 18. HandlerSocket 测试报告 Find 的语法格式为: <indexid><op><vlen><v1> ... <vn><limit><offset><mop><m1> ... <mk> 操作代码 OP 目前支持:'=', '>', '>=', '<', '<=' 等几种。 3. 插入新数据,insert 的语法格式为: <indexid> '+' <vlen><v1> ... <vn> 4. 更新数据行,update 语法格式为: <indexid><op><vlen><v1> ... <vn><limit><offset><mop><m1> ... <mk> 和 find 的语法格式是一样的,只不过在这里的 OP 是:U。 5. 删除数据行,delete 的语法格式和 update 一样,把 OP 值改成:D。 更多的 API 案例可参考附件文档。 4 结语 HandlerSocket 作为目前基于 MySQL InnoDB 引擎的 NOSQL 产品,在 web 3.0 大潮中发挥着重要作用,其独特的设计,高效性能吸引着越来越多的使用者。在 畅游的在线业务中,也有大量的应用场景可以采用,例如: 1. 官网用户验证信息表,这个表可以从原始数据中用触发器等方式维护一 个冗余表,前端验证程序通过 socket 可快速读取迚行验证 2. 在线用户表,该表更新频率非常高,采用 handlersocket 将大大提升其 处理效率 3. 其他存储类型简单,读写效率要求很高的类型,例如微博网站的用户好
  • 19. HandlerSocket 测试报告 友关系信息表等 5 参考信息 http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-s tory-for.html http://www.mysqlperformanceblog.com/2011/03/28/whats-up-with-handlers ocket/ http://www.mysqlperformanceblog.com/2010/11/02/handlersocket-on-ssd/ 测试结果: 1. 同时运行 16 个随机读进程 [@tc_17_77 ~]# mysqladmin ext | egrep -i 'Innodb_rows_inserted|Innodb_rows_read|handler_read_key|Handler_read_rnd_next|Uptime_s ince_flush_status' | Handler_read_key | 21386311927 | | Handler_read_rnd_next | 407 | | Innodb_rows_inserted | 0 | | Innodb_rows_read | 10092637781 | | Uptime_since_flush_status | 95763 | [@tc_17_77 ~]# mysqladmin ext | egrep -i
  • 20. HandlerSocket 测试报告 'Innodb_rows_inserted|Innodb_rows_read|handler_read_key|Handler_read_rnd_next|Uptime_s ince_flush_status' | Handler_read_key | 21391318101 | | Handler_read_rnd_next | 780 | | Innodb_rows_inserted | 0 | | Innodb_rows_read | 10095000090 | | Uptime_since_flush_status | 95785 | 每秒读取 innodb rows:105392.2857 2. 同时运行 8 个随机写进程 [@tc_17_77 ~]# mysqladmin ext | egrep -i 'Innodb_rows_inserted|Innodb_rows_read|handler_read_key|Handler_read_rnd_next|Uptime_s ince_flush_status' | Innodb_rows_inserted | 51218482 | | Uptime_since_flush_status | 6863 | 每秒写 innodb rows:7445.9910 第二次测试: | Innodb_rows_inserted | 737903418 | | Uptime_since_flush_status | 136252 | 5415.7254
  • 21. HandlerSocket 测试报告 6 附件 PERL API 案例: C++ API 案例: JAVA API 案 例 : 可 直 接 查 看 google code 资 源 : http://code.google.com/p/handlersocketforjava/