As Per digitalocean's Article :
Transparent Huge Pages and Alternative Memory Allocators: A Cautionary Tale
Recently, our site reliability engineering team started getting
alerted about memory pressure on some of our Redis instances which
have very small working sets.1 As we started digging into the issue,
it became clear that there were problems with freeing memory after
initial allocation because there were a relatively small number of
keys but a comparatively large amount of memory allocated by
redis-server processes. Despite initially looking like a leak, the
problem was actually an issue between an alternative memory allocator
and transparent huge pages.
Why the need of Disabling THP required ?
This rabbit hole began when a redis-server
process, which had recently been moved over to LD_PRELOAD jemalloc.so
, began using significant amounts of memory. Initial signs pointed to the fact that using an alternative allocator might be part of the issue, so that's where we started digging.
It turns out that jemalloc(3)
uses madvise(2)
extensively to notify the operating system that it's done with a range of memory which it had previously malloc
'ed. Because the machine used transparent huge pages, the page size was 2MB. As such, a lot of the memory which was being marked with madvise(..., MADV_DONTNEED)
was within ranges substantially smaller than 2MB. This meant that the operating system never was able to evict pages which had ranges marked as MADV_DONTNEED
because the entire page would have to be unneeded to allow it to be reused.
So despite initially looking like a leak, the operating system itself was unable to free memory because of madvise(2)
and transparent huge pages. This led to sustained memory pressure on the machine and redis-server
eventually getting OOM killed.
As Per Redis Latency Problems Troubleshooting Documentation :
Transparent huge pages must be disabled from your kernel.
Use echo never > /sys/kernel/mm/transparent_hugepage/enabled
to disable them,
and restart your Redis process.
Latency induced by transparent huge pages
Unfortunately when a Linux kernel has transparent huge pages enabled,
Redis incurs to a big latency penalty after the fork call is used in
order to persist on disk. Huge pages are the cause of the following
issue:
- Fork is called, two processes with shared huge pages are created.
- In a busy instance, a few event loops runs will cause commands to target a few thousand of pages, causing the copy on write of almost
the whole process memory.
- This will result in big latency and big memory usage.