🧭 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
Namespace | Mục đích chính | Ghi 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ể |
gc | Garbage Collection – Xử lý các object đã bị xóa hoặc hết hạn | Thường là gc.<số> |
lc | Lifecycle – Theo dõi, lên lịch và thực thi chính sách lifecycle cho bucket/object | lc.<số> |
usage | Usage logs – Lưu lại log thống kê việc sử dụng (usage report) | Thường là usage.<số> |
reshard | Quá 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ứausage
,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 -s
và ceph 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 usage
có 555.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é!