Skip to main content
RunBook Academy

CephXXV · Erasure Coding FundamentalsErasure Coding Fundamentals

How EC chunks are placed

Advanced⏱ ~18 minceph

What you'll learn

  • Explain why EC chunk position is significant
  • Distinguish the indep and firstn CRUSH modes
  • Read an EC pool's acting set including NONE entries
  • Set and verify an EC pool's failure domain

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

EC chunks are not interchangeable the way replicas are. Chunk 3 must be reconstructed as chunk 3, because the decode arithmetic depends on which position each chunk occupies. That single fact drives a different CRUSH mode, a different acting-set format, and a different failure behaviour — all of which look strange until you know why.

Positions matter

For a replicated PG, acting [12,47,83] means three OSDs hold identical copies. Order determines the primary and nothing else.

For an EC PG, acting [12,47,83,19,55,71] means:

position 0 → osd.12 → data chunk 0
position 1 → osd.47 → data chunk 1
position 2 → osd.83 → data chunk 2
position 3 → osd.19 → data chunk 3
position 4 → osd.55 → coding chunk 0
position 5 → osd.71 → coding chunk 1

The decode needs to know which chunks it has and their positions. Losing the mapping is the same as losing the chunks.

firstn versus indep

Replicated rules use firstn. When a selected OSD is unavailable, CRUSH takes the next candidate and the list shifts left:

healthy:      [12, 47, 83]
osd.47 down:  [12, 83]         ← positions collapse

Harmless for replicas — the surviving copies are still identical.

EC rules use indep. When a selected OSD is unavailable, CRUSH leaves a hole at that position:

healthy:      [12, 47, 83, 19, 55, 71]
osd.83 down:  [12, 47, NONE, 19, 55, 71]

Position 2 stays position 2. The replacement, when one is chosen, becomes chunk 2 and is reconstructed as chunk 2.

ceph osd crush rule dump ec42-rule | jq -r '.steps[]'
# {"op":"take","item":-1,"item_name":"default"}
# {"op":"chooseleaf_indep","num":0,"type":"host"}
# {"op":"emit"}

Reading a degraded EC acting set

ceph pg map 12.a4
# ... -> up [12,47,2147483647,19,55,71] acting [12,47,2147483647,19,55,71]

2147483647 is 0x7FFFFFFF — the sentinel for NONE. Four chunks plus two holes on a 4+2 pool means two chunks are missing: recoverable, but at min_size 5 the PG is not serving.

Failure domain

Set it in the profile, not on the rule, because the profile generates the rule:

ceph osd erasure-code-profile set ec63 \
    k=6 m=3 crush-failure-domain=host

You need k+m failure domains, with headroom above that so recovery has somewhere to place replacement chunks.

Quiz

Knowledge check · 4 questions

  1. Q1. Why do erasure-coded pools use CRUSH `indep` rather than `firstn`?

  2. Q2. An acting set entry of 2147483647 in an EC pool indicates a corrupted chunk.

  3. Q3. Diagnose an EC pool that will not reach clean.

    A newly created 10+4 EC pool on a 12-host cluster sits at `active+undersized+degraded` for every PG and never reaches clean. `ceph pg map` shows two NONE entries in every acting set. The profile specifies crush-failure-domain=host.

  4. Q4. Why can indep fail to find a replacement OSD on a cluster where firstn would succeed?

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

Production discipline

Count failure domains against k+m before creating any EC pool, and record the headroom in the pool documentation — the shortfall does not produce an error at creation time, only a pool that never goes clean. When reading EC acting sets during an incident, count the NONE entries first; the number is the shortfall against size and tells you immediately how close to min_size you are.

Cross-course references

  • Kubernetes: this is the same as a StatefulSet whose pods cannot all be scheduled under anti-affinity constraints
  • Linux: RAID stripe position matters for the same reason parity reconstruction does