|
|
# BIND 9 Memory Explained
|
|
|
|
|
|
## The Basics
|
|
|
|
|
|
BIND 9 basic memory management object is a memory context, the application can have as many as it is practical. There are two reasons for a separate memory context: a) logical separation - this includes both separate accounting, and different configuration, b) contention and speed - access to a memory context pinned on a specific thread will not be blocked by different threads.
|
|
|
|
|
|
## Limiting the memory use
|
|
|
|
|
|
The configuration options `max-cache-size` only affects the memory context in the cache and ADB (address database) - all other memory context are unrestrained. This means setting the `max-cache-size` to 100% would lead to OOM Reaper finding your BIND 9 process and killing it.
|
|
|
|
|
|
### BIND 9.11 and BIND 9.16 memory differences
|
|
|
|
|
|
There are two reasons why BIND 9.16 uses more memory than BIND 9.11:
|
|
|
|
|
|
The networking model has changed - in BIND 9.11 there was a single "listener" that would distribute the incoming work between idle threads. This simpler model would be slower, but because there was a single listener, it would also consume less memory.
|
|
|
Hybrid networking model - BIND 9.16 uses new networking code to receive and process incoming DNS messages (from clients), but it still uses old networking code for sending and processing outgoing DNS messages (to other servers). This means it needs to run double number of threads - there's a threadpool of workers for each function.
|
|
|
|
|
|
### BIND 9.16 and BIND 9.18
|
|
|
|
|
|
The memory usage in BIND 9.18 is again lower and similar to what the memory usage was in 9.11 because the part that sends and processes outgoing DNS message was refactored to use the new networking code and therefore uses half the number of threads that BIND 9.16 was using.
|
|
|
|
|
|
The other major change implemented in BIND 9.18 was replacement of the internal memory allocator with the jemalloc memory allocator. The internal memory allocator would keep pools of memory chunks for later reuse and would never free up the reserved memory. The jemalloc memory allocator is much better suited to the memory usage patterns that BIND 9 exhibits and is able to be both fast and memory efficient.
|
|
|
|
|
|
Our general recommendation for all deployments is to use jemalloc even with BIND 9.16 by forcing linkage via extra LDFLAGS (./configure LDFLAGS="-ljemalloc" should do the trick).
|
|
|
|
|
|
## Measuring Memory
|
|
|
|
|
|
Measuring the real memory usage can be tricky, but fortunately, there are some tools to help with that.
|
|
|
|
|
|
### Measuring Memory Internally
|
|
|
|
|
|
The statistics channel exposes counters about the memory contexts. The important values are 'InUse' and 'Malloced'. The difference between the two is that the InUse counter shows the memory used "externally" and 'Malloced' is the memory including the management overhead (the more memory contexts the more overhead there is).
|
|
|
|
|
|
### Measuring Memory Externally
|
|
|
|
|
|
The rule of thumb is "Don't use top command" - there are better tools that are less misleading. There are two tools the are easily available on modern Linux systems - pmap and smem.
|
|
|
|
|
|
#### pmap
|
|
|
|
|
|
pmap provides detailed statistics, but can be too chatty - the basic usage is `pmap -x -p <pid>`. It prints information about all pages used by the program which includes shared libraries, the program itself and heap. The important number is the last one "Dirty" - it shows the memory "used" by the BIND 9.
|
|
|
|
|
|
#### smem
|
|
|
|
|
|
smem provides less details, so if you want only "single" number run `smem -P named` and look for the USS column - this provides the information about memory used by the program sans the shared library. The PSS column adds shared libraries divided by the number of programs using those libraries, and RSS is the normal Resident Size.
|
|
|
|
|
|
### Differences
|
|
|
|
|
|
There are couple of explanations why the numbers reported by the BIND 9 statistics channel might differ from the memory usage reported by the operating system.
|
|
|
|
|
|
External libraries - BIND 9 uses several external libraries - OpenSSL, libuv, libxml2, json-c and possibly others. All these also need memory from the operating system to operate. The difference should not be large, but it's also not negligible. If the difference between the used memory reported by the internal statistics channel and USS is large (on a busy server), then congratulations, you've found a leak in external library. (NOTE: BIND 9.19 - the development version - provides own memory context for OpenSSL, libuv and libxml2 if the library versions are recent enough.)
|
|
|
Memory fragmentation - there's quite a churn in the memory allocations and deallocations on the busy server, and memory gets fragmented - the default Linux allocator isn't particulary good with the BIND 9 memory usage patters. Using jemalloc is strongly recommended as it handles the memory fragmentation much better and is also faster. |
|
|
\ No newline at end of file |