Ceph儲存池管理

FuShudi發表於2024-05-25

目錄
  • Ceph儲存池
    • 1. Ceph的儲存流程
      • 1. 資料寫入
      • 2. 資料讀取
    • 2. 資源池的配置
      • 2.1 資源池建立
        • pgp是什麼 (Placement Group for Placement purpose)
      • 2.2 繫結池型別
        • 關閉
    • 3. 物件的管理
      • 3.1 上傳物件
      • 3.2 檢視物件
      • 3.3 下載物件
      • 3.4 刪除物件
      • 3.5 查詢物件所在pg
      • 3.6 限制資源池配額
      • 3.7 測試配額
    • 3. 儲存池快照
    • 4. 修改池屬性
      • 4.1 列出屬性
      • 4.2 調整副本數為4
      • 4.3 禁止刪除儲存池
    • 5. 糾刪碼池管理
      • 5.1 原理
      • 5.2 建立糾刪碼池
        • 5.2.1 建立自己的配置檔案
        • 5.2.2 使用自己的配置檔案建立池

Ceph儲存池

前面已經搭建好了一個基礎的Ceph叢集,現在來看看Ceph的儲存

1. Ceph的儲存流程

當客戶端需要儲存一個檔案到Ceph叢集的時候,Ceph會把這個檔案切分成多個物件,預設情況下每個物件4M,不足4M按原大小。切分之後每個物件都有一個對應的物件ID,Ceph拿到這個物件ID之後執行hash演算法,去計算出這個物件應該寫入到哪個PG(Placement Group)

PG是一些物件的集合,這些物件組成一個group,放在某些OSD上(place),組合起來就是Placement Group。將objects以PG為單位進行管理,有以下好處:

叢集中的PG數目經過規劃因為嚴格可控,使得基於PG可以精準控制單個OSD乃至整個節點的資源消耗,如CPU、記憶體、網路頻寬等
因為叢集中的PG數目遠小於objects數目,並且PG數目和每個PG的身份相對固定,以PG為單位進行資料備份策略和資料同步、遷移等,相較於直接以物件為單位而言,難度更小且更加靈活

1. 資料寫入

為了保證叢集裡儲存的資料不丟失,Ceph採用了多副本機制,也就是將一個PG複製到多個osd節點上,當儲存資料時,主osd收到寫入指令後,將資料寫入,並向其他的備osd(這裡的數量取決於你設定的副本數)發起資料寫入指令

強一致性會導致資料寫入有較大的延遲,因此ceph進行了最佳化,將資料的寫入分為2步執行

  1. 第一次當所有資料都寫入osd節點的快取後,向client傳送一次確認,client就認為資料寫入完成,繼續後面的操作
  2. 第二次當所有資料都從快取寫入到磁碟後,再向client傳送一次確認,client就會認為資料徹底寫入,從而根據需要刪除對應的本隊資料

2. 資料讀取

如果是讀取資料呢?是怎麼讀的?在哪個osd讀?

ceph讀取資料的話永遠都是從主osd節點上讀取,不會從其他備osd節點讀。

2. 資源池的配置

2.1 資源池建立

  • 建立資源池的命令是
    ceph osd pool create poolname [pg_num:int] [pgp_num:int] [replicated|erasure] [earsure_code_profile]

    • poolname :資源池名稱,必選
    • pg_num:int:PG數量,現在可以不選
    • pgp_num:int:下面單獨解釋什麼是pgp,也可以不選
    • replicated|erasure:資源池型別,replicated為副本池,另一個則為糾刪碼池
    • earsure_code_profile:糾刪碼配置模板,用於設定資料塊和糾刪碼數量,當資源池型別為糾刪碼時,此選項為必選
    • 如果建立資源池僅僅指定了資源池名稱,那麼其他引數系統會自動補齊,預設資源池型別為副本池
[root@ceph01 ~]# ceph osd pool create test_pool
pool 'test_pool' created

pgp是什麼 (Placement Group for Placement purpose)

我們現在都知道pg是什麼,用比較容易理解的話來說就相當於Linux上的目錄,目錄下面會存放檔案嘛,只不過pg存放的是物件,那如果pg數量太少,物件數量太多,我們是不是應該建立更多的pg出來?對。就是應該建立更多的pg,但是並不是直接建立,而是當任何池的pg_num增加時,此池的每個PG都將一分為二,但它們都保持對映到其父OSD。 直到這個時候,Ceph才開始重新平衡。現在,當你增加同一個池的pgp_num值時,PG開始從父級遷移到其他OSD,並開始群集重新平衡。這就是PGP發揮重要作用的原因。

簡單來說,如果只是pg的數量發生變化的話,那麼這個osd上的pg會發生裂變由原來的一個一分為二,但是資料依舊儲存在這個osd上,但是如果修改了pgp的數量,那麼此時會開始發生遷移,之前發生裂變的pg可能會被重新排程到其他的osd上

2.2 繫結池型別

當我們的儲存池被建立出來之後,我們需要指定他的型別,不建議複用

[root@ceph01 ~]# ceph osd pool application enable test_pool rbd
enabled application 'rbd' on pool 'test_pool'
[root@ceph01 ~]# ceph osd pool create test02
pool 'test02' created
[root@ceph01 ~]# ceph osd pool application enable test02 rgw
enabled application 'rgw' on pool 'test02'[root@ceph01 ~]# ceph osd pool application enable test03 cephfs
enabled application 'cephfs' on pool 'test03'

這時候我們就有3個儲存池,繫結的型別分別是 rbd,rgw,cephfs

關閉

我們剛剛是使用enable繫結的型別,那麼同樣可以使用disable去關閉掉

[root@ceph01 ~]# ceph osd pool application disable test03 cephfs
Error EPERM: Are you SURE? Disabling an application within a pool might result in loss of application functionality; pass --yes-i-really-mean-it to proceed anyway

這個時候他會報錯,目的是讓你確認,你得加上 --yes-i-really-mean-it這個才可以刪除

[root@ceph01 ~]# ceph osd pool application disable test03 cephfs --yes-i-really-mean-it
disable application 'cephfs' on pool 'test03'

3. 物件的管理

我們建立了資源池,也繫結了型別,那麼現在可以使用rados來操作ceph叢集了

3.1 上傳物件

[root@ceph01 ~]# rados -p test03 put test-obj /etc/hosts
  • -p 是指定資源池

  • put是操作

  • test-obj 是物件的id,自己指定

  • /etc/hosts 是需要上傳的檔案

  • 整條命令就是說將本地的/etc/hosts檔案上傳到test03,物件的id是test-obj

3.2 檢視物件

[root@ceph01 ~]# rados -p test03 put test-obj /etc/hosts
[root@ceph01 ~]# rados -p test03 ls
test-obj

我們使用ls就可以看到我們剛剛上傳的檔案了

3.3 下載物件

[root@ceph01 ~]# rados -p test03 get test-obj ./hosts
[root@ceph01 ~]# cat hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 ceph01
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.101.10 ceph01
192.168.101.20 ceph02
192.168.101.30 ceph03

3.4 刪除物件

[root@ceph01 ~]# rados -p test03 rm test-obj 
[root@ceph01 ~]# rados -p test03 ls

3.5 查詢物件所在pg

# 重新上傳一個物件
[root@ceph01 ~]# rados -p test03 put test-obj /etc/hosts
[root@ceph01 ~]# ceph osd map test03 test-obj
osdmap e93 pool 'test03' (4) object 'test-obj' -> pg 4.d6b75f59 (4.19) -> up ([7,2,5], p7) acting ([7,2,5], p7)

我們可以看到這個物件位於 7,2,5這三個pg上,主osd是7

3.6 限制資源池配額

限制資源池有2種,一種是限制最大物件數,一種是限制最大位元組數

限制資源有一點非常不友好,就是你到達了最大數量的限制之後你再去上傳,他不會報錯,會一直卡在那

# 設定最大位元組為5M
[root@ceph01 ~]# ceph osd pool set-quota test03 max_bytes 5M
set-quota max_bytes = 5242880 for pool test03

取消配置只需要設定成0就可以了

[root@ceph01 ~]# ceph osd pool set-quota test03 max_bytes 0

3.7 測試配額

# 建立一個4M的檔案
[root@ceph01 ~]# dd if=/dev/zero of=./4M count=1 bs=4M
1+0 records in
1+0 records out
4194304 bytes (4.2 MB, 4.0 MiB) copied, 0.00513982 s, 816 MB/s

# 上傳檔案
[root@ceph01 ~]# rados -p test03 put 4M ./4M
[root@ceph01 ~]# rados -p test03 ls
test-obj
4M
[root@ceph01 ~]# ceph osd pool  get-quota test03
quotas for pool 'test03':
  max objects: N/A
  max bytes  : 5 MiB  (current num bytes: 4194535 bytes)
[root@ceph01 ~]# rados -p test03 put test_put ./4M
[root@ceph01 ~]# ceph osd pool  get-quota test03
quotas for pool 'test03':
  max objects: N/A
  max bytes  : 5 MiB  (current num bytes: 8388839 bytes)

是不是有疑問了,不是最大限制5M嗎,這都上傳了8M了啊

是這樣的,在你的空間還沒有滿之前,哪怕就剩下1K了,這時候你上傳多大的檔案都可以傳進去,但是當他已經超過之後,你就傳不進去了。我們再來傳一個

[root@ceph01 ~]# rados -p test03 put test_put02 ./4M

你會發現他一直卡在這,對吧。他不會報錯,他也不會告訴你超過配額了。

配額超過之後他是不允許你執行任何上傳,下載操作的。注意。下載也是不行的,你只能執行get這是沒有問題的

3. 儲存池快照

ceph的快照功能有點雞肋,原因是他並不跟虛擬機器的快照功能一樣,還原快照就直接回到當時的那個場景,ceph的快照是這樣的。

首先你對現在的儲存池打一個快照,然後你想恢復的話,需要從某個快照裡面去將某個檔案get到本地,然後再從本地上傳到儲存池內

# 打快照
[root@ceph01 ~]# rados -p test03 ls
test-obj
[root@ceph01 ~]# rados -p test03 mksnap snap01
created pool test03 snap snap01
[root@ceph01 ~]# rados -p test03 lssnap
1	snap01	2024.05.25 10:30:05
1 snaps
# 刪除儲存池的檔案
[root@ceph01 ~]# rados -p test03 rm test-obj
# 檢視檔案,這時候他還會顯示,應該是個bug,但是這個檔案已經是被刪掉了,不信的話可以get一下
[root@ceph01 ~]# rados -p test03 ls
test-obj

# 將檔案還原
[root@ceph01 ~]# rados -p test03 -s snap01 get test-obj ./test-obj
selected snap 1 'snap01'
[root@ceph01 ~]# ls test-obj
test-obj

# 上傳到儲存池內
[root@ceph01 ~]# rados -p test03 put test-obj ./test-obj
[root@ceph01 ~]# rados -p test03 ls
test-obj

怎麼樣,現在是不是覺得非常的雞肋。如果要還原的檔案過多,那麼就需要一個個下載到本地然後重新上傳回去。非常之麻煩

4. 修改池屬性

當池被建立出來之後,我們需要修改他的一些屬性,比如修改副本數,修改pg數等等

4.1 列出屬性

[root@ceph01 ~]# ceph osd pool get test03 all
size: 3
min_size: 2
pg_num: 32
pgp_num: 32
crush_rule: replicated_rule
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
bulk: false

4.2 調整副本數為4

[root@ceph01 ~]# ceph osd pool set test03 size 4
set pool 4 size to 4
[root@ceph01 ~]# ceph osd pool get test03 size
size: 4

4.3 禁止刪除儲存池

[root@ceph01 ~]# ceph osd pool set test03 nodelete true
set pool 4 nodelete to true

nodelete 就是這個儲存池不允許被刪除

我們來刪刪看

[root@ceph01 ~]# ceph osd pool rm test03 
Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool test03.  If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it.
# 他報錯說要刪除儲存池的話需要寫2次儲存池的名字以及加上--yes-i-really-really-mean-it
[root@ceph01 ~]# ceph osd pool rm test03  test03 --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

現在他依然報錯,因為我們剛剛設定了不允許被刪除,現在我們取消

[root@ceph01 ~]# ceph osd pool set test03 nodelete false
set pool 4 nodelete to false
# 再來刪除
[root@ceph01 ~]# ceph osd pool rm test03  test03 --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

可以看到他一樣不讓刪除,他的意思是要刪除的話必須 將 mon_allow_pool_delete設定為true,預設為false

# 修改這個值
[root@ceph01 ~]# ceph config set mon mon_allow_pool_delete true
# 刪除池
[root@ceph01 ~]# ceph osd pool rm test03 test03 --yes-i-really-really-mean-it
pool 'test03' removed

5. 糾刪碼池管理

糾刪碼池在ceph的侷限性是隻能做物件閘道器,但是他不會儲存多個副本,空間利用率大大提升

5.1 原理

當上傳某個檔案的時候,他會將檔案拆成多個資料塊,然後存放的時候會再補充若干個校驗塊,他的冗餘能力為糾刪碼的塊數。假如我們現在有一個3M的檔案,被拆分成3個1M的資料塊,然後還有2個校驗塊,如果掛掉了2個資料塊,正好可以透過還剩下的1個資料塊+2個校驗塊來還原資料。如果3個資料塊都壞掉了那就還原不了

5.2 建立糾刪碼池

[root@ceph01 ~]# ceph osd pool create test04 erasure
pool 'test04' created

之前不是說建立糾刪碼就必須給他指定一個配置檔案嗎?我沒指定怎麼也建立出來了呢?我們來看看

[root@ceph01 ~]# ceph osd pool ls detail |grep erasure
pool 5 'test04' erasure profile default size 4 min_size 3 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 110 flags hashpspool stripe_width 8192

這裡我們可以看到他使用的預設的配置檔案,檢視預設配置檔案

# 檢視有哪些配置檔案
[root@ceph01 ~]# ceph osd erasure-code-profile ls
default
# 檢視配置檔案的詳細配置
[root@ceph01 ~]# ceph osd erasure-code-profile get default
k=2
m=2
plugin=jerasure
technique=reed_sol_van

5.2.1 建立自己的配置檔案

[root@ceph01 ~]# ceph osd erasure-code-profile set test_profile crush-failure-domain=osd k=3 m=2
[root@ceph01 ~]# ceph osd erasure-code-profile ls
default
test_profile
  • k:就是資料塊的個數
  • m: 就是校驗塊的數量
  • crush-failure-domain:故障域,意思就是要求故障域分配在不同的osd上,不需要分配在不同的主機上,為什麼不是host,因為分配在不同的主機上的話,需要k+m臺主機,但是我們現在只有3臺主機,所以需要改

5.2.2 使用自己的配置檔案建立池

[root@ceph01 ~]# ceph osd pool create test05 erasure test_profile
pool 'test05' created
[root@ceph01 ~]# ceph osd pool get test05 all
size: 5
min_size: 4
pg_num: 32
pgp_num: 32
crush_rule: test05
hashpspool: true
allow_ec_overwrites: false
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
erasure_code_profile: test_profile
fast_read: 0
pg_autoscale_mode: on
bulk: false

相關文章