您好,欢迎访问一九零五行业门户网

HandlerSocket

handlersocket http://www.uml.org.cn/sjjm/201211093.asp
目录:
handlersocket的原理
handlersocket的优势和缺陷阐述
handlersocket的性能测试
handlersocket的原理
handlersocket的应用场景:
mysql自身的局限性,很多站点都采用了mysql+memcached的经典架构,甚至一些网站放弃mysql而采用nosql产品,比如redis/mongodb等。不可否认,在做一些简单查询(尤其是pk查询)的时候,很多nosql产品比mysql要快很多,而且前台网站上的80%以上查询都是简洁的查询业务。
mysql通过handlersocket插件提供了api访问接口,在我们的基准测试中,普通的r510服务器单实例percona/xtradb达到了72w+qps(纯读),如果采用更强劲的cpu增加更多的网卡,理论上可以获得更高的性能。而同等条件下memcached仅有40w+qps(纯读),并且在r510上memcached单实例已经无法提升性能,因为memcached对内存的一把大锁限制了它的并发能力。
handlersocket原理:
mysql的架构是“数据库管理”和“数据管理”分离,即mysql server+storage engine的模式。mysql server是直接与client交互的一层,它负责管理连接线程,解析sql生成执行计划,管理和实现视图、触发器、存储过程等这些与具体数据操作管理无关的事情,通过调用handler api让存储引擎去操作具体的数据。storage engine通过继承实现handler api的函数,负责直接与数据交互,数据存取实现(必须实现),事务实现(可选),索引实现(可选),数据缓存实现(可选)。
(图1-1 mysql架构)
handlersocket是在mysql的内部组件,以mysql daemon plugin的形式提供类似nosql的网络服务,它并不直接处理数据,只是侦听配置好的某个端口方式,接收采用nosql/api的通讯协议,然后通过mysql内部的handler api来调用存储引擎(例如innodb)处理数据。理论上,handersocket可以处理各种mysql存储引擎,但是用myisam时,会出现插入的数据查不出来,这个实际上是构造行时第一字节没有初始化为0xff,初始化以后就没有问题,myisam也一样可以支持,但是为了更好地利用内存,用handlersocket都会搭配innodb存储引擎一起使用。
图1-2描述handlersocket具体做了哪些事情:
(图1-2 handlersocket原理)
因为handlersocket是以mysql daemon plugin形式存在,所以在应用中,可把mysql当nosql使用。它最大的功能是实现了与存储引擎交互,比如innodb,而这不需要任何sql方面的初始化开销。访问mysql的table时,当然也是需要open/close table的,但是它并不是每次都去open/close table,因为它会将以前访问过的table cache保存下来以重复使用,而opening/closing tables是最耗资源的,而且很容易引起互斥量的争夺,这样一来,对于提高性能非常有效。在流量变小时,handlersocket会close tables,所以它一般不会阻塞ddl。
handlersocket与mysql+memcached的区别在哪呢?对比图1-2和图1-3,可从中看出其不同点,图1-3展示了典型的mysql+memecached的应用架构。因为memcached的get操作比mysql的内存中或磁盘上的主键查询要快很多,所以memcached用于缓存数据库记录。若是handlersocket的查询速度和相应时间能与memcached媲美,我们就可以考虑替换memcached缓存记录的架构层。
(图1-3 典型mysql+memcached架构)
handlersocket的优势和缺陷阐述
handlersocket的优势和特点:
1) 支持多种查询模式
handlersocket目前支持索引查询(主键索引和非主键的普通索引均可),索引范围扫描,limit子句,也即支持增加、删除、修改、查询完整功能,但还不支持无法使用任何索引的操作。另外支持execute_multi() 一次网络传输多个query请求,节省网络传输时间。
2) 处理大量并发连接
handlersocket的连接是轻量级的,因为handlersocket采用epoll() 和worker-thread/thread-pooling架构,而mysql内部线程的数量是有限的(可以由my.cnf中的handlersocket_threads/handlersocket_threads_wr参数控制),所以即使建立上千万的网络连接到handlersocket,也不会消耗很多内存,它的稳定性不会受到任何影响(消耗太多的内存,会造成巨大的互斥竞争等其他问题,如bug#26590,bug#33948,bug#49169)。
3) 优秀的性能
handlersocket的性能见文章handlersocket的性能测试报告描述,相对于其它nosql产品,性能表现一点也不逊色,它不仅没有调用与sql相关的函数,还优化了网络/并发相关的问题:
(1). 更小的网络数据包:和传统 mysql 协议相比,handlersocket 协议更简短,因此整个网络的流量更小。
(2). 运行有限的mysql内部线程数:参考上面的内容。
(3). 将客户端请求分组:当大量的并发请求到达handlersocket时,每个工作线程尽可能多地聚集请求,然后同时执行聚集起来的请求和返回结果。这样,通过牺牲一点响应时间,而大大地提高性能。例如,可以减少fsync()调用的次数,减少复制延迟。
4) 无重复缓存
当使用memcached缓存mysql/innodb记录时,在memcached和innodb buffer pool中均缓存了这些记录,因此效率非常低(实际上有两份数据,memcached本身可能还需要做ha支持),而采用 handlersocket插件, 它直接访问 innodb 存储引擎,记录缓存在innodb buffer pool,于是其它sql语句还可以重复使用缓存的数据。
5) 无数据不一致的现象
由于数据只存储在一个地方(innodb存储引擎缓存区内),不像使用memcached时,需要在memcached和mysql之间维护数据一致性。
6) 崩溃安全
后端存储是innodb引擎,支持事务的acid特性,能确保事务的安全性,即使设置innodb_flush_log_at_trx_commit=2,若数据库服务器崩溃时,也只会丢掉
7) sql/nosql并存
在许多情况下,我们仍然希望使用sql(例如复杂的报表查询),而大多数nosql产品都不支持sql接口,handlersocket仅仅是一个 mysql 插件,我们依然可以通过mysql客户端发送sql语句,但当需要高吞吐量和快速响应时,则使用 handlersocket。
8) 继承mysql的功能
因为handlersocket运行于mysql,因此所有mysql的功能依然被支持,例如:sql、在线备份、复制、ha、监控等等。
9) 不需要修改/重建mysql
因为handlersocket是一个插件并且开源,所以它支持从任何mysql源码、甚至是第三方版本(例如percona)构建,而无需对mysql做出任何修改。
10) 独立于存储引擎
虽然我们只测试了mysql-enterpriseinnodb和percona xtradb插件,但handlersocket理论上可以和任何存储引擎交互。myisam通过简单的修改也是可以被支持的,但是从数据缓存而利用内存的角度看这个意义不大。
handlersocket的缺陷和注意事项
1) 协议不兼容
handlersocket api与memcached api并不兼容,尽管它很容易使用,但仍然需要一点学习来学会如何与handlersocket交互。不过我们可以通过重载memecached函数来翻译到handlersocket api。
2) 没有安全功能
与其它nosql数据库类似,handlersocket不支持安全功能,handlersocket的工作线程以系统用户权限运行,因此应用程序可以通过handlersocket协议访问所有的表对象,但是可以通过简单的修改协议,在my.cnf中增加一个配置项为密码,连接时通过这个配置的密码验证,当然也可以通过网络防火墙来过滤数据包。
3) 对于磁盘io密集的场景没有优势
对于io密集的应用场景,数据库每秒无法执行数千次查询,通常只有1-10%的cpu利用率,在这种情况下,sql解析不会成为性能瓶颈,因此使用handlersocket没有什么优势,应当只在数据完全装载到内存的服务器上使用 handlersocket。但是对于pci-e ssd(例如fusion-io)设备,每秒可以提供4w+ iops,并且io设备本身消耗cpu比较大,使用handlersocket依然具有优势。
handlersocket的性能测试
handlersocket oprofile测试报告
(mysql通过sql执行k/v查询的oprofile信息)
mysql执行sql语句,首先要经过sql解析阶段,调用mysqlparse() 和mysqllex() 进行语法和词法解析;然后进入查询优化阶段,调用make_join_statistics() 和join::optimize() 获得统计信息和生成执行计划,可以清洗第发现,主要耗资源的是sql解析和优化层,而不是innodb存储层,row_search_for_mysql只消耗了很少的时间。
因此我们对比memcached/nosql,知道mysql除了数据操作,还要很多额外的步骤需要完成:
1 parsing sql statements【解析sql】
2 opening, locking tables【打开并锁定表】
3 making sql execution plans sql【解析sql并生成执行计划】
4 unlocking, closing tables【解锁并关闭表】
另外,mysql 还必须要做大量的并发控制,比如在发送/接收网络数据包的时候,fcntl() 就要被调用很多次;global mutexes比如lock_open,lock_thread_count也被频繁地取得/释放。所以在oprofile的输出中,排在第二位的是my_pthread_fastmutex_lock()。并且mutex的竞争带来的上下文切换,导致%system占用cpu使用比例相当高(>20%)。
其实, mysql 开发团队和外围的开发团体早已意识到大量并发控制对性能的影响,mysql 5.5中已经解决了一些问题,percona也对mutex做了一些拆分处理,未来的mysql版本中,也应该会越来越好。
在完全内存操作的情况时,cpu的效率非常重要。如果只有一小部分数据进入内存,那么sql语句带来的消耗可以忽略不计。很简单,因为机械磁盘io操作的时间消耗远比cpu解析sql语句的时间消耗多,这种情况下,就不需要过分考虑sql语句所带来的消耗。但是对于ssd盘,尤其是pci-e ssd盘,响应时间在微秒级(fusion i/o为30us左右),就必须考虑sql带来的消耗了。
在大多数的mysql 服务器中,大部分的热点数据都缓存在内存中,因而访问变得只受cpu的限制。profiling 的结果就类似上所述的情况:sql 层消耗了大量的资源。假设需要做大量的pk查询(例如:select x from t where id=?)或者是做limit的范围查询,即使有70-80%都是在同一张表中做pk查询(仅仅只是查询条件中给定的值不同,即value不同而已), mysql 还是每次需要去做 parse/open/lock/unlock/close, 这对我们来说是非常影响效率的事情。
(mysql通过handlersocket执行k/v查询的oprofile信息)
handlersocket性能测试报告:
【测试主机】
机型:r510
cpu:intel(r) xeon(r) cpu e5520 @ 2.27ghz
内存:4g*6
磁盘:146g*2(os) + 300g*12 raid10(data)
1) 完全随机测试
测试场景描述:
单实例mysql 5.1.48 innodb plugin
测试sql:insert into table (key, value) values(#key#, #value#) / select value from table where key=#key#
hs api:execute_single
2) 重复获取同一条数据
测试场景描述:
1 单实例percona 5.1.57-12.8 xtradb
2 测试sql:select value from table where key=#key#
3 hs api:execute_single
4 mc api:get
其它类似信息

推荐信息