OneProxy :: 利用Query Cache的自动化缓存功能,实现网站性能的一键优化

OneProxy内置的Query Cache功能,可以不访问数据库直接返回SQL的查询结果,具有极高的性能,在12 Core的测试机器(实验室硬件条件有限)上,如果全部命中缓存,可以达到百万的QPS。如果OneProxy和应用程序布署在一起,效果则相当于是Client Cache了。在某个客户的PHP网站上,使用了Query Cache功能后,将一些执行比较慢的SQL全部缓存起来,有效地降低了数据库的压力,也提升了网站的访问速度,其慢SQL的缓存命中率达到20%的样子。

达到这个效果并不需要应用更改一行代码,也不需要DBA运行很多设置命令,只需要在管理端口中开启自动缓存优化功能,即执行一条如下命令:

mysql> set QCACHE_AUTOTUNE on;
Query OK, 0 rows affected (0.00 sec)

然后OneProxy将根据运行过程中收集到的SQL响应时间,自动挑选适合启用缓存的SQL语句,并自动设置缓存的有效时间,无须人工干预,DBA只需要边喝咖啡边观察数据库的压力变化即可,也可以在OneProxy的监控页面中查看哪些SQL被开启了自动缓存。自动缓存优化策略偏向于优化比较慢的SQL,其基本策略如下:

  • 对于执行比较快的SQL,默认是小于5ms的查询,并且重复执行率小于10倍的SQL语句,自动禁用查询缓存,让短平快的SQL语句直接查询数据库。得用OneProxy的读写分离功能,可以实现读流量的按需扩展。为了减少误判,会在执行一段时间后,才进行自动设置。
  • 对于执行比较慢的SQL,默认是大于100ms的查询,如果重复执行率大于1.2倍,则自动开启查询缓存,并且设置缓存有效时间为10个查询响应时间。对于慢查询,在一个监控周期(默认是10秒)后马上生效。
  • 对于已经开启了查询缓存的SQL,如果缓存效果不理想,则会自动加大缓存有效时间,但不会超过系统设置的最大缓存有效时间(默认为30秒),每次缓存时间的增幅为20%。
  • 对于已经开启查询缓存的SQL,如果缓存有效时间已经达到最大缓存有效时间,并且缓存的效果十分不理想(小于5%命中率),则禁用此SQL的缓存,以节约缓存维护成本和内存。
  • 对于主从复制时延超过5秒钟以上的从结点上的查询,并不会去更新缓存,从而可以确保缓存自动刷新时用的是比较新的数据快照。

客户应用中开启自动缓存功能,并经过一段时间(大约一小时左右),就可以看到缓存的效果了,一些执行很快的SQL都被打上了不缓存的标记,而绝大多数执行慢的查询语句,则被自动设上了较为合理的缓存时间,在内置的监控页面上也可以看到缓存的命中次数。客户的日均PV数在300万的样子,高峰时的缓存内存使用量大约在50MB的样子。

使用OneProxy的自动查询缓存功能的综合成本非常低,如果你的系统已经能接受读写分离,可以说是零成本。OneProxy的查询缓存功能,有如下特点:

  • 不需要更改应用代码,可以透明上线和下线;也不需要布署额外的组件,如Memcached、Redis等。
  • 对强制走主的SQL语句无效,仍从数据库查询(select /*master*/ …),不影响强一致性的查询请求。
  • 对事务中的SQL语句无效,仍从数据库查询,不影响强一致性的查询请求。
  • 在自动缓存策略下,仍可以人工调整SQL的缓存策略或时间,人工调整过的SQL不再受自动缓存策略影响。

在精心优化自动查询缓存策略的过程中,发现可以调计出一种新的主从流量分配策略,即根据SQL的响应时间,将慢SQL转发到从库去执行。在应对双十一的应用改造方案中,不少用户都计划在系统中增加Redis等缓存层,那么现在OneProxy的自动查询缓存,也可以充分考虑起来了。