[Ceph Turning] – Tham số OSD Max Backfills và Recovery Max Active

1. Tổng quan.

1.1. Tham số osd_max_backfills.

Tham số osd_max_backfills giới hạn số backfill song song trên mỗi OSD (tách riêng read và write).

Khi set trị này nhỏ lại, ví dụ 1 sẽ giúp giảm tải cho cụm nhưng recovery/backfill chậm hơn.

Tham số osd_max_backfills áp riêng cho chiều đọc và chiều ghi trên mỗi OSD.

Ví dụ nếu bạn đặt osd_max_backfills = 5 ⇒ tối đa 5 luồng backfill đọc (outbound) và tối đa 5 luồng backfill ghi (inbound) có thể chạy đồng thời trên cùng OSD → tổng cộng tối đa 10 luồng (5 read + 5 write), miễn là còn PG cần backfill theo các chiều đó.

Lưu ý nhỏ.

  • Số thực tế tham số này có thể bị ảnh hưởng bởi các tham số khác, ví dụ osd_recovery_max_active/osd_recovery_max_active_hdd.
  • Nếu đang dùng mClock mà  tham số osd_mclock_override_recovery_settings đang là false thì osd_max_backfills sẽ bị mClock chặn lại. Chỉ khi osd_mclock_override_recovery_settings là true thì nó mới có tác dụng.

Tham số osd_recovery_max_active có tác dụng trong cả hai trường hợp Recovery và Backfill.

  • Recovery – Khi một OSD chết, dữ liệu của nó sẽ được recovery từ các OSD khác để tái lập trạng thái full replication/EC.
  • Backfill – Khi có OSD mới join cluster hoặc PG được remap, Ceph phải backfill dữ liệu sang vị trí mới.

1.2. Tham số osd_recovery_max_active.

  • Tham số osd_recovery_max_active là sSố op recovery/backfill đồng thời tối đa cho mỗi OSD.
  • Backfill cũng được tính là recovery op trong queue, nên bị giới hạn bởi thông số này.
  • Nó hoạt động song song với osd_max_backfills:
    • osd_max_backfills → giới hạn số PG backfill đồng thời.
    • osd_recovery_max_active → giới hạn số operation recovery/backfill đồng thời.

Nếu bạn set cả hai bằng 1 → vừa hạn PG đồng thời, vừa hạn op đồng thời, tốc độ sẽ giảm mạnh.

2. Flow của recovery/backfill

Dưới đây là sơ đồ flow mô tả mối quan hệ giữa các tham số dưới để bạn thấy rõ luồng giới hạn khi recovery/backfill trong Ceph:

  • osd_max_backfills
  • osd_recovery_max_active
  • osd_recovery_max_chunk
            ┌─────────────────────────────┐
            │ 1. PG cần recovery/backfill │
            └────────────┬────────────────┘
                         │
             [ Giới hạn theo PG ]
                         │
              osd_max_backfills
      (Số PG backfill/recovery đồng thời tối đa
        mà 1 OSD tham gia xử lý)
                         │
            ┌────────────┴────────────┐
            │ 2. Mỗi PG được xử lý    │
            └────────────┬────────────┘
                         │
          [ Giới hạn theo số op đồng thời ]
                         │
         osd_recovery_max_active
 (Số operation recovery/backfill đồng thời tối đa
   mà 1 OSD cho phép chạy trong tất cả các PG)
                         │
            ┌────────────┴────────────┐
            │ 3. Mỗi operation chạy   │
            └────────────┬────────────┘
                         │
       [ Giới hạn kích thước mỗi gói truyền ]
                         │
        osd_recovery_max_chunk (MB)
 (Kích thước dữ liệu gửi mỗi lần cho 1 op,
   ví dụ 8MB mặc định → giảm xuống 1MB
   sẽ nhẹ hơn cho HDD nhưng nhiều request hơn)

Tóm tắt thứ tự áp dụng giới hạn:

  • osd_max_backfills → hạn chế số PG đang backfill/recovery đồng thời.
  • osd_recovery_max_active → hạn chế số op đồng thời trong tất cả các PG đó.
  • osd_recovery_max_chunk → hạn chế kích thước dữ liệu gửi trong mỗi op.

Nếu muốn giảm tải HDD, bạn thường phải chỉnh kết hợp cả 3 tham số chứ không chỉ 1, vì mỗi cái điều tiết ở một tầng khác nhau.

3. Ví dụ

Dưới đây là ví dụ thực tế để hình dung rõ hơn giữa osd_max_backfills và osd_recovery_max_active khi phục hồi một file.

Giả sử

  • Pool EC 6+2
  • File F = 24 MB → Ceph chia thành 3 object, mỗi object = 8 MB (giả sử rgw_obj_stripe_size = 8 MB).
  • Mỗi object bị mất một shard (do 1 OSD chết) và cần recovery.

Bước 1 – PG liên quan

  • 3 object này thuộc 3 PG khác nhau: PG1PG2PG3.
  • Khi recovery bắt đầu, Ceph sẽ chọn PG để backfill/recovery theo giới hạn của osd_max_backfills.
  • Nếu:
    • osd_max_backfills = 1 → Mỗi OSD chỉ xử lý 1 PG recovery cùng lúc (ví dụ chỉ PG1).
    • osd_max_backfills = 3 → Có thể xử lý PG1, PG2, PG3 cùng lúc.

Bước 2 – Op trong mỗi PG

  • Mỗi PG có thể có nhiều object cần phục hồi.
  • osd_recovery_max_active = giới hạn số op recovery đồng thời trên OSD, tính gộp tất cả PG đang chạy. Ví dụ:
    • Nếu osd_max_backfills = 2 (PG1 và PG2 chạy song song)
    • Và osd_recovery_max_active = 1 → Mỗi OSD chỉ chạy 1 op recovery tại một thời điểm (dù có 2 PG đang chạy).
    • Nếu osd_recovery_max_active = 4 → OSD có thể chạy cùng lúc 4 op recovery, phân bổ vào cả PG1 và PG2.

Bước 3 – Chunk mỗi op

  • osd_recovery_max_chunk quyết định mỗi op gửi bao nhiêu dữ liệu.
  • Nếu = 8MB (default) → Mỗi op gửi trọn object 8MB.
  • Nếu = 1MB → Mỗi op gửi 1MB, cần 8 op để phục hồi xong object.

Sơ đồ flow của ví dụ trên

  • File 24MB → 3 object (8MB mỗi object).
  • 3 object thuộc 3 PG khác nhau: PG1, PG2, PG3.
  • Pool EC 6+2 → mỗi object chia thành 8 shard (6 data, 2 parity).
  • Một OSD chết → cần recovery 1 shard của mỗi object.
                  [ File 24MB bị mất shard trên 1 OSD ]
                                    │
                                    ▼
     ┌───────────────────────────────────────────────────┐
     │                 BƯỚC 1: PG SELECT                 │
     │   osd_max_backfills = số PG xử lý song song       │
     │                                                   │
     │   Ví dụ:                                          │
     │     osd_max_backfills = 1  → PG1 chạy trước       │
     │     osd_max_backfills = 2  → PG1 + PG2 chạy song  │
     │     osd_max_backfills = 3  → PG1 + PG2 + PG3      │
     └───────────────────────────────────────────────────┘
                                    │
                                    ▼
     ┌───────────────────────────────────────────────────┐
     │          BƯỚC 2: OPERATION TRONG MỖI PG           │
     │  osd_recovery_max_active = số op recovery tối đa  │
     │  (gộp tất cả PG đang chạy)                        │
     │                                                   │
     │   Ví dụ:                                          │
     │     osd_recovery_max_active = 1 → 1 op tổng       │
     │     osd_recovery_max_active = 3 → 3 op tổng       │
     │     (Có thể chia đều cho các PG hoặc dồn vào 1 PG)│
     └───────────────────────────────────────────────────┘
                                    │
                                    ▼
     ┌───────────────────────────────────────────────────┐
     │        BƯỚC 3: CHUNK MỖI OP GỬI DỮ LIỆU           │
     │   osd_recovery_max_chunk = kích thước mỗi gói     │
     │   (Mặc định 8MB → gửi 1 object trong 1 op)        │
     │   (Nếu 1MB → cần 8 op cho object 8MB)             │
     └───────────────────────────────────────────────────┘

Ví dụ chạy với các giá trị khác nhau:

Chậm nhất nhưng nhẹ HDD

osd_max_backfills = 1
osd_recovery_max_active = 1
osd_recovery_max_chunk = 1MB
→ Mỗi lần chỉ phục hồi 1MB dữ liệu trên OSD.

Nhanh hơn nhưng nặng HDD

osd_max_backfills = 3
osd_recovery_max_active = 6
osd_recovery_max_chunk = 8MB
→ Nhiều PG chạy song song, mỗi op 8MB → bão IO.

4. Các kịch bản để bạn dễ hình dung mối quan hệ PG và op.

Kịch bản A

Tham số osd_max_backfills = 2 (2 PG được xếp vào) osd_recovery_max_active = 1 (chỉ 1 op tổng)

[ OSD ]
  ├─ PG1: [OP]──▶ đang chạy
  └─ PG2: [OP]    đợi vì hết slot op

=> Thực tế: CHỈ 1 PG “thực sự chạy” tại một thời điểm (vì chỉ có 1 op).

Kịch bản B

osd_max_backfills = 2 osd_recovery_max_active = 2

[ OSD ]
  ├─ PG1: [OP]──▶ chạy
  └─ PG2: [OP]──▶ chạy

=> Thực tế: 2 PG cùng active vì đủ 2 slot op.

Kịch bản C

osd_max_backfills = 1 (chỉ 1 PG được xếp vào) osd_recovery_max_active = 4 (4 op tổng)

[ OSD ]
  └─ PG1:
       [OP][OP][OP][OP] ──▶ 4 op song song trong 1 PG

=> Thực tế: chỉ 1 PG hoạt động, nhưng bên trong PG đó có thể chạy nhiều op song song.

Bảng summary

Tham sốTác động trong ví dụ file 24MB
osd_max_backfills = 1Chỉ recovery 1 PG → xử lý tuần tự PG1 → PG2 → PG3
osd_recovery_max_active = 1Dù 1 PG có nhiều object, OSD cũng chỉ phục hồi 1 object (hoặc 1 chunk) tại 1 thời điểm
osd_recovery_max_chunk = 1MBMỗi object 8MB cần 8 op, giảm tải HDD nhưng tăng số op

5. Combo khuyến nghị (êm, an toàn cho HDD)

Đây là combo mình thấy ổn cho 1 farm lớn sử dụng HDD EC 6+2 với dung lượng trên 5PB

# Đã có:
ceph config set osd osd_mclock_override_recovery_settings true
ceph config set osd osd_max_backfills 1

# Thêm siết theo HDD (thay vì để 0):
ceph config set osd osd_recovery_max_active_hdd 1
ceph config set osd osd_recovery_max_active 0   # giữ 0 để dùng _hdd ở trên

# (Tuỳ) làm gói nhỏ để giảm burst:
ceph config set osd osd_recovery_max_chunk 2MiB

Nếu sau khi siết như trên mà recovery quá chậm ngoài giờ, bạn có thể tạm tăng:

ceph config set osd osd_recovery_max_active_hdd 2

Hoặc chuyển profile:

ceph config set osd osd_mclock_profile high_recovery_ops

(đổi profile không cần restart; đổi osd_op_queue mới cần).

6. Lưu ý khi sử dụng profile mClock.

Nếu osd_mclock_override_recovery_settings = true thì dù bạn đang chạy osd_op_queue = mclock_scheduler + profile high_client_ops/high_recovery_ops/balanced, các tham số recovery truyền thống như:

  • osd_recovery_max_active / osd_recovery_max_active_hdd
  • osd_max_backfills
  • osd_recovery_max_chunk

Lý do: khi override = true, Ceph bỏ qua phần mClock tự động điều chỉnh 2 tham số osd_max_backfills và osd_recovery_max_active dựa theo profile, cho phép bạn tự set thủ công.

Nên nếu farm của bạn toàn HDD, việc set cấu hình dưới vẫn có hiệu lực và sẽ giới hạn số operation recovery/backfill đồng thời cho mỗi PG trên mỗi OSD.

ceph config set osd osd_recovery_max_active_hdd 1

Bài viết gần đây

spot_img

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here

Đăng ký nhận thông tin bài viết qua email