为什么Redis要关闭THP?

在Linux下Redis启动时可能会看到如下警告日志:


WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.


从提示看Redis建议关闭Transparent Huge Pages(THP)。

那么什么是Transparent Huge Pages(THP)(透明大页)呢?

在说THP之前先说一下Hugepages(注意:大页(Huge Pages和透明大页(Transparent Huge Pages)有区别)

内存是由块管理,即众所周知的页面。在Linux 64位系统里面,默认内存是以4K的页面(Page)来管理的。也就是说一个页面有 4096 字节。1MB 内存等于 256 个页面。2MB内存等于512个页面。如果是一个比较大的服务器内存,那么管理大内存管理需要形成的页面列表(相当于索引表)就很大,CPU 有内嵌的内存管理单元TLB,这些单元中包含这些页面列表,每个页面都使用页表条目。页表(Page Table)用来存放虚拟内存和物理内存页对应关系的内存结构。如果page size较小,那么相应的页表内存结构就会比较大。而Hugepages的默认值page size为2M,是4KB的500倍,所以可以大大减小Page Table的大小。通过启用 HugePages使用大页面,可以用一个页表条目代表一个大页面,而不是使用许多条目代表较小的页面,从而可以管理更多内存,减少操作系统对页面状态的维护并提高 TLB 缓存命中率。注意,Hugepagesize的大小默认为2M,这个也是可以调整的。区间范围为2MB to 256MB。

标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。相信有不少人将Huge Page和Transparent Huge Pages混为一谈。目前透明大页与传统HugePages联用会出现一些问题,导致性能问题和系统重启。Oracle 建议禁用透明大页(Transparent Huge Pages)。在 Oracle Linux 6.5 版中,已删除透明 HugePages。

透明大页除了机制问题以外,在增大页面大小缩小页面索引列表这点上是一样的原理。

为什么Redsi使用透明大页会存在问题?

这里就涉及到Redis在持久化AOF过程中都存在创建子进程的情况。

Redis 在AOF持久化过程中会fork一个子进程进行AOF操作。这块又涉及到一个fork过程的CopyOnWrite机制。

copy-on-write技术,在fork出子进程后,与父进程共享内存空间,两者只是虚拟空间不同,但是其对应的物理空间是同一个;

这里有两个关键地方:

      ①fork子进程会拷贝父进程的页面索引列表,如果索引列表小,那么fork拷贝的内存就会小,那么fork子进程的速度就会快。

      ②当fork()之后,kernel把父进程中所有的内存页的权限都设为read-only,然后子进程的地址空间指向父进程。当父子进程都只读内存时,相安无事。当其中某个进程写内存时,CPU硬件检测到内存页是read-only的,于是触发页异常中断(page-fault),陷入kernel的一个中断例程。中断例程中,kernel就会把触发的异常的页复制一份,于是父子进程各自持有独立的一份。如果使用大页每次有页面要修改,那么就要拷贝一个2MB的大页面,会大幅增加重Redis写期间父进程内存消耗。同时每次写命令引起的复制内存页单位为2MB,会拖慢写操作的执行时间,导致大量写操作慢查询,

所以除了“透明大页与传统HugePages联用会出现一些问题,导致性能问题和系统重启"外,上面这两点是Redis建议关闭THP的更重要的原因。

你可能感兴趣的:(为什么Redis要关闭THP?)