原文:https://www.sohu.com/a/120065877_468741
背景
Ceph提供了三種存儲類型:塊存儲、文件存儲和對象存儲,本文主要介紹對象存儲的RGW基本原理和應用場景。
RGW
1
什么是對象存儲?
對象存儲(雲存儲)是面向對象/文件的、海量的互聯網存儲。對象存儲里的對象是經過封裝了的文件,在對象存儲系統里, 不能直接打開/修改文件,但可以像ftp一樣上傳文件,下載文件等。另外,對象存儲沒有像文件系統那樣有一個很多層級 的文件結構,而是只有一個“桶”的概念(也就是存儲空間),“桶”里面全部都是對象,是一種非常扁平化的存儲方式。 其最大的特點就是它的對象名稱就是一個域名地址,一旦對象被設置為“公開”,所有網民都可以訪問到。對象存儲最主 流的使用場景,就是存儲網站、移動app等互聯網/移動互聯網應用的靜態內容(視頻、圖片、文件、軟件安裝包等等)。
2
什么是RGW?
RGW為Rados Gateway的縮寫,ceph通過RGW為互聯網雲服務提供商提供對象存儲服務。RGW在librados之上向應用提供訪問ceph集群的RestAPI, 支持Amazon S3和openstack swift兩種接口。對RGW最直接的理解就是一個協議轉換層,把從上層應用符合S3或Swift協議的請求轉換成rados的請求, 將數據保存在rados集群中。
3
幾個內部基本概念
zone:包含多個RGW實例的一個邏輯概念。zone不能跨集群。同一個zone的數據保存在同一組pool中。
zonegroup:一個zonegroup如果包含1個或多個zone。如果一個zonegroup包含多個zone,必須指定 一個zone作為master zone,用來處理bucket和用戶的創建。一個集群可以創建多個zonegroup,一個zonegroup也可以跨多個集群。
realm:一個realm包含1個或多個zonegroup。如果realm包含多個zonegroup,必須指定一個zonegroup為master zonegroup, 用來處理系統操作。一個系統中可以包含多個realm,多個realm之間資源完全隔離。
4
幾個外部基本概念
user:對象存儲的使用者,默認情況下,一個用戶只能創建1000個存儲桶。
bucket:存儲桶,用來管理對象的容器。
object:對象,泛指一個文檔、圖片或視頻文件等,盡管用戶可以直接上傳一個目錄,但是ceph並不按目錄層級結構保存對象, ceph所有的對象扁平化的保存在bucket中。
5
訪問流程
下圖展示了應用、RGW、ceph集群的關系:
應用通過RGW訪問集群流程如下:
● S3或Swift 應用通過http協議發送請求到RGW。
● RGW從http請求中解析出s3或swift協議數據,調用librados接口,將對應的請求發送到rados集群中。
注:圖中load balance非必須,只要在存在多個RGW做負荷分擔時需要。
6
數據存儲位置
對象存儲涉及各種類型的數據,ceph將不同類型的數據存儲在不同的pool中,RGW涉及的pool分為兩大類:
● 保存集群數據的pool,比如用來保存realm信息,zonegroup信息,zone信息,使用哪個pool來保存哪個信息在配置文件中指定, 默認保存在.rgw.zone中。
●保存跟單個zone相關數據的pool,在創建zone時指定,默認情況下,pool名以zone名+rgw+保存數據類型來命名,例如下面名為z1的zone默認pool如下:
注:RGW需要用到的這些pool最好在使用之前手動創建,如果不手動創建,RGW會在需要時自動創建。手動創建的好處是 我們可以根據需要指定pool的PG數,crush規則等。
下面詳細說明RGW涉及到的各個pool的作用:
domain_root:
保存bucket和bucket元數據。
control_pool:
在RGW上電時,在control pool創建若干個對象用於watch-notify,主要作用為當一個zone對應多個RGW,且cache使能時, 保證數據的一致性,其基本原理為利用librados提供的對象watch-notify功能,當有數據更新時,通知其他RGW刷新cache, 后面會有文檔專門描述RGW cache。
gc_pool:
RGW中大文件數據一般在后台刪除,該pool用於記錄那些待刪除的文件對象。
lc_pool:
保存對象生命周期執行狀態。
log_pool:
各種log信息,如op log、數據同步log、過期對象等。
intent_log_pool:
目前沒用。
usage_log_pool:
存儲計量數據統計,比如上傳文件多少次,下載多少次,遍歷bucket多少次之類。
user_keys_pool:
存儲用戶AK和uid的對應關系,方便通過用戶restful請求的ak找到用戶id。
user_email_pool:
存儲swift key和uid的對應關系。
user_swift_pool:
存儲用戶email和uid的對應關系。
user_uid_pool:
存儲用戶信息,和用戶下bucket列表。
index_pool:
保存bucket中對象列表,index_pool可以配置多個,跟data_pool、data_extra_pool一起組成placement_pool, 在創建bucket時指定數據保存到哪一組placement_pool中。
data_pool:
保存對象數據,data_pool可以有多個。
data_extra_pool:
Multipart upload過程中一些中間態的數據,會存在該pool上。這些數據可以幫助用戶進行斷點續傳及垃圾數據回收。
7
應用場景
● 頻繁IO的網盤。
● 有海量數據歸檔和備份需求的互聯網應用企業
雲備份的企業用戶。
2.RGW的內部結構和處理流
以下是RGW的內部邏輯處理層級結構圖:
-
HTTP 前端接收請求數據並保存在相應的數據結構中。
-
REST API 通用處理層從 HTTP 語義中解析出 S3 或 Swift 數據並進行一系列檢查。
-
檢查通過后,根據不同 API 操作請求執行不同的處理流程。
-
如需從 RADOS 集群中獲取數據或者往 RADOS 集群中寫入數據,則通過 RGW 與 RADOS 接口適配層調用 librados 接口將請求發送到 RADOS 集群中獲取或寫入相應數據。
二、RGW對外的的三類基礎數據邏輯實體
RGW對外提供三種基礎數據邏輯實體:
- 用戶
- 存儲桶
- 對象
1.用戶
RGW兼容AWS S3和OpenStack Swift。RGW user對應S3 user,RGW user對應Swift Account,RGW subuser對應Swift user。
用戶數據信息包含:
- 用戶認證信息:S3(access key, secret key), Swift(secret key)
- 訪問控制權限信息:包含操作訪問權限(read、write、delete等)和訪問控制列表ACL
- 用戶配額信息:防止某些用戶占用過多存儲空間,根據用戶付費情況配置存儲空間。
2.存儲桶(bucket)
存儲桶是對象的容器,是為了方便管理和操作具有相同屬性的一類對象而引入的一級管理單元。
存儲桶信息包含:
- 基礎信息:(保存在對應RADOS對象的數據部分)RGW關注的信息,包含bucket配額信息(最大對象數目或最大對象大小總和),bucket placement rule,bucket中的索引對象數目等等。
- 擴展信息:(保存在對應RADOS對象的擴展屬性)對RGW透明的一些信息,如用戶自定義的元數據信息。
對於bucket placement rule,
3.對象
RGW中的應用對象對應RADOS對象。應用對象上傳分整體上傳和分段上傳,不同的上傳方式應用對象對應RADOS對象的方式不同。
首先介紹三個概念:
- rgw_max_chunk_size:分塊大小,RGW下發至RADOS集群的單個IO的大小。
- rgw_obj_stripe_size:條帶大小,multipart除首對象外的分段其他大小
- class RGWObjManifest:管理應用對象和RADOS對象的對應關系。
3.1 整體上傳
- 應用對象大小小於等於分塊大小:用戶上傳的一個對象只對應一個 RADOS 對象,該 RADOS 對象以應用對象名稱命名,應用對象元數據也保存在該 RADOS 對象的擴展屬性中。
- 應用對象大小大於分塊大小:應用對象被分解成一個大小等於分塊大小的首對象,多個大小等於條帶大小的中間對象,和一個大小小於等於條帶大小的尾對象。首對象以應用對象名稱命名,在 RGW 中將該對象稱為head_obj,該對象的數據部分保存了應用對象前 rgw_max_chunk_size 字節的數據,擴展屬性部分保存了應用對象的元數據信息和manifest信息。中間對象和尾對象保存應用對象剩余的數據,對象名稱為
“shadow_” + “.” + “32bit 隨機字符串” + “_” + “條帶編號”
,其中條帶編號從1開始。
3.2 分段上傳
RGW依照條帶大小將應用對象的每一個分段分成多個RADOS對象,每個分段的第一個 RADOS 對象名稱為:
“_multipart_” + “用戶上傳對象名稱” + “分段上傳ID” + “分段編號”
其余對象的名稱為:“_shadow_” + “用戶上傳對象名稱” + “分段上傳ID” + “分段編號” + “_” + “條帶編號”
當所有的分段上傳結束后,RGW 會從 data_extra_pool 中的分段上傳臨時對象中讀取各個分段信息,主要是各分段的 manifest 信息,組成一個 manifest;然后生成一個新的 RADOS 對象,即 head obj,用來保存分段上傳的應用對象的元數據信息和各分段的manifest。