Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deployment

A busy-spinning thread is only as fast as its host. Start with Kubernetes HFT tuning: one table of every setting, where it goes (node or pod) and its evidence.

pagefor
Kubernetes HFT tuningstart here: the settings table, the measured runs, copy-paste blocks, three checks
AWS and Azure hosts, x86 and Gravitonhow to apply each node setting on a VM or node
Kuberneteswhole cores, no CPU quota, SMT off, the node bootstrap; the EKS manifests
Benchmarks: x86 and Gravitonwhich platform: latency and cost per hour, side by side
Java for Archive and Clusterthe JVM and Aeron settings for Archive and Cluster
Latency podsthe five grants a normal pod cannot make
Shared CPUsk8s/nri-shared-cpus: exclusive CPUs plus the node’s shared ones
Clockswhich clock to read, and time sync on the node

The DPDK transport in this repository is a proof of concept.

Glossary

Network, memory, cloud and measuring terms: DPDK chapter’s glossary. Host, Kubernetes and Java terms:

termwhat it ispros / cons, when it matters
C-statehow deeply an idle CPU sleepsdeeper saves power but wakes later. A spinning core never idles; capping is mixed (C-states)
timer tick, RCU callbackskernel work on every CPU: a regular timer interrupt; deferred clean-upisolcpus keeps tasks off, nohz_full stops the tick, rcu_nocbs moves the callbacks (isolation)
interrupt affinity, irqbalancethe CPUs an interrupt may run on; irqbalance is a daemon that moves interrupts aroundstop irqbalance, pin interrupts to housekeeping, pin again after every NIC reset
IOMMU passthroughIOMMU: the unit that checks which memory a device may reach. Passthrough (iommu=pt; Graviton iommu.passthrough=1) skips it for the host’s own driverslets igb_uio work on metal; harmless on a VM
NUMA nodea group of cores and the memory nearest themkeep a pod’s CPUs and devices on one; every lab host had only one
KSM, NUMA balancingkernel background work: merging identical pages; moving pages nearer the CPU that uses themKSM merges only memory marked mergeable (MADV_MERGEABLE), which Aeron and ergon-io do not mark; NUMA balancing matters only with several NUMA nodes. The EKS node turns both off. Not measured here
spin testspin on every CPU for two minutes; note any that stall 300 µs or morea node-level check: a pod cannot choose its cores. Not measured here
-march, -mcpu, target-cpucompiler options that build for one CPU: -march, -mcpu (C), target-cpu (Rust). On AArch64 only -mcpu sets the coreGraviton: without them, gcc calls a library helper for each atomic add
clocksource=tsc, tsc=reliableboot options: the kernel keeps time with the CPU counter, and tsc=reliable turns its runtime checks offit turns the kernel’s TSC checks off. The EKS node takes it only on bare metal with RUSTERON_FORCE_TSC=1, never on a VM, and records the choice (node/provision-node.sh)
wall clock, NTP, PTPthe time of day (UTC), kept right by chrony over the network (NTP) or from a hardware clock (PTP)pro: matches other hosts and NIC stamps. Con: a correction can step it back; time intervals with quanta or Instant
kubeletthe agent on each Kubernetes node that starts pods and gives them CPUs, memory and devicesit must be told to give whole cores
Guaranteed QoSa pod whose requests equal its limits on every resourceonly these, with whole CPUs, get cores of their own from the static CPU manager
SMT (hyper-threading)two logical CPUs on one physical core, sharing its execution resourcesa pod with cpu: 1 shares the core with its twin. Turn SMT off on x86 latency nodes: one CPU is then one core, as on Graviton
CPU quota (CFS quota)a container’s CPU limit as the kernel applies it: at most the quota of CPU time in each 100 ms perioda busy-spinning thread runs at the cap; when it is used up the kernel stops the whole container until the period ends. On kubelet 1.33+ the quota goes away by itself for a container with exclusive CPUs; do not turn it off for the whole node
static CPU manager, topology managerkubelet policies: whole cores for Guaranteed pods; a pod’s CPUs and devices on one NUMA nodewith full-pcpus-only, no hyperthread is shared with another pod
cpusetthe CPUs a pod may run onpin each busy thread to its own CPU from it (Cpus_allowed_list)
DaemonSetone pod on every matching nodehere, one media driver per DPDK node
device plugina node service that offers devices to pods as a resourcehere, ENA pairs bound to igb_uio
taint, toleration, nodeSelectora taint keeps pods off a node unless the pod tolerates it; a nodeSelector sends a pod to labelled nodestogether: only latency pods (and the DaemonSets that must run there) land on latency nodes
LimitRange, ResourceQuotanamespace defaults and caps: a LimitRange gives every container a default CPU request and limit; a ResourceQuota caps the namespacean unlabelled pod cannot then ask for half a node (keep other pods in check)
PriorityClasshow important a pod is: a higher class preempts a lower onegive latency pods a high class and the rest a low one
hostPatha directory of the node, mounted into a podhere, the node’s hugetlbfs for Aeron’s directory
hostNetworka pod on the node’s network, not the pod network’s virtual interfacetakes a kernel-UDP pod off that interface
Archive, ClusterAeron’s Java services. Archive records and replays streams; Cluster runs your service on several nodes that agree on one log (the consensus module)ergon is only a cluster client; these run on Java
Agronathe Java library of buffers and agents that Aeron is built onits use of jdk.internal.misc.Unsafe is why the JVM needs the first --add-opens
LTSa Java release with long-term support (17, 21, 25)run Archive and Cluster on 25
JITthe JVM’s compiler: it turns hot code into machine code while the program runscode-cache pressure can undo its work (deoptimise)
GC, barrierGC: the garbage collector, which frees objects no longer used. Barrier: the extra work it adds to the program’s memory accessesParallelGC is what Aeron’s scripts use: convention, not a measured collector A/B
safepointa pause in which every Java thread stopsevery one is logged with its cause to tmpfs (-Xlog:gc*,safepoint, Java)
duty cycleone pass of an agent’s work loop*.cycle.threshold=1ms counts each one over 1 ms, so stalls show
spya subscription that reads a publication on its own host, from its log buffer, not the networksee aeron.spies.simulate.connection (Java)
sparse file, pre-touchsparse: disk pages appear only on first write. Pre-touch: every page is faulted in at startno first-write page faults, but pre-touched terms count against a container’s memory limit