Ceph讀寫流程
一、Osd中的模塊
消息封裝
在OSD上發送和接收信息。有兩類:
1.cluster_messenger -與其它OSDs和monitors溝通
2.client_messenger -與客戶端溝通
消息調度
Dispatcher類,主要負責消息分類
工作隊列
1. OpWQ: 處理ops(從客戶端)和sub ops(從其他的OSD)。運行在op_tp線程池。
2. PeeringWQ: 處理peering任務,運行在op_tp線程池。
3. CommandWQ:處理cmd命令,運行在command_tp。
4. RecoveryWQ: 數據修復,運行在recovery_tp。
5. SnapTrimWQ: 快照相關,運行在disk_tp。
6. ScrubWQ: scrub,運行在disk_tp。
7. ScrubFinalizeWQ: scrub,運行在disk_tp。
8. RepScrubWQ: scrub,運行在disk_tp。
9. RemoveWQ: 刪除舊的pg目錄。運行在disk_tp。
線程池
有4種 OSD線程池:
1. op_tp: 處理ops和sub ops
2. recovery_tp:處理修復任務
3. disk_tp: 處理磁盤密集型任務
4. command_tp: 處理命令
二、Ceph讀流程
注:索引的格式,查找更新索引、如何持久化的,還沒搞清楚。
沒有所謂索引,一切皆規則:
每個object的文件名格式為:
objectname_key_head(snap_num)_hash_namespace_poolid
? objectname:對象名
? key、namespace:都是客戶端指定,做名稱空間細分用。當塊兒設備使用時,一般都置為空
? head(snap_num):snapshot版本
? hash:由objectname計算得到,u_int32_t類型,這里轉換為16進制字符打印,如3AF0B980
? poolid:pool的id
目錄結構:
數據目錄/PG名稱/子目錄/object文件名
舉例說明:
/data09/ceph/osd2/current/0.0_head/DIR_0/DIR_8/DIR_9/10000007af4.00000000__head_3AF0B980__0
其中,子目錄是根據object文件名中hash字段的字符反向排列生成。當一個目錄中的文件個數大于配置值(merge_threshold * 16 * split_multiplier)時,會建子目錄,對文件進行歸檔。
ReplicatedPG.h
ReplicatedPG.cc
int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)函數中的
Case CEPH_OSD_OP_READ分支
r = osd->store->fiemap(coll, soid, op.extent.offset, op.extent.length, bl);
r = pgbackend->objects_read_sync(
soid, miter->first, miter->second, &tmpbl);
pgbackend->objects_read_sync轉int ReplicatedBackend::objects_read_sync調用 store->read(coll, hoid, off, len, *bl) ,來自ObjectStore::read
三、Ceph寫流程
階段1:主節點發請求
階段2:從節點處理請求
osd->store->queue_transactions(&osr, rm->tls, onapply, oncommit);
這里注冊的兩個回調:
Context *oncommit = new C_OSD_RepModifyCommit(rm); 當日志寫入磁盤后被調用
Context *onapply = new C_OSD_RepModifyApply(rm); 當該操作被處理后被調用
分別向主節點做ACK和ON_DISK兩種回應。
注: transaction 封裝, journal log 寫入細節,對象寫入細節還沒來得及看 。
階段3:主節點接收從節點回應,并回應客戶端
