Logo

Personal Ops Runbook

Personal runbook covering infrastructure operations for Cloud, Kubernetes, OpenStack, and Ceph environments. Includes deployment and teardown procedures, node management, cluster monitoring setup, and incident response workflows compiled from day-to-day operational work. Intended strictly for personal reference — configurations and scripts are environment-specific and not guaranteed to work as-is elsewhere.

Ceph PG Autoscaler - Cách xác định pool theo OSD và cách tính NEW PG_NUM

OVERVIEW

Tài liệu hướng dẫn cách xác định một osd.<id> đang phục vụ những pool nào và hiểu lúc nào Ceph PG Autoscaler đề xuất hay không đề xuất thay đổi pg_num dựa trên RATE, BIAS, RATIO, mon_target_pg_per_osd và ngưỡng mgr/pg_autoscaler/threshold.

Mục đích:

  • Muốn biết khi nào NEW PG_NUM được đề xuất.
  • Trước/sau khi add thêm OSD (thay đổi RAW CAPACITY) để dự đoán autoscale sẽ phản ứng thế nào.
  • Khi cần truy vết OSD này đang gánh những pool nào? dùng crush_rule nào? thuộc subtree nào?

Xác định pool/crush rule/subtree từ một OSD

1) Liệt kê các pool mà osd.<id> đang phục vụ

  • Từ danh sách osd.<id> → lấy pool_id → map sang thông tin pool (replicated/erasure, crush_rule, pg_num, autoscale_mode,...)
  • Thay 0 bằng osd_id cần kiểm tra.
shell> ceph pg ls-by-osd 0 -f json | jq -r '.pg_stats[].pgid' | cut -d. -f1 | sort -u | while read id; do echo -n "pool $id = "; ceph osd pool ls detail | grep "^pool $id "; done
pool 10 = pool 10 'fs.metadata' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 256 pgp_num 256 autoscale_mode on last_change 176302 lfor 0/176302/176300 flags hashpspool,bulk stripe_width 0 expected_num_objects 3 pg_autoscale_bias 1 pg_num_min 16 recovery_priority 5 application cephfs read_balance_score 1.56
pool 11 = pool 11 '.nfs' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode off last_change 26190 flags hashpspool stripe_width 0 application nfs read_balance_score 6.22
pool 13 = pool 13 'fs.data.ssd.01' erasure profile erasure-code-2-2-ssd size 4 min_size 3 crush_rule 3 object_hash rjenkins pg_num 512 pgp_num 512 autoscale_mode off last_change 165742 lfor 0/165742/165740 flags hashpspool,ec_overwrites,bulk stripe_width 8192 fast_read 1 compression_algorithm lz4 compression_max_blob_size 4194304 compression_min_blob_size 4096 compression_mode passive compression_required_ratio 0.8 application cephfs
pool 15 = pool 15 'default.rgw.buckets.data' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode off last_change 194282 flags hashpspool,bulk stripe_width 0 application rgw read_balance_score 3.75
pool 2 = pool 2 '.rgw.root' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 7688 lfor 0/7682/7686 flags hashpspool stripe_width 0 application rgw read_balance_score 3.73
pool 4 = pool 4 'default.rgw.log' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237009 lfor 0/0/236808 flags hashpspool max_bytes 1000000000000 stripe_width 0 application rgw read_balance_score 3.13
pool 5 = pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 236837 lfor 0/0/236828 flags hashpspool stripe_width 0 application rgw read_balance_score 3.75
pool 6 = pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236837 flags hashpspool stripe_width 0 pg_autoscale_bias 1 application rgw read_balance_score 2.49
pool 7 = pool 7 'default.rgw.buckets.index' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236842 flags hashpspool stripe_width 0 pg_autoscale_bias 1 application rgw read_balance_score 3.75
pool 8 = pool 8 'default.rgw.buckets.non-ec' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236846 flags hashpspool stripe_width 0 application rgw read_balance_score 3.13

2) Xác định crush_rule và subtree mà pool đang sử dụng

Từ output ở bước trước, nó cho biết mỗi pool sẽ có trường crush_rule <id>.

Bước này dùng để kiểm tra các rule_id đó đang take subtree nào trong CRUSH map (ví dụ: mbf9-01~ssd).

Ví dụ kiểm tra crush_rule có id là 1

root@VSTOR-CEPH-MBF9-MON-05:/# ceph osd crush rule dump -f json | jq '.[] | select(.rule_id==1)'
{
  "rule_id": 1,
  "rule_name": "replicated_ssd_01",
  "type": 1,
  "steps": [
    {
      "op": "take",
      "item": -26,
      "item_name": "mbf9-01~ssd"
    },
    {
      "op": "chooseleaf_firstn",
      "num": 0,
      "type": "host"
    },
    {
      "op": "emit"
    }
  ]
}

Kiểm tra crush_rule có id là 3

root@VSTOR-CEPH-MBF9-MON-05:/# ceph osd crush rule dump -f json | jq '.[] | select(.rule_id==3)'
{
  "rule_id": 3,
  "rule_name": "fs.data.ssd.01",
  "type": 3,
  "steps": [
    {
      "op": "set_chooseleaf_tries",
      "num": 5
    },
    {
      "op": "set_choose_tries",
      "num": 100
    },
    {
      "op": "take",
      "item": -26,
      "item_name": "mbf9-01~ssd"
    },
    {
      "op": "chooseleaf_indep",
      "num": 0,
      "type": "host"
    },
    {
      "op": "emit"
    }
  ]
}
  • Kết quả từ 2 output trên cho biết crush_rule 1 và 3 đều đang đang take vào subtree mbf9-01~ssd

3) Kiểm tra trạng thái PG autoscale của các pool liên quan

  • Dùng ceph osd pool autoscale-status để xem: SIZE, RATE, RAW CAPACITY, RATIO, BIAS, PG_NUM, NEW PG_NUM, AUTOSCALE, BULK.
  • Output dưới đây đã lọc theo danh sách pool cần quan tâm.
shell> ceph osd pool autoscale-status | egrep 'rgw.root|default.rgw.log|default.rgw.control|default.rgw.meta|default.rgw.buckets.index|default.rgw.buckets.non-ec|.nfs|fs.metadata|fs.data.ssd.01|default.rgw.buckets.data'
.rgw.root                   36864                               3.0        71518G  0.0000                                  1.0      32              on         False
default.rgw.log             202.1M                              3.0        71518G  0.0000                                  1.0      64              on         False
default.rgw.control             0                               3.0        71518G  0.0000                                  1.0      64              on         False
default.rgw.meta            27537k                              3.0        71518G  0.0000                                  1.0      64              on         False
default.rgw.buckets.index   153.7G                              3.0        71518G  0.0064                                  1.0      64              on         False
default.rgw.buckets.non-ec  138.8M                              3.0        71518G  0.0000                                  1.0      64              on         False
.nfs                        290.3k                              3.0        71518G  0.0000                                  1.0      32              off        False
fs.metadata                  3008M                              3.0        71518G  0.0001                                  1.0     256              on         True
fs.data.ssd.01                  0                               2.0        71518G  0.0000                                  1.0     512              off        True
default.rgw.buckets.data    244.4G                              3.0        71518G  0.0103                                  1.0      32              off        True

4) Đếm số node trong subtree

Xác định các node liên quan đến subtree `mbf9-01~ssd

root@VSTOR-CEPH-MBF9-MON-05:/# ceph osd crush dump -f json \
| jq -r '.buckets[] | select(.name=="mbf9-01~ssd") | .items[].id' \
| wc -l
20

5) Đếm số OSD trong subtree

Xác định các OSD liên quan đến subtree `mbf9-01~ssd

root@VSTOR-CEPH-MBF9-MON-05:/# ceph osd crush dump -f json | jq -r '
  .buckets as $b
  | ($b[] | select(.name=="mbf9-01~ssd") | .items[].id) as $hid
  | ($b[] | select(.id==$hid) | .items[].id)
  | select(.>=0)
' | sort -n | uniq | wc -l
40

Cách Autoscaler tính pg_num và quyết định có đề xuất NEW PG_NUM hay không

Warning: Ceph chỉ đề xuất khi chênh lệch so với PG_NUM hiện tại vượt ngưỡng mgr/pg_autoscaler/threshold và không bị chặn bởi pg_num_min/max hoặc flag bulk.

BƯỚC 1 - TÍNH RATE

RATE là hệ số quy đổi từ dung lượng đã replica (SIZE) sang RAW USED

Đối với pool Replicated

  • Thông thường: RATE ≈ size (số replica)

Ví dụ:

  • REP 1: RATE = 1 → dữ liệu 2 GiB sẽ tiêu tốn toàn bộ khoảng 2 GiB raw
  • REP 2: RATE = 2 → dữ liệu 2 GiB sẽ tiêu tốn toàn bộ khoảng 4 GiB raw
  • REP 3: RATE = 3 → dữ liệu 2 GiB sẽ tiêu tốn toàn bộ khoảng 6 GiB raw

Đối với pool Erasure Coding (EC)

  • Công thức: RATE = (k + m) / k

Ví dụ:

  • EC k=2, m=2 (2+2): RATE = (2+2)/2 = 2 → Overhead parity (m/k) * 100% = (2/2)*100% = 100% → dữ liệu 2 GiB sẽ tiêu tốn thêm khoảng 2 * (2/2) = 2 GiB raw, tổng 4GiB
  • EC k=6, m=2 (6+2): RATE = (6+2)/6 ≈ 1.3333 → Overhead parity (2/6) * 100% ≈ 33.33% → dữ liệu 2 GiB sẽ tiêu tốn thêm khoảng 2 * (2/6) = 0.66 GiB raw, tổng 2.66 GiB

BƯỚC 2 - TÍNH BIAS

BIAS dùng để ưu tiên một pool có nhiều/ít PG hơn so với mức bình thường.

  • BIAS > 1.0: ưu tiên cấp nhiều PG hơn
  • BIAS < 1.0: ưu tiên giảm PG
  • BIAS = 1.0: không ưu tiên

Mặc định thường là 1.0 và có thể set lại bằng:

ceph osd pool set <pool> pg_autoscale_bias <bias>

Kiểm tra lại giá trị vừa đặt:

ceph osd pool get <pool> pg_autoscale_bias

BƯỚC 3 - TÍNH RATIO

RATIO thể hiện tỷ lệ raw mà pool đang chiếm trên tổng raw capacity của nhóm OSD liên quan.

  • Công thức: RATIO = RAW USED / RAW CAPACITY
  • Trong đó:

  • RAW USED ≈ SIZE * RATE: tổng dung lượng raw đã sử dụng

  • RAW CAPACITY: tổng dung lượng raw các nhóm OSD thuộc subtree nào đó

Ví dụ với pool default.rgw.buckets.index farm HCM04

shell> ceph osd pool autoscale-status | awk 'NR==1 || /default.rgw.buckets.index/'
POOL                          SIZE  TARGET SIZE                RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO  BIAS  PG_NUM  NEW PG_NUM  AUTOSCALE  BULK
default.rgw.buckets.index    153.7G                             3.0        71518G  0.0064                                  1.0      64              on         False

Từ output trên có thể kiểm tra nhanh:

  • size: 153.7G
  • rate: 3.0
  • raw_capacity: 1.787TB * 40 OSDs = 71518G

Cách tính - thay các giá trị vào công thức trên, ta có:

  • raw_used = 153.7G * 3.0 = 461.1G
  • ratio = 461.1G / 71518G ≈ 0.00645 → làm tròn để giống với output của lệnh ceph osd pool autoscale-status đang hiển thị là 0.0064

Như vậy ratio ≈ 0.0064 nghĩa là pool này đang chiếm khoảng 0.64% tổng dung lượng raw của subtree.

BƯỚC 4 - TÍNH pg_num_ideal

Autoscaler cần biết target PG/OSD của cluster:

  • mon_target_pg_per_osd: số PG placements mục target mỗi OSD, xem mon_target_pg_per_osd hiện tại (ví dụ: 100):
shell> ceph config get mon mon_target_pg_per_osd
100
  • Tính tổng placements target cho subtree OSD: total_pgs_all_osd = osd_count * mon_target_pg_per_osd

Sau đó:

  • weighted_capacity_ratio = ratio * bias
  • ideal_pg_placements = weighted_capacity_ratio * total_pgs_all_osd
  • Với pool replicated, ước tính:

  • pg_num_ideal ≈ ideal_pg_placements / replicated_size

Áp dụng công thức trên cho 40 OSD farm HCM04 thì với mon_target_pg_per_osd = 100 ta có:

  • total_pgs_all_osd = 40 * 100 = 4000
  • weighted_capacity_ratio = 0.0064 * 1.0 = 0.0064
  • ideal_pg_placements = 0.0064 * 4000 = 25.6
  • pg_num_ideal ≈ 25.6 / 3 = 8.53

Lưu ý:

  • Autoscaler chọn pg_num theo lũy thừa của 2 ví dụ 2, 4, 8, 16, 32, 64, 128,...
  • Và chỉ đề xuất nếu vượt ngưỡng mgr/pg_autoscaler/threshold (mặc định là 3 lần)

BƯỚC 5 - Áp dụng ngưỡng mgr/pg_autoscaler/threshold

Trong ví dụ này PG_NUM=64 nhưng NEW PG_NUM trống vì:

  • NEW PG_NUM chỉ hiện khi đề xuất lệch hơn threshold lần so với PG_NUM hiện tại.

Kiểm tra threshold:

shell> ceph config get mgr mgr/pg_autoscaler/threshold
3.000000

Với pg_num_ideal ≈ 8.53 thì mức lũy thừa của 2 gần nhất sẽ rơi vào 16. So với PG_NUM=64, tỷ lệ thay đổi là 64 / 16 = 4 (giảm 4 lần). Tuy nhiên, việc scale-down còn phụ thuộc vào profile/bulk/pg_num_min và logic nội bộ của autoscaler.

Để test trường hợp autoscaler sẽ đề xuất thì phải làm sao để cho pg_num_ideal đủ lớn để đề xuất tăng:

  • Điều kiện đơn giản (theo threshold):

  • pg_num_target / current_pg_num > threshold

Ví dụ: 197 / 64 = 3.078125 > 3.0 → vượt ngưỡng, autoscaler có thể đề xuất tăng.

Note: Output dưới đây chỉ là ví dụ được copy/paste sau đó chỉnh sửa lại cho phù hợp với output nếu có đề xuất.

Sử dụng command ceph osd pool autoscale-status -f json-pretty

shell> ceph osd pool autoscale-status -f json-pretty | jq '.[]|select(.pool_name=="default.rgw.buckets.index")|{pg_num_target,pg_num_final,logical_used,would_adjust}'
{
  "pg_num_target": 64,
  "pg_num_final": 256,
  "logical_used": 165033233612,
  "would_adjust": true
}

Sử dụng command ceph osd pool autoscale-status

shell> ceph osd pool autoscale-status | awk 'NR==1 || /default.rgw.buckets.index/'
POOL                          SIZE  TARGET SIZE                RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO  BIAS  PG_NUM  NEW PG_NUM  AUTOSCALE  BULK
default.rgw.buckets.index    153.7G                             3.0        71518G   0.0064                                 1.0      64         128  on         False

Sử dụng command ceph -s

shell>  ceph -s

  cluster:
    id:     c85b0190-27aa-11ef-97a7-7f90cac4804a
    health: HEALTH_WARN
            1 pools have too few placement groups

  services:
    mon: 5 daemons, quorum VSTOR-CEPH-MBF9-MON-05,VSTOR-CEPH-MBF9-MON-06,VSTOR-CEPH-MBF9-MDS-09,VSTOR-CEPH-MBF9-MDS-08,VSTOR-CEPH-MBF9-MON-07 (age 9w)
    mgr: VSTOR-CEPH-MBF9-MON-07.blpwtk(active, since 4w), standbys: VSTOR-CEPH-MBF9-MON-05.dptncn, VSTOR-CEPH-MBF9-MON-06.oleywv
    mds: 2/2 daemons up, 2 hot standby
    osd: 737 osds: 737 up (since 4d), 737 in (since 4d); 2 remapped pgs
    rgw: 11 daemons active (8 hosts, 1 zones)

  data:
    volumes: 1/1 healthy
    pools:   16 pools, 14497 pgs
    objects: 1.88G objects, 3.2 PiB
    usage:   4.3 PiB used, 2.3 PiB / 6.6 PiB avail
    pgs:     14495 active+clean

  io:
    client:   576 MiB/s rd, 378 MiB/s wr, 37.47k op/s rd, 1.68k op/s wr

Sử dụng command ceph health detail

shell>  ceph health detail
[WRN] POOL_TOO_FEW_PGS: 1 pools have too few placement groups
    Pool default.rgw.buckets.index has 64 placement groups, should have 256

Ví dụ trường hợp gắn thêm 14 OSD cho subtree mbf9-01~ssd thì autoscale có đề xuất mới không?

Giả sử:

  • Số OSD tăng từ 40 → 54
  • RATE không đổi (vẫn ~3.0 cho pool replicated size=3)
  • SIZE (đã tính replica) tại thời điểm đó là 200G

Tính nhanh:

  • raw_capacity = 1.787TB * 54 OSDs = 96498G
  • raw_used = 200G * 3.0 = 600G
  • ratio = 600 / 96498 ≈ 0.0062

Với mon_target_pg_per_osd = 100:

  • total_pgs_all_osd = 54 * 100 = 5400
  • ideal_pg_placements = 0.0062 * 5400 = 33.48
  • pg_num_ideal ≈ 33.48 / 3 = 11.16 → làm tròn theo lũy thừa của 2 sẽ về 16

Theo docs Ceph upstream, với flag bulk thì cũng là 1 option để autoscaler quyết định hành vi scale-down hay scale-up:

  • Nếu pool có bulk=true: autoscaler start full PGscó thể scale down nhưng chỉ khi usage ratio across the pool is uneven.
  • Nếu pool có bulk=false: autoscaler bắt đầu ít PG và chỉ tạo thêm PG khi usage tăng — docs không mô tả việc tự giảm pg_num cho option này.

Vì vậy, trước khi add 14 OSD, với các option của pool bulk=false, pg_autoscale_mode=on, threshold=3.0, dự đoán nhất là:

  • PGS/OSD: theo lý thuyết khi thêm OSD lượng pg trên mỗi osd chắc chắn sẽ giảm.
  • pg_num của pool hiện tại là 64 nên với đề xuất pg_num_ideal = 16 không đủ điều kiện để scale up, còn với scale down docs hoàn toàn không nhắc đến khi cờ bulk=false nên NEW PG_NUM có thể vẫn trống như output dưới:,
shell> ceph osd pool autoscale-status | awk 'NR==1 || /default.rgw.buckets.index/'
POOL                          SIZE  TARGET SIZE                RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO  BIAS  PG_NUM  NEW PG_NUM  AUTOSCALE  BULK
default.rgw.buckets.index     200G                              3.0        96498G  0.0062                                  1.0      64              on         False

Điều kiện để Autoscaler trigger NEW PG_NUM

Ngoài phép tính pg_num_ideal, kết quả còn bị chi phối bởi các điều kiện/cấu hình sau.

1) Giới hạn pg_num_min / pg_num_max của pool

ceph osd pool get default.rgw.buckets.index pg_num_min
ceph osd pool get default.rgw.buckets.index pg_num_max

Nếu:

  • pg_num_min32 → autoscaler không đề xuất thấp hơn 32 (dù tính toán ra nhỏ hơn) → NEW PG_NUM có thể trống.
  • pg_num_max64 → autoscaler không đề xuất cao hơn 64 (dù tính toán ra lớn hơn) → NEW PG_NUM có thể trống.

2) Mode autoscale của pool (pg_autoscale_mode)

Có 3 mode chính: on | off | warn

  • on: bật autoscale (có thể đề xuất/điều chỉnh) và không có cảnh báo
  • off: tắt autoscale sẽ không có cảnh báo
  • warn: không tự điều chỉnh pg mà chỉ cảnh báo qua ceph health detail, ceph -s, ceph osd pool autoscale-status, ...

Lệnh để chuyển pg_autoscale_mode của 1 pool

ceph osd pool set <pool> pg_autoscale_mode warn

Verify

ceph osd pool get <pool> pg_autoscale_mode

Một yếu tố rất quan trọng khác là cờ bulk của pool:

ceph osd pool get default.rgw.buckets.index bulk

3) Cờ bulk

Khi bulkoff (mặc định / False)

  • Khởi tạo: bắt đầu với số PG thấp (thường 1/4/8 tuỳ phiên bản & policy)
  • Scale up: khi data tăng, autoscaler tăng PG dần dần
  • Scale down: Docs không mô tả hành vi scale-down cho pool có bulk=false. Tài liệu có nói nếu pool có bulk=false thì autoscaler khởi tạo với số PG tối thiểuchỉ tạo thêm PG khi usage tăng (if a pool is not flagged bulk, then the autoscaler starts the pool with minimal PGs and creates additional PGs only if there is more usage in the pool). Vì vậy với bulk=false có thể hiểu là autoscaler thiên về scale-up.

Note: Tham khảo: Ceph Docs (Reef) – Placement Groups.

Khi bulk=true

  • Khởi tạo: cấp phát sớm một lượng PG tương đối lớn ngay khi tạo pool
  • Mục tiêu: giảm hiện tượng PG splitting liên tục khi dữ liệu đổ vào (tốn tài nguyên, có thể gây lag IO)
  • Scale down: vẫn có thể xảy ra, nhưng thường ưu tiên giữ mức PG cao hơn để chờ dữ liệu

Ước lượng mốc dữ liệu để bắt đầu thấy NEW PG_NUM

Giữ nguyên 40 OSD và các cấu hình:

  • mgr/pg_autoscaler/threshold = 3.0
  • mon_target_pg_per_osd = 100

Với pool default.rgw.buckets.index đang có PG_NUM=64, để autoscaler đề xuất tăng (vượt threshold), cần pg_num_ideal đủ lớn sao cho:

  • pg_num_target / 64 > 3pg_num_target > 192

Gọi SSIZE: đây chính là size dung lượng logic của pool với pool default.rgw.buckets.index đang replicated size=3:

  • raw_used ≈ S * 3
  • ratio = raw_used / raw_capacity
  • ideal_pg_placements = ratio * (40 * 100)

Bỏ qua làm tròn, điều kiện xấp xỉ cho mốc đề xuất tăng là:

  • S > (192 * 71518 GB) / 4000 ≈ 3432.86 GB → khoảng 3.35 TB

Khi dữ liệu vượt khoảng ~3.4 TB, ta có thể thấy:

  • pg_num_ideal vượt mốc ~192
  • vượt ngưỡng mgr/pg_autoscaler/threshold
  • NEW PG_NUM xuất hiện (thường nhảy lên 256 vì là lũy thừa của 2 gần nhất)

Note: Nếu muốn Ceph nhạy hơn, có thể giảm mgr/pg_autoscaler/threshold (ví dụ 2.0 hoặc 1.5). Tuy nhiên giảm quá thấp có thể làm autoscaler điều chỉnh thường xuyên khi dữ liệu dao động nhỏ.


Vì sao ceph osd df cho thấy PGS của osd.0 là 101 và osd.1 là 118?

ceph osd df hiển thị số PG (placements) đang được map vào từng OSD tại thời điểm xem, số này phụ thuộc:

  • OSD đang tham gia những pool nào (replicated/EC)
  • pg_num của từng pool
  • Phân phối CRUSH tại thời điểm hiện tại (không nhất thiết đều tuyệt đối)

Ví dụ xem 2 OSD (0 và 1):

shell> ceph osd df | awk 'NR == 1 || ($1 ~ /^(0|1)$/ && $2 == "ssd")'
ID   CLASS  WEIGHT    REWEIGHT  SIZE     RAW USE  DATA     OMAP     META     AVAIL    %USE   VAR   PGS  STATUS
  0    ssd   1.74599   1.00000  1.7 TiB   32 GiB   16 GiB  9.6 GiB  5.5 GiB  1.7 TiB   1.76  0.03  101      up
  1    ssd   1.74599   1.00000  1.7 TiB   58 GiB   31 GiB   18 GiB  9.5 GiB  1.7 TiB   3.27  0.05  118      up

Nếu xem danh sách PG/pool đang map vào osd.0, ta thấy subtree mbf9-01~ssd đang phục vụ nhiều pool (cả replicated lẫn EC):

shell> ceph pg ls-by-osd 0 -f json | jq -r '.pg_stats[].pgid' | cut -d. -f1 | sort -u | while read id; do echo -n "pool $id = "; ceph osd pool ls detail | grep "^pool $id "; done
pool 10 = pool 10 'fs.metadata' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 256 pgp_num 256 autoscale_mode on last_change 176302 lfor 0/176302/176300 flags hashpspool,bulk stripe_width 0 expected_num_objects 3 pg_autoscale_bias 1 pg_num_min 16 recovery_priority 5 application cephfs read_balance_score 1.56
pool 11 = pool 11 '.nfs' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode off last_change 26190 flags hashpspool stripe_width 0 application nfs read_balance_score 6.22
pool 13 = pool 13 'fs.data.ssd.01' erasure profile erasure-code-2-2-ssd size 4 min_size 3 crush_rule 3 object_hash rjenkins pg_num 512 pgp_num 512 autoscale_mode off last_change 165742 lfor 0/165742/165740 flags hashpspool,ec_overwrites,bulk stripe_width 8192 fast_read 1 compression_algorithm lz4 compression_max_blob_size 4194304 compression_min_blob_size 4096 compression_mode passive compression_required_ratio 0.8 application cephfs
pool 15 = pool 15 'default.rgw.buckets.data' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode off last_change 194282 flags hashpspool,bulk stripe_width 0 application rgw read_balance_score 3.75
pool 2 = pool 2 '.rgw.root' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 7688 lfor 0/7682/7686 flags hashpspool stripe_width 0 application rgw read_balance_score 3.73
pool 4 = pool 4 'default.rgw.log' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237009 lfor 0/0/236808 flags hashpspool max_bytes 1000000000000 stripe_width 0 application rgw read_balance_score 3.13
pool 5 = pool 5 'default.rgw.control' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 236837 lfor 0/0/236828 flags hashpspool stripe_width 0 application rgw read_balance_score 3.75
pool 6 = pool 6 'default.rgw.meta' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236837 flags hashpspool stripe_width 0 pg_autoscale_bias 1 application rgw read_balance_score 2.49
pool 7 = pool 7 'default.rgw.buckets.index' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236842 flags hashpspool stripe_width 0 pg_autoscale_bias 1 application rgw read_balance_score 3.75
pool 8 = pool 8 'default.rgw.buckets.non-ec' replicated size 3 min_size 2 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on last_change 237047 lfor 0/0/236846 flags hashpspool stripe_width 0 application rgw read_balance_score 3.13

Từ danh sách pool ở trên, có thể ước lượng tổng PG placements mà subtree đang gánh như sau.

Tính placements cho từng pool

Pool replicated size=3:

  • pool 10: 256 (pg_num) × 3 = 768
  • pool 11: 32 × 3 = 96
  • pool 15: 32 × 3 = 96
  • pool 2: 32 × 3 = 96
  • pool 4: 64 × 3 = 192
  • pool 5: 64 × 3 = 192
  • pool 6: 64 × 3 = 192
  • pool 7: 64 × 3 = 192
  • pool 8: 64 × 3 = 192

Pool EC size=4:

  • pool 13 (k=2, m=2): 512 × 4 = 2048

Tổng placements:

  • 768 + (3×96) + (5×192) + 2048
  • = 768 + 288 + 960 + 2048
  • = 4064 (tuỳ thời điểm, có thể chênh do pool thay đổi/PG splitting/merge)

Lấy xấp xỉ theo 40 OSD:

  • ~ 4064 / 40 ≈ 101.6 placements/OSD

Vì CRUSH phân bổ theo hash nên từng OSD có thể lệch nhẹ so với trung bình — do đó thấy 101 trên osd.0118 trên osd.1 là hợp lý trong thực tế.


KẾT LUẬN

Với subtree dùng chung cho nhiều pool và workload lớn như farm HCM04, chiến lược vận hành có lẽ vẫn nên set autoscale_mode mode warn để nhận đề xuất giúp chủ động chọn thời điểm manual scale, vì:

  • pg_autoscale_mode=on: tiện vì cluster tự điều chỉnh nhưng rủi ro là PG split/merge có thể kéo theo rebalancing/backfill đúng lúc workload đang cao (nhất là khi nhiều pool chung 1 subtree) → dễ làm IO/CPU, latency tăng.
  • pg_autoscale_mode=off: an toàn nhất nhưng phải tự biết khi nào cần tăng/giảm PG → dễ để thiếu PG lâu quá hoặc set quá tay.
  • pg_autoscale_mode=warn: vẫn nhờ Ceph tính giúppg_num_final và cảnh báo nhưng không tự scale → chủ động chọn thời điểm ít tải để scale manual.

Để dùng warn mode hiệu quả hơn:

  1. Ưu tiên bật warn cho các subtree sử dụng cho nhiều pool (ví dụ RGW index, metadata pool)
  2. Khi thấy cảnh báo, không nên set 1 phát quá lớn vì khi cluster đang có workload thì tốt nhất nên tăng theo từng bậc ví dụ 64→128→256 giúp rebalance nhẹ nhàng hơn.
  3. Làm checklist trước khi scale PG:
  4. ceph -s (recovery/backfill có đang chạy không)
  5. ceph osd df (PGS/OSD có lệch quá nhiều không)
  6. ceph osd perf / latency
  7. giới hạn recovery (osd_max_backfills, osd_recovery_max_active, v.v.) để tránh quá trình rebalance ăn hết workload của client.