1. PG介紹
PG, Placement Groups。CRUSH先將數據分解成一組對象,然后根據對象名稱、復制級別和系統中的PG數等信息執行散列操作,再將結果生成PG ID。可以將PG看做一個邏輯容器,這個容器包含多個對象,同時這個邏輯對象映射之多個OSD上。
如果沒有PG,在成千上萬個OSD上管理和跟蹤數百萬計的對象的復制和傳播是相當困難的。沒有PG這一層,管理海量的對象所消耗的計算資源也是不可想象的。建議每個OSD上配置50~100個PG。
2. 計算PG數
一般的,
Ceph集群中的PG總數:
PG總數 = (OSD總數 * 100) / 最大副本數
** 結果必須舍入到最接近的2的N次方冪的值。
Ceph集群中每個pool中的PG總數:
存儲池PG總數 = (OSD總數 * 100 / 最大副本數) / 池數
平衡每個存儲池中的PG數和每個OSD中的PG數對於降低OSD的方差、避免速度緩慢的恢復再平衡進程是相當重要的。
3. 修改PG和PGP
PGP是為了實現定位而設置的PG,它的值應該和PG的總數(即pg_num)保持一致。對於Ceph的一個pool而言,如果增加pg_num,還應該調整pgp_num為同樣的值,這樣集群才可以開始再平衡。
參數pg_num定義了PG的數量,PG映射至OSD。當任意pool的PG數增加時,PG依然保持和源OSD的映射。直至目前,Ceph還未開始再平衡。此時,增加pgp_num的值,PG才開始從源OSD遷移至其他的OSD,正式開始再平衡。PGP,Placement Groups of Placement。
1.獲取現有的PG數和PGP數值:
ceph osd pool get data pg_num
ceph osd pool get data pgp_num
2.檢查存儲池的副本數或糾刪碼配置
ceph osd dump|greo -i size
糾刪碼池的 size 即為k+m
3.計算pg_num和pgp_num
# pg_num calculation
pg_num = (num_osds * 100) / num_copies
num_up = pow(2, int(log(pg_num,2) + 0.5))
num_down = pow(2, int(log(pg_num,2)))
if abs(pg_num - num_up) <= abs(pg_num - num_down):
pg_num = num_up
else:
pg_num = num_down
pgp_num = pg_num
4.修改存儲池的PG和PGP
ceph osd pool set data pg_num <pg_num>
ceph osd pool set data pgp_num <pgp_num>
5.同樣,修改另外兩個存儲池:metadata和rbd的PG和PGP
4. 集群擴容對PG分布的影響
場景數據遷移流程:
擴容前 3 個 OSD, 4 個 PG
擴容后 4 個 OSD, 4 個 PG
擴容前:
擴容后: