How to create an erasure-coded pool in Ceph

An erasure-coded Ceph pool stores each object as data and parity chunks instead of full replicated copies. It is a good fit for large object, archive, and capacity-sensitive data where the cluster can spend extra CPU and recovery work to reduce raw storage overhead.

The erasure-code profile defines how many data chunks and parity chunks Ceph writes and which CRUSH failure domain keeps those chunks apart. Create the profile before the pool, because changing the profile later means creating a new pool and moving data rather than editing the existing pool in place.

The sample pool archive_ec uses a 4+2 profile with chunks spread across hosts, overwrite support for clients that need partial object updates, and an RGW application tag. Use a replicated metadata pool for RBD or CephFS metadata, and use an erasure-coded pool only where that workload explicitly supports it.

Steps to create a Ceph erasure-coded pool:

  1. Check cluster health before changing pool layout.
    $ ceph -s
      cluster:
        id:     11111111-2222-3333-4444-555555555555
        health: HEALTH_OK
    
      services:
        mon: 3 daemons, quorum ceph-node1,ceph-node2,ceph-node3
        mgr: ceph-node1(active), standbys: ceph-node2
        osd: 9 osds: 9 up, 9 in
    
      data:
        pools:   2 pools, 65 pgs
        objects: 184.32k objects, 720 GiB
        usage:   2.2 TiB used, 58 TiB / 60 TiB avail
        pgs:     65 active+clean

    Create pools only when OSDs are up and PGs are active+clean. A degraded cluster makes it harder to tell whether later placement warnings came from the new pool or from existing recovery work.

  2. Create the erasure-code profile.
    $ ceph osd erasure-code-profile set archive_ec_profile k=4 m=2 crush-failure-domain=host

    k=4 stores four data chunks and m=2 stores two parity chunks for each object. crush-failure-domain=host keeps chunks from the same object on different hosts when the CRUSH map has enough hosts.

    Do not overwrite an existing profile unless every pool that uses it can keep the old layout. Use a new profile name when changing k, m, plugin, or failure domain for a new pool.

  3. Review the saved erasure-code profile.
    $ ceph osd erasure-code-profile get archive_ec_profile
    crush-failure-domain=host
    crush-root=default
    jerasure-per-chunk-alignment=false
    k=4
    m=2
    plugin=jerasure
    technique=reed_sol_van
  4. Create the erasure-coded pool with the profile.
    $ ceph osd pool create archive_ec erasure archive_ec_profile
    pool 'archive_ec' created

    Recent Ceph releases use the PG autoscaler for new pools by default. Set target-size hints or the bulk flag separately when this pool is expected to hold a large share of cluster data.
    Related: How to enable the Ceph PG autoscaler

  5. Enable overwrite support for the pool.
    $ ceph osd pool set archive_ec allow_ec_overwrites true
    set pool 7 allow_ec_overwrites to true

    allow_ec_overwrites lets supported clients update parts of existing objects instead of writing only whole objects. It requires BlueStore OSDs, which are the supported OSD backend for current Ceph releases.

  6. Enable the application tag for the intended workload.
    $ ceph osd pool application enable archive_ec rgw
    enabled application 'rgw' on pool 'archive_ec'

    Use rgw for object gateway data, cephfs for CephFS data pools, or rbd only for an erasure-coded RBD data pool paired with a replicated metadata pool.

  7. Confirm the pool detail shows the erasure profile, overwrite flag, and application tag.
    $ ceph osd pool ls detail
    pool 7 'archive_ec' erasure profile archive_ec_profile size 6 min_size 5 crush_rule 4 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 126 flags hashpspool,ec_overwrites stripe_width 16384 application rgw
    ##### snipped #####

    size 6 matches k+m for the 4+2 profile. application rgw and ec_overwrites show that the workload tag and overwrite setting are active.

  8. Write a small test object to the new pool.
    $ printf 'erasure-coded pool test\n' | rados --pool archive_ec put ec-test-object -
  9. Read the test object back from the pool.
    $ rados --pool archive_ec get ec-test-object -
    erasure-coded pool test
  10. Remove the test object after the read succeeds.
    $ rados --pool archive_ec rm ec-test-object