在InnoDB刚刚被开发的时候,当时多核CPU还并不是这么流行,当时也并没有针对多核CPU优化的内存分配器(memory allocator libraries ),所以InnoDB实现了一个自己的内存分配子系统(mem subsystem),这个子系统是通过单个互斥量(mutex)实现管理的,而这可能是一个瓶颈。除此,InnoDB还对OS自带的内存分配管理 (malloc和free)作了一次简单封装,这些管理函数实现也类似地通过互斥量的机制实现的,所以这并没有解决问题。
从MySQL5.5.X版本开始,用户可以控制InnoDB 是使用自带的内存分配程序,还是使用当前部署的操作系统中现有的更高效的内存分配程序。通过在 MySQL 5.5 选项文件my.cnf 中设置新的系统配置参数 innodb_use_sys_malloc,可方便地进行控制。默认设置值为1,表示InnoDB使用操作系统的内存分配程序。
TCMalloc(Thread-Caching Malloc )是google开发的开源工具──“google-perftools” 中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
下面介绍下TCMalloc的安装和使用:
安装libunwind(32位操作系统忽略此步骤)
# vi /usr/local/mysql/bin/mysqld_safe
在# executing mysqld_safe的下一行,加入以下内容 export LD_PRELOAD=/usr/local/lib/libtcmalloc.so |
重启MySQL服务
# service mysqld restart
使用lsof命令查看tcmalloc是否生效
# lsof -n |grep tcmalloc
如果可以显示类似下列信息,则表明MySQL已经成功加载tcmalloc
mysqld 13093 mysql mem REG 253,0 2070229 936032 /usr/local/lib/libtcmalloc.so.0.1.0 |
下面,我用SysBench压力测试了两种内存管理模式的性能对比。 由于是虚拟机,SysBench参数设置的很小:
#!/bin/bash
i=1 while true do while [ $i -le 1000 ] do /usr/local/bin/sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=10000 --max-requests=100 --num-threads=6 -- mysql-host=192.168.110.140 --mysql-port=3306 --mysql-user=admin --mysql-password=123456 --mysql-db=test --mysql-socket=/tmp/ mysql.sock run >> semi_replication.txt let i++ done break done |
系统:Red Hat Enterprise Linux Server release 6.0 (Santiago) 内核:2.6.32-71.el6.x86_64
左边是使用InnoDB自带的内存分配程序 中间是使用谷歌的TCMalloc内存分配程序 右边是使用系统自带的Malloc内存分配程序
结论:从结果上看,使用谷歌的TCMalloc内存分配程序对系统的压力相对要小一些。当然如果是真正的物理机,性能的差异会更明显,有兴趣的读者可以一试,期待着你的测试结果。
参见MySQL5.5手册:
13.7.7.3. Using Operating System Memory Allocators
When InnoDB was developed, the memory allocators supplied with operating systems and run-time libraries were often lacking in performance and scalability. At that time, there were no memory allocator libraries tuned for multi-core CPUs. Therefore, InnoDB implemented its own memory allocator in the mem subsystem. This allocator is guarded by a single mutex, which may become a bottleneck. InnoDB also implements a wrapper interface around the system allocator (malloc and free) that is likewise guarded by a single mutex.
Today, as multi-core systems have become more widely available, and as operating systems have matured, significant improvements have been made in the memory allocators provided with operating systems. New memory allocators perform better and are more scalable than they were in the past. The leading high-performance memory allocators include Hoard, libumem, mtmalloc, ptmalloc, tbbmalloc, and TCMalloc. Most workloads, especially those where memory is frequently allocated and released (such as multi-table joins), benefit from using a more highly tuned memory allocator as opposed to the internal, InnoDB-specific memory allocator.
|