IT技术博客大学习 共学习 共进步

Row Cache For Innodb

淘宝JAVA中间件团队博客 2011-09-14 13:35:00 浏览 3,901 次
  • 最近在做MySQL的优化,看到现在MySQL分表分库后导致的内存利用率较低的问题,进行了优化,如果你也有类似的问题,可以试试下面的Patch
  • Patch下载: http://code.google.com/p/row-cache-for-innodb/
  • 问题
  • 当一个MySQL存不下全部的数据时,那么分库分表是一种常规的解决方案.但是一旦分库分表之后,关系型数据库对应的关系实际上被弱化了,很多查询不得不转换为类似K-V的查询.一般情况下为了使分库分表的数据尽量的平均都采用去模(mod)的算法来分配数据,这样就导致热门数据也会很离散的分布在各个表的各个区段上,分布很离散.  而Innodb的Buffer Pool则是按Page(默认为16k大小)来进行缓存,那么可能热门数据只占16k中的2k甚至更少(对于辅助索引来说会更少,可能只有几百个字节),那么被载入到Buffer Pool中的数据会被读取的可能就很少了,也就是说Buffer Pool的内存利用率是很低的.
  • 解决
  • 既然是由于Buffer Pool无差别缓存一个Page导致内存利用率低,那么我们可以直接缓存row来提高内存利用率. 所以Row Cache For Innodb就诞生了. Row_Cache 在Buffer Pool之上再建一层缓存.在innodb访问B-Tree的时候判断索引是唯一索引,且查询条件是唯一查询的时候(就是典型的K-V查询)便会进入到Row Cache的查找逻辑中. 由于只缓存Row内存利用率会很高,即能缓存的热门数据会比Buffer Pool多很多. 按照压测的结果来看240w的热门数据(数据分布较离散) 使用18G的Buffer Pool是无法完全载入到内存的.导致随机select数据还会有大量的IO操作存在QPS维持在一个较低的水平.但是使用Row Cache后240w的数据只使用了5G内存就能全部载入到内存中,QPS能提升几倍
  • 额外收货
  • Row Cache使用Hash算法+LRU算法进行缓存数据的管理,所以将原来Buffer Pool中的B-Tree查询转化为Hash-Table的查询,使数据能被较快命中,节省了CPU使用也提升了响应时间
  • Row Cache中的Hash-Table管理采用区段锁而非Buffer Pool的单一全局锁,降低了锁竞争而导致的上下文切换.而且对LRU 和 内存池 也和Hash-Table区段对应,各个区段独立维护各自的资源
  • 适合的使用场景
  • 查询以K-V形式为主 类似 select * from table where key = ? 这样的查询,而且key字段需要建唯一索引
  • 读>写
  • 热门数据较集中,且基本都能放在内存中
  • Row Cache和handlersocket配合应该是不错的选择
  • 性能测试
  • 使用了淘宝某核心系统对Row Cache的效果进行了性能测试和稳定性测试.
  • 机器配置:
  • CPU:16核的Xeon(R) E5520  @ 2.27GHz
  • 内存:24G
  • 硬盘: 12个盘的RAID10
  • MySQL版本: 5.1.48版本使用innodb_plugin 1.0.9
  • 测试场景
  • 8000w的基准数据(实际Row不止,还有这些基准数据对应的扩展数据,路由数据,全部加起来有近10亿数据),240w的热门数据(相对基准数据而言),对热门数据进行随机访问和更新删除插入等操作
  • 读写比为100:1的混合测试, 这是比较典型的互联网应用
  • 测试结果(上图是只使用18G Buffer Pool的结果,下图为使用5G Row Cache + 13G Buffer Pool的结果)
  • 全部Statement的对比
  • 可以看到等稳定后 QPS是原来的3倍以上
  • 对update/insert/delete操作的对比
  • Update
  • Insert
  • Delete
  • 可以看到在使用Row Cache后对于Update/Insert/Delete这样的操作TPS也提升了一倍有余
  • 虽然Row Cache是针对Select操作的优化,但是当Row Cache为Select剩下大量IOPS之后,这些IOPS可以被利用到Update/Insert/Delete这样的操作上,间接是TPS也获得了提升.
  • CPU/Iowait对比
  • CPU
  • Iowait
  • 从CPU的走势可以看出当使用Row Cache后其命中率达到一定的层次后,IO资源会被释放,CPU占主导地位,由于使用Row Cache后QPS较高所以上图中CPU较高但相对BP而言,Row Cache将B-Tree查询转化为Hash-Table查询反而是节省了CPU资源,提高了响应时间
  • 缺点
  • 从上面的图可以看出,使用Row Cache后预热时间大大加长,由于Buffer Pool一次读进16k数据,而Row Cache则是一条条row进行读取,需要花较长的时间才能达到较高的缓冲命中率,从而才能发挥Row Cache的威力
  • 如果大家对Row Cache感兴趣可以到 http://code.google.com/p/row-cache-for-innodb/downloads/list 上下载patch来试用一把
  • 安装和使用说明见 http://code.google.com/p/row-cache-for-innodb/wiki/Installation
  • 建议继续学习

    1. Innodb IO优化-配置优化 (阅读 7,603)
    2. Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读 7,565)
    3. Innodb 表和索引结构 (阅读 6,041)
    4. InnoDB线程并发检查机制 (阅读 5,601)
    5. Innodb如何使用内存 (阅读 5,101)
    6. Innodb文件表空间结构 (阅读 5,062)
    7. 快速预热Innodb Buffer Pool的方法 (阅读 4,981)
    8. InnoDB的缓存替换策略及其效果 (阅读 4,781)
    9. 多版本并发控制:PostgreSQL vs InnoDB (阅读 4,561)
    10. InnoDB之Dirty Page、Redo log (阅读 4,481)