ptmalloc(glibc的malloc)是Linux提供的内存分配管理模块,目前我们MySQL默认使用的内存分配模块。

tcmalloc是Google提供的内存分配管理模块。

jemalloc是FreeBSD提供的内存分配管理模块。

下面用sysbench对MySQL5.7.18搭配三种不同的内存分配管理模块做了压测。

【sysbench配置】

16个tables,单表数据量2500W,OLAP模式,预热时间600S,单次测试时间600S,每个场景测试5次。

【mysql配置】

关闭预热,buffer pool调整为16G,服务器物理内存64G

innodb_buffer_pool_load_at_startup=0

innodb_buffer_pool_size=16G

【测试数据】

QPS

ptmalloc2

tcmalloc4.1.0

jemalloc-5.0.1

warm up

8158.05

8720.78

8828.06

Threads 16

8788.19

8755.96

9976.9

Threads 32

13481.61

11908.99

13559.32

Threads 64

15722.35

15678.27

17015.05

Threads 128

17957.68

17929.17

19665.71

TPS

ptmalloc2

tcmalloc4.1.0

jemalloc-5.0.1

warm up

453.22

484.47

490.44

Threads 16

488.21

486.43

554.25

Threads 32

748.96

661.59

753.28

Threads 64

873.43

870.99

945.24

Threads 128

997.57

996.02

1092.42

 

ptmalloc

tcmalloc

jemalloc

VmRSS:

2259272

2325520

2899384

VmRSS:

4942224

4205684

3990556

VmRSS:

7351488

6668696

6585080

VmRSS:

9703240

9031616

9027632

VmRSS:

12005820

11318512

11479836

VmRSS:

14261672

13639416

13845412

VmRSS:

16467972

15919476

16175976

VmRSS:

18358520

18111000

18443324

VmRSS:

18366840

18403856

18649424

VmRSS:

18368820

18404236

18650740

VmRSS:

18368504

18406144

18650896

VmRSS:

18467844

18492448

18718692

VmRSS:

18469004

18492880

18719844

VmRSS:

18469268

18493016

18720412

VmRSS:

18469796

18493568

18721692

【图形展示】

【原创】MySQL5.7.18(ptmalloc VS tcmalloc VS jemalloc)性能测试-LMLPHP

【原创】MySQL5.7.18(ptmalloc VS tcmalloc VS jemalloc)性能测试-LMLPHP

【原创】MySQL5.7.18(ptmalloc VS tcmalloc VS jemalloc)性能测试-LMLPHP

【结论】

1、jemalloc在多线程高并发环境下,随着并发线程数的增加,QPS和TPS增长比较稳定,性能高于ptmalloc和tcmalloc。

2、在目前的压测场景下,随着线程数的增加,MySQL进程占用的物理内存并没有太大的差异。

3、关于jemalloc的应用,相对tcmalloc而言,jemalloc是MariaDB,Redis等默认的内存分配管理模块,另外AliSQL也集成了jemalloc。

【附录】

1、下图是其他机构的一个测试报告(针对较早之前的版本),最左边的是glibc的ptmalloc,最右边的就是jemalloc,

可以看到jemalloc和tcmalloc的性能差异不大,jemalloc的效率稍高。

【原创】MySQL5.7.18(ptmalloc VS tcmalloc VS jemalloc)性能测试-LMLPHP

2、三者的比较

ptmalloc2

tcmalloc4.1.0

jemalloc-5.0.1

ptmalloc的缺陷

  • 后分配的内存先释放,因为 ptmalloc 收缩内存是从 top chunk 开始,如果与 top chunk 相邻的 chunk 不能释放, top chunk 以下的 chunk 都无法释放。
  • 多线程锁开销大, 需要避免多线程频繁分配释放。
  • 内存从thread的areana中分配, 内存不能从一个arena移动到另一个arena, 就是说如果多线程使用内存不均衡,容易导致内存的浪费。 比如说线程1使用了300M内存,完成任务后glibc没有释放给操作系统,线程2开始创建了一个新的arena, 但是线程1的300M却不能用了。
  • 每个chunk至少8字节的开销很大
  • 不定期分配长生命周期的内存容易造成内存碎片,不利于回收。 64位系统最好分配32M以上内存,这是使用mmap的阈值。

tcmalloc的改进

  • ThreadCache会阶段性的回收内存到CentralCache里。 解决了ptmalloc2中arena之间不能迁移的问题。
  • Tcmalloc占用更少的额外空间。例如,分配N个8字节对象可能要使用大约8N * 1.01字节的空间。即,多用百分之一的空间。Ptmalloc2使用最少8字节描述一个chunk。
  • 更快。小对象几乎无锁, >32KB的对象从CentralCache中分配使用自旋锁。 并且>32KB对象都是页面对齐分配,多线程的时候应尽量避免频繁分配,否则也会造成自旋锁的竞争和页面对齐造成的浪费。

jemalloc的优化

  • Jmalloc小对象也根据size-class,但是它使用了低地址优先的策略,来降低内存碎片化。
  • Jemalloc大概需要2%的额外开销。
  • Jemalloc和tcmalloc类似的线程本地缓存,避免锁的竞争
  • 相对未使用的页面,优先使用dirty page,提升缓存命中。

参考资料:

ptmalloc,tcmalloc和jemalloc内存分配策略研究

http://www.360doc.com/content/13/0915/09/8363527_314549128.shtml

内存优化总结:ptmalloc、tcmalloc和jemalloc

http://www.cnhalo.net/2016/06/13/memory-optimize/

【原创】MySQL5.7.18(ptmalloc VS tcmalloc VS jemalloc)性能测试-LMLPHP

05-08 08:08