Skip to main content
RunBook Academy

CephLXXXII · Hyper-Converged CephHyper-Converged Ceph

Managing compute and storage contention

Advanced⏱ ~18 mincephqmsystemctl

What you'll learn

  • Identify the resources that contend
  • Measure contention as it occurs
  • Apply limits that bound each side
  • Verify the limits are effective

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

Compute and storage on one host contend for four resources, and each needs a different mechanism to bound.

The contended resources

ResourceVM demandOSD demandSymptom of contention
CPUguest executionI/O processing, checksumsOSD latency rises
Memoryguest allocationBlueStore cachehost swaps; both degrade
Storage devicesguest I/O via RBDOSD backing storeif co-located, severe
Networkguest trafficreplication and recoveryboth slow

The device row is the one to avoid entirely: VM disks and OSD data on the same physical devices is a configuration that should not exist.

Measuring contention

# CPU: is the OSD getting scheduled?
top -H -p $(pgrep -d, ceph-osd) -b -n 1 | head -20
mpstat -P ALL 1 5

# memory
free -g
ceph config get osd osd_memory_target
ceph daemon osd.0 dump_mempools | python3 -c '
import sys,json; d=json.load(sys.stdin)["mempool"]["by_pool"]
print("total:", sum(v["bytes"] for v in d.values()) // 1048576, "MiB")'

# is the host swapping at all?
vmstat 1 5 | awk 'NR>2 {print $7, $8}'
# correlate: VM CPU against OSD latency
ceph osd perf | sort -k2 -rn | head -3

Bounding the OSD side

ceph config set osd osd_memory_target 4294967296
ceph config set osd osd_max_backfills 1
ceph config set osd osd_mclock_profile high_client_ops
# CPU affinity via systemd
systemctl set-property ceph-osd@0.service AllowedCPUs=0-7
systemctl set-property ceph-osd@0.service CPUWeight=200

CPUWeight raises the OSD’s share under contention without pinning, which is usually preferable to hard affinity.

Bounding the VM side

# CPU limits per VM
qm set 100 --cpulimit 4 --cpuunits 100

# memory without ballooning surprises
qm set 100 --memory 16384 --balloon 0

# I/O limits per disk
qm set 100 --scsi0 ceph-vms:vm-100-disk-0,mbps_rd=200,mbps_wr=100,iops_rd=5000,iops_wr=2000

The per-disk I/O limits are what prevent one VM saturating the storage for every other, and they are rarely set by default.

Verifying the limits work

# generate load in a VM and watch OSD latency
# in the guest:
fio --name=load --rw=randwrite --bs=4k --iodepth=64 --runtime=300 --time_based

# on the host, concurrently:
watch -n 5 'ceph osd perf | sort -k2 -rn | head -3'

If OSD latency rises materially while one VM generates load, the limits are not effective and the numbers need tightening.

Acceptable: one VM at full allowed rate raises OSD latency modestly
Not acceptable: one VM raises cluster-wide latency for every other VM

Quiz

Knowledge check · 4 questions

  1. Q1. Why is `CPUWeight` usually preferable to hard CPU affinity for OSDs?

  2. Q2. Per-disk I/O limits on VMs are set by default in Proxmox.

  3. Q3. Bound contention on a hyper-converged cluster.

    A hyper-converged cluster shows storage latency spikes correlating with a batch job running in one VM. No VM I/O limits are configured.

  4. Q4. Which contended resource cannot be meaningfully separated by configuration?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Set per-disk mbps and iops limits on every VM as a baseline; without them one VM can saturate the shared OSDs for the entire cluster. Use CPUWeight rather than hard affinity for OSDs, and never place VM disks on the same physical devices as OSD data.

Cross-course references

  • Kubernetes: per-pod I/O limits are equally necessary and equally often omitted
  • Linux: cgroup weights suit contention better than hard CPU pinning