許金財
(廈門身份寶網絡科技有限公司 福建 廈門 361008)
隨著互聯網的高速發展,分布式文件系統的應用越來越廣泛。FastDFS是為互聯網應用量身定做的分布式文件系統,充分考慮了冗余備份、負載均衡、線性擴容等機制,并注重高可用、高性能等指標,適合用來存儲大量的圖片、視頻、電子文檔等文件。本文對分布式文件系統FastDFS進行研究,并提出了文件編碼到文件地址的轉換算法,有效地提升了文件地址的檢索速度[1]。
FastDFS是一個開源的輕量級分布式文件系統,采用C語言開發,支持Linux、FreeBSD等UNIX系統,充分考慮了冗余備份、負載均衡、線性擴容等機制,簡單、靈活、高效。2008年7月FastDFS發布第一個版本V1.00,截至目前最新版本是V6.07。FastDFS由跟蹤服務器(tracker server)、存儲服務器(storage server)和客戶端(client)3個部分組成,包括文件存儲、文件同步、文件訪問以及高容量和負載均衡,主要解決海量數據存儲問題。跟蹤服務器主要做調度工作,起到均衡的作用;存儲服務器主要采用分組方式提供容量和備份服務。FastDFS文件地址由FastDFS服務端生成并返回,包含了組名、文件目錄和文件名。
FastDFS客戶端與服務端采用TCP通信協議,協議包由header和body兩部分組成,其中header由8字節的消息體長度、1字節的命令字和1字節的狀態碼組成,消息體由不同的命令字確定,允許空內容[2]。
FastDFS應用中主要包括文件上傳和文件下載兩種應用流程。
文件上傳時,由FastDFS客戶端向跟蹤服務器發送帶有101命令字的消息請求,跟蹤服務器按照負載均衡算法返回可用的存儲服務器Socket地址,再由FastDFS客戶端向指定的Socket地址發送帶有11命令字和文件內容(可攜帶文件信息)的消息請求完成文件的上傳,存儲節點返回帶有組名和文件地址的文件標識,例如:group2/M07/1B/D8/ClhYsVz0lV6AWXPXAABKRaBPLb0897.jpg,見圖1。

圖1 文件上傳流程
在FastDFS中,上傳后的文件標識不是由客戶端指定,而是由Storage節點生成后返回給客戶端的,文件標識作為文件訪問憑證。
文件下載時,由FastDFS客戶端向Tracker服務器發送帶有102命令字和文件標識的消息請求,Tracker按照文件標識找到匹配的Storage存儲節點服務器Socket地址,再由FastDFS客戶端向指定的Socket地址發送帶有14命令字和文件標識的消息請求,存儲節點返回文件內容,見圖2。

圖2 文件下載流程
FastDFS返回的文件標識,其表現形式類似于文件路徑,字符長度在46~61,與業務系統整合應用時,常規做法是增加UUID唯一識別碼與文件標識進行映射,然后將UUID唯一標識碼作為業務數據對應的文件編碼進行存儲。文件標識映射需要使用到數據庫或Redis緩存,在高并發查詢檢索時會給服務器帶來不小的負擔。
結合FastDFS系統特點,本文采用了幾種常見的Base編碼方案來研究FastDFS文件尋址算法。文件上傳時,將服務端返回的FastDFS文件標識解析為210 bit數據內容,經過Base編碼后生成36個字節的文件編碼作為文件的業務標識。文件下載時,將文件編碼經過Base解碼為210 bit數據內容,再轉換為文件標識。目前已在多個項目的生產環境中使用FastDFS分布式文件系統和文件尋址算法。
把二進制數據轉化為可打印字符集數據稱為base encoding,編碼后的數據方便用于存儲和網絡傳輸,本文中涉及Base32、Base64和Base62 3種編碼方案。
Base32基于32個包括字母A~V、數字0~9的可打印字符。
Base64按照bit流進行編碼,24(6和8的最小公倍數)bit為一組。
Base62是一種基于62個可打印字符來表示二進制數據的表示方法,可打印字符包括字母A~Z、a~z、數字0~9,共有62個字符。Base62提供了一種無符號輸出的Base64的編碼方案,在許多應用場合其純字母和數字的輸出形式,可以有效規避因為符號帶來的各種負面影響,并能夠有效削減或兼容各種Base64的變種形式。
FastDFS文件標識由組名、主目錄索引、一級子目錄、二級子目錄、文件名5個部分組成。
(1)最大支持512個分組(V2.06之前的版本最大支持64個分組);
(2)最大支持256個主目錄;
(3)最大支持256×256個子目錄;
(4)文件名固定為34個字符,可包含“-”和“_”半角符號;
(5)支持不超過6個字符的文件擴展名(允許無擴展名)。
文件名的前27個字符是base64編碼字符,文件名可解析為以下6個信息。
(1)存儲節點服務器IPv4(32位整數);
(2)文件創建時間(UNIX時間戳,32位整數);
(3)文件大小(64位整數);
(4)文件CRC32校驗碼(32位整數);
(5)文件擴展名(例如.jpg);
(6)隨機數(用來填補文件編號長度,其長度與文件擴展名的長度加起來等于7)。
前4個信息組合起來的160 bit數據內容經過base64編碼后形成27個字符的唯一識別碼,FastDFS支持不超過6個字符的文件擴展名,為了保持長度的一致性,當文件擴展名小于6個字符時,FastDFS將隨機生成的阿拉伯數字填入文件標識中。
FastDFS文件標識編碼原則,見圖3。

圖3 FastDFS文件標識編碼圖解
(1)使用group1至group512對分組名稱進行統一命名(不支持其他自定義命名的組名),編碼時僅保留分組索引;
(2)對通用的文件擴展名進行映射管理,最多可設置36個通用的文件擴展名映射編碼;
(3)使用Base編碼后的文件編碼長度固定為36個字符;
(4)支持未設置映射編碼的文件擴展名(此時應使用文件編碼.后綴名完成文件尋址)。
FastDFS文件標識編碼方式如下。
(1)使用2個32進制編碼裝載10位二進制(方便快速識別分組信息);
(2)使用7個62進制編碼裝載41位二進制;
(3)使用9個62進制編碼裝載53位二進制。
FastDFS文件編碼尋址過程如下。
(1)使用Base32將文件編碼的前兩個字符解碼為10 bit數據內容;
(2)使用Base62將文件編碼的第3~9個字符解碼為41 bit數據內容;
(3)使用Base62將文件編碼的剩余27個字符分3次解碼為3組53 bit數據內容;
(4)將開頭的10 bit數據內容轉換為分組索引并加上group分組前綴(見圖3的group2);
(5)從41 bit數據內容中取出前3個字節,轉換為文件目錄(見圖3的M07/1B/D8);
(6)從41 bit數據內容中取出1 bit,其他3個53 bit數據內容中分別取出5 bit,按順序組成擴展數據項,其中十進制的第1個數據位為預定義文件擴展名(見圖3的.jpg),其他數值為文件標識中擴展部分的隨機阿拉伯數字(見圖3的897);
(7)其他剩下的160 bit數據內容,使用Base64解碼為27個字符的唯一識別碼(見圖3的ClhYsVz0lV6AWXP XAABKRaBPLb0);
(8)最終尋址結果:group2/M07/1B/D8/ClhYsVz0lV6 AWXPXAABKRaBPLb0897.jpg。
本文結合公司多個項目開發過程中碰到的圖片存儲服務文件編碼和檢索問題,研究了基于FastDFS分布式文件系統的文件編碼到文件地址的轉換算法,有效提升了文件地址的檢索速度[3]。