Using Linux KSM in uWSGI

Kernel Samepage Merging is a feature ofLinux kernels >= 2.6.32 which allows processes to share pages of memory withthe same content. This is accomplished by a kernel daemon that periodicallyperforms scans, comparisons, and, if possible, merges of specific memory areas.Born as an enhancement for KVM it can be used for processes that use common data(such as uWSGI processes with language interpreters and standard libraries).

If you are lucky, using KSM may exponentially reduce the memory usage of youruWSGI instances. Especially in massive Emperor deployments:enabling KSM for each vassal may result in massive memory savings.KSM in uWSGI was the idea of Giacomo Bagnoli of Asidev s.r.l.. Many thanks to him.

Enabling the KSM daemon

To enable the KSM daemon (ksmd), simply set /sys/kernel/mm/ksm/run to 1,like so:

  1. echo 1 > /sys/kernel/mm/ksm/run

Note

Remember to do this on machine startup, as the KSM daemon does not run bydefault.

Note

KSM is an opt-in feature that has to be explicitly requested by processes,so just enabling KSM will not be a savior for everything on your machine.

Enabling KSM support in uWSGI

If you have compiled uWSGI on a kernel with KSM support, you will be able touse the ksm option. This option will instruct uWSGI to register processmemory mappings (via madvise syscall) after each request or master cycle.If no page mapping has changed from the last scan, no expensive syscalls areused.

Performance impact

Checking for process mappings requires parsing the /proc/self/maps fileafter each request. In some setups this may hurt performance. You can tune thefrequency of the uWSGI page scanner by passing an argument to the ksmoption.

  1. # Scan for process mappings every 10 requests (or 10 master cycles)
  2. ./uwsgi -s :3031 -M -p 8 -w myapp --ksm=10

Check if KSM is working well

The /sys/kernel/mm/ksm/pages_shared and /sys/kernel/mm/ksm/pages_sharingfiles contain statistics regarding KSM’s efficiency. The higher values, theless memory consumption for your uWSGI instances.

KSM statistics with collectd

A simple Bash script like this is useful for keeping an eye on KSM’s efficiency:

  1. #!/bin/bash
  2.  
  3. export LC_ALL=C
  4.  
  5. if [ -e /sys/kernel/mm/ksm/pages_sharing ]; then
  6. pages_sharing=`cat /sys/kernel/mm/ksm/pages_sharing`;
  7. page_size=`getconf PAGESIZE`;
  8. saved=$(echo "scale=0;$pages_sharing * $page_size"|bc);
  9. echo "PUTVAL <%= cn %>/ksm/gauge-saved interval=60 N:$saved"
  10. fi

In your collectd configuration, add something likethis:

  1. LoadPlugin exec
  2. <Plugin exec>
  3. Exec "nobody" "/usr/local/bin/ksm_stats.sh"
  4. </Plugin>