Running uWSGI in a Linux CGroup

Linux cgroups are an amazing feature available in recent Linux kernels. Theyallow you to “jail” your processes in constrained environments with limitedCPU, memory, scheduling priority, IO, etc..

Note

uWSGI has to be run as root to use cgroups. uid and gid are very, very necessary.

Enabling cgroups

First you need to enable cgroup support in your system. Create the /cgroupdirectory and add this to your /etc/fstab:

  1. none /cgroup cgroup cpu,cpuacct,memory

Then mount /cgroup and you’ll have jails with controlled CPU and memory usage.There are other Cgroup subsystems, but CPU and memory usage are the most usefulto constrain.

Let’s run uWSGI in a cgroup:

  1. ./uwsgi -M -p 8 --cgroup /cgroup/jail001 -w simple_app -m --http :9090

Cgroups are simple directories. With this command your uWSGI server and itsworkers are “jailed” in the ‘cgroup/jail001’ cgroup. If you make a bunch ofrequests to the server, you will see usage counters – cpuacct. andmemoryfiles. in the cgroup directory growing. You can also use pre-existingcgroups by specifying a directory that already exists.

A real world example: Scheduling QoS for your customers

Suppose you’re hosting apps for 4 customers. Two of them are paying you $100 amonth, one is paying $200, and the last is paying $400. To have a good Qualityof Service implementation, the $100 apps should get 1/8, or 12.5% of your CPUpower, the $200 app should get 1/4 (25%) and the last should get 50%. Toimplement this, we have to create 4 cgroups, one for each app, and limit theirscheduling weights.

  1. ./uwsgi --uid 1001 --gid 1001 -s /tmp/app1 -w app1 --cgroup /cgroup/app1 --cgroup-opt cpu.shares=125
  2. ./uwsgi --uid 1002 --gid 1002 -s /tmp/app2 -w app1 --cgroup /cgroup/app2 --cgroup-opt cpu.shares=125
  3. ./uwsgi --uid 1003 --gid 1003 -s /tmp/app3 -w app1 --cgroup /cgroup/app3 --cgroup-opt cpu.shares=250
  4. ./uwsgi --uid 1004 --gid 1004 -s /tmp/app4 -w app1 --cgroup /cgroup/app4 --cgroup-opt cpu.shares=500

The cpu.shares values are simply computed relative to each other, so youcan use whatever scheme you like, such as (125, 125, 250, 500) or even (1, 1,2, 4). With CPU handled, we turn to limiting memory. Let’s use the samescheme as before, with a maximum of 2 GB for all apps altogether.

  1. ./uwsgi --uid 1001 --gid 1001 -s /tmp/app1 -w app1 --cgroup /cgroup/app1 --cgroup-opt cpu.shares=125 --cgroup-opt memory.limit_in_bytes=268435456
  2. ./uwsgi --uid 1002 --gid 1002 -s /tmp/app2 -w app1 --cgroup /cgroup/app2 --cgroup-opt cpu.shares=125 --cgroup-opt memory.limit_in_bytes=268435456
  3. ./uwsgi --uid 1003 --gid 1003 -s /tmp/app3 -w app1 --cgroup /cgroup/app3 --cgroup-opt cpu.shares=250 --cgroup-opt memory.limit_in_bytes=536870912
  4. ./uwsgi --uid 1004 --gid 1004 -s /tmp/app4 -w app1 --cgroup /cgroup/app4 --cgroup-opt cpu.shares=500 --cgroup-opt memory.limit_in_bytes=1067459584