glusterfs源碼框架分析: https://www.jianshu.com/p/699e9c17deff
經過大量的蒐集網上的素材,總結下文(寫的比較粗糙)
函數API
STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf,
preparent, postparent, xdata);
參數介紹
op: 操作類型
frame: 當前請求的stack frame
params: 任何其他的入口點相關的參數(比如針對此fop的inodes, file descriptors, offsets, data buffers等)
op_ret: fop的到目前的狀態(讀的字節數或者寫的字節數,常常0表示fop成功,-1表示失敗)
op_errno: 標準錯誤碼(在fop失敗的情況下)
fd: 打開的文件描述符
inode:
buf
https://blog.csdn.net/liuaigui/article/details/7786215/
Per Request Context請求上下文私有變量: local指針
local指針:每個translator-stack frame都有一個local指針,用來儲存該translator特定的上下文,這是在調用和回調函數間存儲上下文的主要機制
。
// dispatch函數
param_t* p = malloc(sizeof(param_t));
p->data = ...;
frame->local = p; // 給local賦值
-----------------------
// cbk函數
param_t* p = frame->local; // 取出local
frame->local = NULL; // 將local設爲NULL
free(p->data); // 記得釋放param_t
free(p);
STACK_UNWIND(...,...)
注意:在cbk函數中,使用完frame->local後,記得將其設爲NULL。
要記住:每個幀frame的非NULL的local域當要毀棧時要用GF_FREE來釋放,不用做其他的清理工作。如果local結構裏包含指針或對其他對象的引用,需要我們自己進行這些資源的清理。在毀棧前,內存或者其他資源先清理是個好的習慣,爲此就不能依靠GF_FREE來自動清理。最安全的方式是定義我們自己的xlator相關的destructor,在調用STACK_UNWIND前手動調用。
形參類型:
inode_t *inode
xlator_t *xlator
value是uint64_t類型(64位整形)
inode_ctx_put (inode, xlator, value) // /* NB: put, not set */把value放到inode裏?
inode_ctx_get (inode, xlator, &value) // 從inode中獲取值,保存到value
inode_ctx_del (inode, xlator, &value) // _del函數實際是破壞性get,先返回然後刪除值
fd_ctx_set (fd, xlator, value)
fd_ctx_get (fd, xlator, &value)
fd_ctx_del (fd, xlator, &value)
dict_t 字典
一個通用的排序字典或hash-map的數據結構, <key, value>分別是<字符串, 任意類型>。任意類型一般是整數、字符串、二進制
作用:
1. 用於調用、回調函數
2. 傳遞不同的模塊選項,包括xlator初始化選項
。事實上,目前xlator的init函數,主要用於解析字典中的選項
選項 options[]
向xlator中添加一個選項,需要在xlator的options數組中添加實體,解析後的選項和其他信息可以存放在xlator_t結構體的private內
VFS
Vritual Filesystem 是給用戶空間程序提供統一的文件和文件系統訪問接口的內核子系統。藉助VFS,即使文件系統的類型不同(比如NTFS和ext3),也可以實現文件系統之間交互(移動、複製文件等),
從用戶空間程序的角度來看,VFS提供了一個統一的抽象、接口。這使得用戶空間程序可以對不同類型的文件系統發起統一的系統調用,而不需要關心底層的文件系統類型。
從文件系統的角度來看,VFS提供了一個基於Unix-style文件系統的通用文件模型,可以用來表示任何類型文件系統的通用特性和操作。底層文件系統提供VFS規定的接口和數據結構,從而實現對linux的支持。
複製卷——self-heal自修復
- 假設是2副本構成的集羣:即
node1:/data/brick、node2:/data/brick構成複製卷 - 殺死使node1上的brick的服務器進程:使brick的塊Online狀態變成N
kill -9 xxx - client在卷掛載目錄/mnt上創建file文件
- 分別在node1、node2的/data/brick目錄下查看是否有file文件
node1:無
node2:有 - 將node1的brick重新上線
gluster volume start [卷名] force - 再次檢查node1的brick目錄下是否有新建的file文件
結果:有!因爲集羣進行了自修復,使得node2節點上的數據同步到node1上
xlator中的調用(STACK_WIND)與回調(STACK_UNWIND)
STACK_WIND: 沿着volume 文件設置的xlator 路徑,傳遞此請求
STACK_UNWIND: 當本xlator層完成對req的處理,要從本層的回調中把請求傳回上一個xlator時
http://www.bubuko.com/infodetail-2761168.html
向掛載點寫入數據(Linux向VFS傳遞這個動作)–>/dev/fuse–>fuse_xlator_t節點(進入xlator樹)–>STACK_WIND遞交給子節點,直到到達樹的葉子節點–>STACK_UNWIND遞交給父節點,直到到達fu_xlator_t–>FUSE–>VFS
App執行一次IO操作的流程
-
當APP指向系統調用向掛載點/mnt/glusterfs[寫入數據]時,讀寫操作將會被交給VFS來處理,VFS會將請求交給FUSE內核模塊,而FUSE又會通過設備/dev/fuse將數據交給glusterfs Client(此時,實際的寫處理遞交給了 glusterfs 系統樹的 fuse_xlator_t 這個根節點,這樣, [一個寫數據流就正式流入了系統的 xlator_t 結構樹])。
-
請求的傳遞[dispatch+STACK_WIND]
寫處理請求從fuse_xlator_t,在(dispatch函數中)把該請求使用STACK_WIND傳遞給下一個或多個translator,直到到達client xlator(client模塊用於與brick端通信);繼續調用STACK_WIND傳遞給glusterfsd服務端,直到到達glusterfsd服務端的最後一個xlator
3.請求的處理[STACK_UNWIND+cbk]
(請求傳遞到最後一個xlator後,將不會調用STACK_WIND,而是調用STACK_UNWIND將處理後的結果和返回值傳遞給父volume,對應着調用父volume中的_cbk函數,即XXX_cbk),直到傳遞到Client的第一個xlator(fuse_xlators)。這樣,一個write請求操作纔算完成!
- 最後,處理的結果從fuse_xlators, 通過FUSE內核模塊返回給用戶。
基本概念
1、gfid:GFS卷中的每個文件或目錄都有唯一的標識
1、volume:創建一個卷volume:邏輯上有N個brick構成
2、Brick :
存儲目錄是Glusterfs的基本存儲單元,由可信存儲池中服務器上對外輸出的目錄表示。存儲目錄的格式由服務器和目錄的絕對路徑構成,具體如下:
SERVER:EXPORT.例如:myhostname:/exports/myexportdir/
說明1:在創建卷的時候,指定Brick的掛載目錄:
gluster create [卷名]:[Brick]
—>gluster create [卷名]:[/主機名/目錄名]
說明2:用戶對捲進行操作時,實際上數據存放在Brick上
4種進程
-
gluster:命令客戶端
主要功能是解析命令行參數,把命令發送給glusterd模塊執行,[只與glusterd管理進程通信] -
glusterd:文件系統管理進程,
(1) [處理gluster發過來的命令]
(2) 處理集羣管理、存儲池管理、brick管理、負載均衡、快照管理等。
集羣信息、存儲池信息和快照信息等都是以配置文件的形式存放在服務器中,當客戶端掛載存儲時, glusterd會把存儲池的配置文件發送給客戶端。 -
glusterfs:是客戶端模塊
(1) 負責通過[mount]掛載集羣中某臺服務器的存儲池,以[目錄]的形式呈現給用戶
(2) 用戶從此目錄讀寫數據時,客戶端根據從glusterd模塊獲取的存儲池的配置文件信息,通過[DHT算法計算文件所在服務器的brick位置],然後通過Infiniband RDMA 或Tcp/Ip 方式[把數據發送給brick,等brick處理完,給用戶返回結果]。
(3) 存儲池的副本、條帶、hash、EC等邏輯都在客戶端處理。 -
glusterfsd:是服務端模塊
(1) 存儲池中的[每個brick都會啓動一個glusterfsd進程]。
(2) 此模塊主要是[處理客戶端的讀寫請求,從關聯的brick所在磁盤中讀寫數據,然後返回給客戶端]。
gfs中的xlator的作用
kvm kvm虛擬機進程
io-retry xlator IO錯誤重試模塊,根據錯誤碼,決定是否進行io重試
io-split xlator API模式下生效,將大的IO按照128K切分
ssd-cache xlator 提供讀cache,cache可緩存在SSD,連接到ssd-cached
qemu-lvm xlator
配合bd模塊的lvm的使用,進行bd文件的設置,這樣qcow2文件將使用lvm分區直接IO
dht xlator 文件的哈希分佈,2^32區間劃分
afr xlator 文件級別鏡像冗餘,類似raid1,VS加入了大量的修復,腦裂的處理代碼
client xlator client模塊用於與brick端通信
server xlator 即brick端,用於連接客戶端
io-stats xlator 統計io數據,可定位性能問題
exclusive xlator 排他插件,避免同一虛擬機文件被多個客戶端進程讀寫
io-threads xlator 將IO並行分發到不同線程,提高性能,並能設置IO優先級
locks xlator 用於實現gluster內部鎖和posix鎖,與afr插件有耦合
changelog xlator 控制擴展屬性中的changelog字段,記錄操作的是否成功entry/data/metadata,與afr插件有耦合
bd xlator block device,bd文件的讀寫由lvm替代文件系統,bd文件數據和元數據操作兩分離
posix xlator 訪問本地文件系統
ssd-cached 提供真正的ssd緩存功能,單實例運行
ssdc-cli.js 用於收集ssd-cached信息和設置ssd-cached參數
glusterfs的常用命令
https://www.jianshu.com/p/31e6a2870803
https://www.cnblogs.com/netonline/p/9102004.html
實戰: 設計新的xlator,加入到gfs
null xlator的構造(劉愛貴)
https://blog.csdn.net/liuaigui/article/details/7786215/
GlusterFS的audit operation xlator設計實現方案
https://blog.csdn.net/lavorange/article/details/44902541
https://blog.csdn.net/lavorange/article/details/45246175
trashdir回收站目錄只讀權限以及白名單的設計與實現
https://blog.csdn.net/lavorange/article/details/47863923
GlusterFS安裝
1、編譯&安裝
3臺node機器,相互之間能ping通
下載gfs源代碼,編譯&安裝(安裝成功後,會自動啓動glusterd服務)
gluster peer probe <主機名>
創建卷
2、掛載卷
假設已經安裝好3個node的gfs集羣,並創建了卷,後面要進行卷掛載
。
在3臺node上安裝了gfs源碼&創建了一個卷後,3臺node既作爲服務端brick,又作爲客戶端。
每個node的客戶端若想訪問卷,就必須在本node系統下創建一個本地目錄,然後將卷掛載到本地目錄。
掛載完畢後,在node上訪問本地目錄,就相當於在捲上執行了io操作。(即:在node上寫入一個文件,本質上該文件將會被分佈存儲到卷的各個brick對應的目錄上!!!)