您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

MySQL如何才能提高响应速度

2024/6/6 3:20:44发布38次查看
mysql自身的局限性,很多站点都采用了mysql+memcached的经典架构,甚至一些网站放弃mysql而采用nosql产品。不可否认,在做一些简单查询(尤其是pk查询)的时候,很多nosql产品比mysql要快很多。
一、概述
二、应用场景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对内存的一把大锁限制了它的并发能力。
innodb引擎、按主键、unique key或索引搜索(也就是说它的sql的where条件必须是这些);支持limit 语句、in、insert/update/delete。
没有主键、unique key或索引搜索不行!
表必须是innodb引擎
handlersocket和nosql这两者主要的使用场景不同。handlersocket主要是用于改善mysql,优化表格的增删改查以及表格的结构修改等操作,支持密集型cpu操作;而nosql作为缓存的功能,支持密集型i/o的操作。
因此,当有需要的时候,可以结合这两者共同工作。
三、原理handlersocket是mysql的一个插件,集成在mysqld进程中;nosql无法实现的复杂查询等操作,仍然使用mysql自身的关系型数据库实现。在运维层面,原来广泛使用的mysql主从复制等经验继续发挥作用,相比其他nosql产品,数据安全更有保障,原理如图:
可以看出,handlersocket绕过mysql的sql解析层(sql layer),直接访问mysql存储层。另外,handlersocket采用epoll和worker thread/thread pooling网络架构,性能更高。
mysql的架构是“数据库管理”和“数据管理”分离,即mysql server+storage engine的模式。mysql server是直接与client交互的一层,它负责管理连接线程,解析sql生成执行计划,管理和实现视图、触发器、存储过程等这些与具体数据操作管理无关的事情,通过调用handler api让存储引擎去操作具体的数据。storage engine通过继承实现handler api的函数,负责直接与数据交互,数据存取实现(必须实现),事务实现(可选),索引实现(可选),数据缓存实现(可选)。
handlersocket是在mysql的内部组件,以mysql daemon plugin的形式提供类似nosql的网络服务,它并不直接处理数据,只是侦听配置好的某个端口方式,接收采用nosql/api的通讯协议,然后通过mysql内部的handler api来调用存储引擎(例如innodb)处理数据。理论上,handersocket可以处理各种mysql存储引擎,但是用myisam时,会出现插入的数据查不出来,这个实际上是构造行时第一字节没有初始化为0xff,初始化以后就没有问题,myisam也一样可以支持,但是为了更好地利用内存,用handlersocket都会搭配innodb存储引擎一起使用。
从上图可以看出,handlersocket作为mysql客户端和mysql的中间层,取代mysql原生的部分数据、表格处理工作,采用多线程的方式,区分ddl和dml进行操作。这样的目的是保证在复杂处理的情况下,能够高效的进行处理。
因为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缓存记录的架构层。
四、优势劣势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相关的函数,还优化了网络/并发相关的问题:
更小的网络数据包:和传统 mysql 协议相比,handlersocket 协议更简短,因此整个网络的流量更小。
运行有限的mysql内部线程数:参考上面的内容。
将客户端请求分组:当大量的并发请求到达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,若数据库服务器崩溃时,也只会丢掉<= 1s的数据。
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依然具有优势。
五、安装注意:书上的安装方式已经过时了,版本也较低,不建议使用,建议使用官方的文档进行安装,github地址:https://github.com/dena/handlersocket-plugin-for-mysql
安装文档:https://github.com/dena/handlersocket-plugin-for-mysql/blob/master/docs-en/installation.en.txt
下载源码:可以通过github直接git clone或者是下载也行
安装步骤:
1. build handlersocket
./autogen.sh./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
注意:
with-mysql-source:mysql源代码目录with-mysql-bindir:mysql二进制可执行文件目录(mysql_config所在目录)with-mysql-plugindir:mysql插件目录2. 编译
make && make install
3. 配置
编译之后handlesocket还不能使用,还需要在mysql配置文件(my.cnf)中增加以下配置:
[mysqld]# 绑定读请求端口loose_handlersocket_port = 9998# 绑定写请求端口loose_handlersocket_port_wr = 9999# 读请求线程数loose_handlersocket_threads = 16# 写请求线程数loose_handlersocket_threads_wr = 16# 设置最大接收连接数open_files_limit = 65535
这里增加的这些主要是针对handlesocket的配置,它有两个端口,9998读数据,9999写数据,但通过9998读的效率更高,这里设置处理读写的线程数均为16个,另外为了处理更多并发连接,设置能打开的文件描述符个数为65535
此外,innodb的innodb_buffer_pool_size或myisam的key_buffy_size配置选项关系到缓存索引,所以尽可能设置大一些,这样才能发挥handlesocket的潜力。
4. 激活handlesocket
登陆mysql执行
mysql> install plugin handlersocket soname 'handlersocket.so';
可以通过show processlist或show plugins来看到handlesocket
最后需要安装php的扩展包php handlersocket
安装文档:https://github.com/tz-lom/hsphp
php用法:
select
<?php $c = new \hsphp\readsocket();$c->connect();$id = $c->getindexid('data_base_name', 'table_name', '', 'id,name,some,thing,more');$c->select($id, '=', array(42)); // select with primary key$response = $c->readresponse();//select with in statement$c = new \hsphp\readsocket();$c->connect();$id = $c->getindexid('data_base_name', 'table_name', '', 'id,name,some,thing,more');$c->select($id, '=', array(0), 0, 0, array(1,42,3));$response = $c->readresponse();
update
<?php$c = new \hsphp\writesocket();$c->connect('localhost',9999);$id = $c->getindexid('data_base_name','table_name','','k,v');$c->update($id,'=',array(100500),array(100500,42)); // update row(k,v) with id 100500 to k = 100500, v = 42$response = $c->readresponse(); // has 1 if ok$c = new \hsphp\writesocket();$c->connect('localhost',9999);$id = $c->getindexid('data_base_name','table_name','','k,v');$c->update($id,'=',array(100500),array(100500,42), 2, 0, array(100501, 100502)); // update rows where k in (100501, 100502)$response = $c->readresponse(); // has 1 if ok
delete
<?php$c = new \hsphp\writesocket();$c->connect('localhost',9999);$id = $c->getindexid('data_base_name','table_name','','k,v');$c->delete($id,'=',array(100500));$response = $c->readresponse(); //return 1 if ok
insert
<?php$c = new \hsphp\writesocket();$c->connect('localhost',9999);$id = $c->getindexid('data_base_name','table_name','','k,v');$c->insert($id,array(100500,'test\nvalue'));$response = $c->readresponse(); //return array() if ok
相关推荐:《mysql教程》
以上就是mysql如何才能提高响应速度的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product