Script tìm kiếm Object có OMAP lớn trong Ceph

🧭 Tổng quan

Trong hệ thống Ceph, OMAP (Object Map) là một trong những thành phần quan trọng để lưu trữ metadata (dữ liệu siêu văn bản) liên quan đến các object. Tuy nhiên, khi một object có quá nhiều khóa OMAP, nó có thể gây ảnh hưởng tới hiệu suất của cluster, đặc biệt là trong quá trình deep-scrub hoặc recovery. Ceph cung cấp một cách để phát hiện các object như vậy thông qua các chỉ số như num_large_omap_objects.

Bài viết này sẽ chia sẻ một script bash được sử dụng để phát hiện các object có số lượng khóa OMAP vượt quá ngưỡng cho phép trong một pool cụ thể. Chúng ta sẽ cùng tìm hiểu cách script hoạt động, các thành phần bên trong và ưu – nhược điểm của giải pháp này.

🎯 Mục đích

Lỗi HEALTH_WARN 1 large omap objects trong Ceph thường xảy ra khi một object trong pool có số lượng khóa OMAP vượt quá ngưỡng được cấu hình, gây ảnh hưởng đến hiệu suất cluster, đặc biệt là trong các thao tác deep-scrub hoặc reshard bucket.

Trong hướng dẫn này, chúng ta sẽ từng bước xác định:

  • Pool nào bị ảnh hưởng
  • PG nào chứa object lỗi
  • Object nào có quá nhiều OMAP keys
  • Cách xác định ngưỡng và lý do lỗi phát sinh

📚 Để dễ hiểu hơn, đầu tiên bạn hãy tìm hiểu namespace trong Ceph là gì đã nhé.

  • Namespace là một lớp logic nằm trong một pool.
  • Các object trong pool có thể được gán vào một namespace cụ thể.
  • Nếu không chỉ định, object mặc định nằm trong namespace " " (trống).

🧩 Danh sách namespace thường gặp trong các pool (RGW)

Nếu bạn đang sử dụng Ceph với RADOS Gateway (RGW) (phục vụ S3/Swift), thì mỗi pool có thể chứa nhiều namespace, tùy thuộc vào chức năng.

📋 Ví dụ dưới đây là danh sách Namespace trong pool default.rgw.log

NamespaceMục đích chínhGhi chú thêm
(trống)Mặc định – chứa các object như obj_delete_at_hint.*, pubsub.*, data_log.*Các object không thuộc namespace cụ thể
gcGarbage Collection – Xử lý các object đã bị xóa hoặc hết hạnThường là gc.<số>
lcLifecycle – Theo dõi, lên lịch và thực thi chính sách lifecycle cho bucket/objectlc.<số>
usageUsage logs – Lưu lại log thống kê việc sử dụng (usage report)Thường là usage.<số>
reshardQuá trình resharding (chia nhỏ index bucket khi quá lớn)reshard.<số>

🔍 Chi tiết vai trò từng namespace

(trống) – Namespace mặc định

  • Chứa các object không được gán vào namespace cụ thể.
  • Trong Ceph RGW, thường dùng để lưu:
    • obj_delete_at_hint.*: dùng trong cơ chế delayed delete của Ceph.
    • pubsub.*: metadata cho hệ thống Pub/Sub.
    • data_log.*: metadata cho logging nội bộ.

gc – Garbage Collection

  • Là nơi lưu các GC markers (dấu hiệu cần xóa).
  • Dùng bởi Ceph RGW để lên lịch và xử lý xóa object đã expired/multipart failed.
gc.1, gc.13, gc.31, ...

lc – Lifecycle

  • Lưu trữ các policy lifecycle và lịch trình tương ứng.
  • Thường được cấu hình từ client S3 (expiration rule, transition rule).
lc.0, lc.1, lc.27, ...

usage – Usage Stats

  • Thu thập dữ liệu thống kê sử dụng bucket và user, như số byte read/write, số request.
  • Dữ liệu này được dùng để phục vụ API GET /usage hoặc dashboard.
usage.1, usage.2, ..., usage.31

reshard – Bucket Resharding

  • Quá trình reshard xảy ra khi bucket có quá nhiều object vượt ngưỡng rgw_max_objs_per_shard.
  • Ceph RGW tạo ra các reshard.* để quản lý phiên làm việc chia tách.
reshard.0000000000, reshard.0000000015, ...

Namespace khác nhau giữa các pool, tùy theo:

  • Tính năng (log, index, metadata, data…)
  • Cách hoạt động của RGW hoặc phần mềm sử dụng
  • Cấu trúc bucket / user / lifecycle hiện tại

Ví dụ:

  • default.rgw.log chứa usage, gc, lc, reshard
  • default.rgw.buckets.data thường không có gc, mà có .dir, .users.uid, hoặc namespace theo bucket.

Lời khuyên khi làm việc với namespace

Tránh thao tác ghi/xóa object mà không hiểu rõ namespace, có thể làm hỏng metadata. Chúng ta có thể xác định danh sách namespace của một pool bằng lệnh dưới, với default.rgw.log là pool name.

shell> rados -p default.rgw.log ls -f json --all | jq -r '.[].namespace' | sort | uniq
<trống>
gc
lc
reshard
usage

📚 Chúng ta nên xem quy trình thủ công dưới đây để hiểu cách hoạt động của script.

📌 Ghi nhận lỗi từ ceph -sceph health detail

Khi chạy lệnh:

ceph -s

Bạn sẽ thấy cảnh báo:

shell> sudo ceph -s
  cluster:
    id:     c85b0190-2755-11ef-97a7-7fefcac123fg
    health: HEALTH_WARN
            1 large omap objects

  services:
    mon: 5 daemons, quorum CEPH-LAB-MON-05,CEPH-LAB-MON-06,CEPH-LAB-MON-07,CEPH-LAB-MDS-09,CEPH-LAB-MDS-08 (age 5M)
    mgr: CEPH-LAB-MON-05.dptncn(active, since 9w), standbys: CEPH-LAB-MON-07.blpwtk, CEPH-LAB-MON-06.oleywv
    mds: 2/2 daemons up, 2 hot standby
    osd: 307 osds: 307 up (since 2w), 307 in (since 3w)
    rgw: 3 daemons active (3 hosts, 1 zones)

  data:
    volumes: 1/1 healthy
    pools:   11 pools, 3041 pgs
    objects: 586.03M objects, 1.5 PiB
    usage:   2.0 PiB used, 991 TiB / 3.0 PiB avail
    pgs:     2699 active+clean
             248  active+clean+scrubbing
             94   active+clean+scrubbing+deep

  io:
    client:   634 KiB/s rd, 85 MiB/s wr, 438 op/s rd, 366 op/s wr

Để xem chi tiết hơn:

ceph health detail

Kết quả:

shell> ceph health detail
HEALTH_WARN 1 large omap objects
[WRN] LARGE_OMAP_OBJECTS: 1 large omap objects
    1 large objects found in pool 'default.rgw.log'
    Search the cluster log for 'Large omap object found' for more details.

📍 Lỗi cho biết có một object trong pool default.rgw.log có số lượng OMAP keys vượt quá giới hạn.

🧮 Kiểm tra ngưỡng omap key hiện tại

Ceph quy định giới hạn OMAP key qua tham số:

ceph tell mon.0 config show | grep -i osd_deep_scrub_large_omap_object_key_threshold

Kết quả ví dụ:

"osd_deep_scrub_large_omap_object_key_threshold": "200000"

✅ Nghĩa là: bất kỳ object nào có trên 200.000 OMAP keys sẽ bị đánh dấu là “large omap object”.

📂 Xác định namespace trong pool default.rgw.log

Namespace giúp phân vùng logic object trong pool. Để xem namespace có trong pool:

radosgw-admin zone get | jq -r '.[] | values' | grep default.rgw.log | cut -d':' -f2 | grep -v default.rgw.log

Kết quả ví dụ:

gc
lc
intent
usage
reshard
notif

🔍 4. Tìm danh sách các Placement Group (PG) của pool

Chạy:

ceph pg ls-by-pool default.rgw.log | grep -v NOTE | awk '{print $1}'

Kết quả:

4.0
4.1
4.2
...
4.1f

🔬 Xác định PG chứa object OMAP lớn

Duyệt từng PG trong danh sách trên. Ví dụ kiểm tra PG 4.8:

ceph pg 4.8 query | jq '.info.stats.stat_sum | select(.num_large_omap_objects > 0) | .num_large_omap_objects'

Nếu có kết quả > 0, thì PG đó chứa object vượt ngưỡng. Ví dụ:

1

Ghi chú lại PG này để xử lý tiếp (ví dụ 4.8).

📄 Liệt kê object trong PG bị ảnh hưởng (ví dụ 4.8)

Với mỗi namespace đã tìm được, chạy lệnh để liệt kê object:

rados -p default.rgw.log --pgid 4.8 ls -N usage -f json | jq -r '.[].name'

Ví dụ trả về:

usage.14
usage.17
...

📏 Kiểm tra số lượng OMAP keys trong object

Với mỗi object tìm được, dùng lệnh sau để đếm số lượng OMAP keys:

rados -p default.rgw.log listomapkeys usage.14 -N usage | wc -l

Kết quả ví dụ:

555094

✅ Object usage.14 trong namespace usage555.094 khóa OMAP → vượt ngưỡng 200.000.

✅ Tóm tắt quy trình

[ceph -s] → [ceph health detail]
        ↓
 Xác định pool bị ảnh hưởng (ví dụ: default.rgw.log)
        ↓
 Lấy danh sách PGs → Duyệt từng PG để tìm PG lỗi
        ↓
 Từ PG lỗi → duyệt object theo namespace
        ↓
 Kiểm tra số OMAP keys từng object → Xác định object vi phạm

Gợi ý xử lý

  • Backup object nếu cần (nếu là object ứng dụng).
  • Xóa hoặc di chuyển object nếu không còn cần thiết.
  • Xem xét tăng ngưỡng osd_deep_scrub_large_omap_object_key_threshold, nhưng phải cân nhắc kỹ vì có thể che giấu vấn đề thực sự.
  • Nếu object là bucket index → có thể cần thực hiện reshard bucket.

🧠 Sử dụng script.

🛠 Mục tiêu của script

Script find_large_omap.sh giúp:

  • Xác định các PG chứa object có số lượng khóa OMAP lớn hơn cấu hình Ceph hiện tại.
  • Kiểm tra chi tiết trong các namespace của pool để tìm ra chính xác object nào vượt quá ngưỡng.
  • Hiển thị thông tin để hỗ trợ việc xử lý hoặc tối ưu hóa sau này.

📄 Nội dung chi tiết script

cat find_large_omap.sh
#!/bin/bash
ceph=$(which ceph)
large_omap_object_key_threshold=$($ceph tell mon.0 config show | grep -i osd_deep_scrub_large_omap_object_key_threshold | grep -o "[0-9]*")

if [ "$1" == "" ] || [ $# -gt 1 ]; then
    echo "Pool not set!"
    exit 0
fi

echo " ======== Details ======="

# Get pool name from user
POOL=$1

# Find all namespaces in pool
namespaces=$(radosgw-admin zone get | jq -r '.[] | values' | grep $POOL | cut -d':' -f2 | grep -v $POOL)
echo "Get Namespaces in $POOL :"
for namespace in $namespaces
do
    echo -e "\tNameSpace $namespace Found in $POOL"
done

echo " ======== Details ======="
PGS=$(ceph pg ls-by-pool $POOL | grep -v NOTE | tail -n +2 | awk '{print $1}')
for i in $PGS
do
    NUM_LARGE=$(ceph pg $i query | jq  '.info.stats.stat_sum | select(.num_large_omap_objects > 0) | .num_large_omap_objects')
printf "\033[2K\rFound $NUM_LARGE Large omap in PG $i\n"
    if [[ $NUM_LARGE ]]; then
        printf "\033[2K\rFound $NUM_LARGE Large omap in PG $i\n"
        for namespace in $namespaces
        do
            printf "\033[2K\r[CHECK] Search for Large omap objects in pool '$POOL', PG '$i' and NameSpace '$namespace' ... \033[2k\r"
            find_large="False"
            objects=$(rados -p $POOL --pgid $i ls -N $namespace -f json | jq -r '.[].name')
            for obj in $objects
            do
                omap_in_obj=$(rados -p $POOL --pgid $i listomapkeys $obj -N $namespace | wc -l)
                if [[ $omap_in_obj -gt $large_omap_object_key_threshold ]]; then
                    find_large="True"
                    printf "\033[2K\rObject : $obj\tOmap Counts : $omap_in_obj \033[0k\n"
                fi
            done
            if [ $find_large == "True" ]; then
                echo "----------------------------------------------"
            fi
        done
    fi
done

Lấy ngưỡng OMAP

large_omap_object_key_threshold=$($ceph tell mon.0 config show | grep -i osd_deep_scrub_large_omap_object_key_threshold | grep -o "[0-9]*")
  • Dòng này lấy giá trị osd_deep_scrub_large_omap_object_key_threshold, là ngưỡng số lượng khóa OMAP mà Ceph coi là “lớn”.
  • Mặc định thường là 2000 hoặc 4000 tuỳ theo phiên bản.

Kiểm tra tham số pool

if [ "$1" == "" ] || [ $# -gt 1 ]; then
    echo "Pool not set!"
    exit 0
fi
  • Đảm bảo người dùng truyền đúng 1 tham số là tên pool.

Tìm các namespace trong pool

radosgw-admin zone get | jq -r '.[] | values' | grep $POOL | cut -d':' -f2 | grep -v $POOL
  • Giả định đang sử dụng Ceph RGW (Rados Gateway).
  • Lọc các namespace liên quan đến pool.

Tìm PG có chứa object lớn

ceph pg ls-by-pool $POOL | grep -v NOTE | tail -n +2 | awk '{print $1}'
  • Lấy danh sách PG thuộc pool.
  • Với mỗi PG, script dùng:
ceph pg $i query | jq  '.info.stats.stat_sum | select(.num_large_omap_objects > 0) | .num_large_omap_objects'
  • Để xác định PG nào chứa object có OMAP lớn.

Lọc object thật sự có số lượng khóa OMAP vượt ngưỡng

rados -p $POOL --pgid $i ls -N $namespace -f json | jq -r '.[].name'
  • Lấy danh sách object trong PG theo namespace.
rados -p $POOL --pgid $i listomapkeys $obj -N $namespace | wc -l
  • Đếm số khóa OMAP cho mỗi object.

🔁 Quy trình tổng thể minh hoạ:

+----------------+
|  Nhập tên pool |
+-------+--------+
        |
        v
+-------+--------+
|   Tìm namespace|
+-------+--------+
        |
        v
+-------+--------+
| Lấy PGs của pool|
+-------+--------+
        |
        v
+-------+--------+
| Kiểm tra PG nào |
| có OMAP lớn     |
+-------+--------+
        |
        v
+-------+--------+
| Kiểm tra object |
| trong PG đó     |
+-------+--------+
        |
        v
+-------+--------+
| Đếm khóa OMAP  |
| nếu > ngưỡng =>|
| in ra thông tin|
+----------------+

✅ Ưu điểm

  • Dễ sử dụng: Script chỉ cần truyền tên pool là chạy được.
  • Tùy chỉnh linh hoạt: Có thể mở rộng để log ra file hoặc alert.
  • Độ chính xác cao: Sử dụng lệnh gốc của Ceph để truy vấn nên đảm bảo dữ liệu đúng.

❌ Nhược điểm

  • Tốc độ chậm: Nếu pool có hàng triệu object, việc duyệt từng object và đếm OMAP sẽ rất lâu.
  • Phụ thuộc vào CLI & quyền truy cập: Cần quyền root hoặc user đủ role để dùng rados, ceph, radosgw-admin.

📌 Ví dụ sử dụng

./find_large_omap.sh default.rgw.buckets.data

Kết quả mẫu:

======== Details =======
Get Namespaces in default.rgw.buckets.data :
    NameSpace .users.uid Found in default.rgw.buckets.data
======== Details =======
Found 1 Large omap in PG 1.23a
[CHECK] Search for Large omap objects in pool 'default.rgw.buckets.data', PG '1.23a' and NameSpace '.users.uid' ...
Object : 29d9a0b3... Omap Counts : 5451
----------------------------------------------

⚠️ Lời khuyên

  • Chạy script này vào ngoài giờ cao điểm để tránh ảnh hưởng performance.
  • Backup trước khi can thiệp vào các object nghi ngờ.
  • Nếu phát hiện nhiều object có OMAP lớn, cần điều tra nguyên nhân (thường do app ghi metadata quá nhiều).
  • Kết hợp với ceph health detail, ceph osd perf để có cái nhìn toàn diện hơn.

🔚 Kết luận

Script find_large_omap.sh là một công cụ đơn giản nhưng mạnh mẽ giúp quản trị viên Ceph xác định được các object tiềm ẩn rủi ro hiệu năng do OMAP lớn. Trong môi trường production, việc chủ động kiểm tra và xử lý các object kiểu này sẽ giúp duy trì tính ổn định và hiệu suất của toàn bộ cluster.

Nếu bạn thấy bài viết hữu ích, hãy chia sẻ với đồng nghiệp hoặc comment góp ý bên dưới để mình cải thiện nhé!

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