go-fastdfs是一個基於http的分散式檔案系統,它基於大道至簡的設計理念,一切從簡設計,使得它的運...
https://m.gitee.com/sjqzhang/go-fastdfs
go-fastdfs是一個基於http協議的分散式檔案系統,它基於大道至簡的設計理念,一切從簡設計,使得它的運維及擴充套件變得更加簡單,它具有高效能、高可靠、無中心、免維護等優點。
大家擔心的是這麼簡單的檔案系統,靠不靠譜,可不可以用於生產環境?答案是肯定的,正因為簡單所以穩定。如果你擔心功能,那就跑單元測試,如果擔心效能,那就跑壓力測試,專案都自帶了,跑一跑更放心^_^。
支援curl命令上傳
支援瀏覽器上傳
支援HTTP下載
支援多機自動同步
支援斷點下載
支援配置自動生成
支援小檔案自動合併(減少inode佔用)
支援秒傳
支援斷點續傳(tus)
支援docker部署
支援自監控告警
支援叢集檔案資訊檢視
使用通用HTTP協議
無需專用客戶端(支援wget,curl等工具)
類fastdfs
高效能 (使用leveldb作為kv庫)
高可靠(設計極其簡單,使用成熟元件)
無中心設計(所有節點都可以同時讀寫)
優點
無依賴(單一檔案)
自動同步
失敗自動修復
按天分目錄方便維護
支援不同的場景
檔案自動去重
支援目錄自定義
支援保留原檔名
支援自動生成唯一檔名
支援瀏覽器上傳
支援檢視叢集檔案資訊
支援叢集監控郵件告警
支援小檔案自動合併(減少inode佔用)
支援秒傳
支援斷點續傳(tus)
支援docker部署
支援token下載token=md5(file_md5+timestamp)
運維簡單,只有一個角色(不像fastdfs有三個角色Tracker Server,Storage Server,Client),配置自動生成
每個節點對等(簡化運維)
所有節點都可以同時讀寫
啟動伺服器(已編譯,下載極速體驗,只需一分鐘)
./fileserver
命令上傳
curl -F file=@http-index-fs http://10.1.xx.60:8080/upload
WEB上傳(瀏覽器開啟)
http://yourserver ip:8080 注意:不要使用127.0.0.1上傳
程式碼上傳(選項參閱瀏覽器上傳)
python版本:
import requests
url = 'http://10.1.5.9:8080/upload'
files = {'file': open('report.xls', 'rb')}
options={'output':'json','path':'','scene':''} #參閱瀏覽器上傳的選項
r = requests.post(url, files=files)
print(r.text)
golang版本
package main
import (
"fmt"
"github.com/astaxie/beego/httplib"
)
func main() {
var obj interface{}
req:=httplib.Post("http://10.1.5.9:8080/upload")
req.PostFile("file","path/to/file")
req.Param("output","json")
req.Param("scene","")
req.Param("path","")
req.ToJSON(&obj)
fmt.Print(obj)
}
java版本
依賴(這裡使用了hutool工具包,更簡便)
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.4.3</version>
</dependency>
上傳程式碼
public static void main(String[] args) {
//檔案地址
File file = new File("D:\\git\\2.jpg");
//宣告引數集合
HashMap<String, Object> paramMap = new HashMap<>();
//檔案
paramMap.put("file", file);
//輸出
paramMap.put("output","json");
//自定義路徑
paramMap.put("path","image");
//場景
paramMap.put("scene","image");
//上傳
String result= HttpUtil.post("http://xxxxx:xxxx/upload", paramMap);
//輸出json結果
System.out.println(result);
}
更多語言請參考
斷點續傳示例
golang版本
package main
import (
"os"
"fmt"
"github.com/eventials/go-tus"
)
func main() {
f, err := os.Open("100m")
if err != nil {
panic(err)
}
defer f.Close()
// create the tus client.
client, err := tus.NewClient("http://10.1.5.9:8080/big/upload/", nil)
fmt.Println(err)
// create an upload from a file.
upload, err := tus.NewUploadFromFile(f)
fmt.Println(err)
// create the uploader.
uploader, err := client.CreateUpload(upload)
fmt.Println(err)
// start the uploading process.
fmt.Println( uploader.Upload())
}
更多客戶商請參考
部署圖 部署圖
有問題請點選反饋
重要說明
在issue中有很多實際使用的問題及回答(很多已關閉,請檢視已關閉的issue)
Q&A
在微信討論群中大家都問到go-fastdfs效能怎樣?
由於問的人太多,在這裡統一回答。
go-fastdfs的檔案定位與其它分散式系統不同,它的定址是直接定位,不經過任何元件,所以可以近似時間複雜度為o(1)[檔案路徑定位]
基本沒有效能損耗,專案中也附有壓測指令碼,大家可以自已進行壓測,群裡就不要太多討論問題了,人多每次回覆同樣的問題
大家也會覺得這群無聊。
已經使用fastdfs儲存的檔案可以遷移到go fastdfs下麼?
答案是可以的,你擔心的問題是路徑改變,go fastdfs為你考慮了這一點
curl -F file=@data/00/00/_78HAFwyvN2AK6ChAAHg8gw80FQ213.jpg -F path=M00/00/00/ http://127.0.0.1:8080/upload
同理可以用一行命令遷移所有檔案
cd fastdfs/data && find -type f |xargs -n 1 -I {} curl -F file=@data/{} -F path=M00/00/00/ http://127.0.0.1:8080/
以上命令可以過遷粗糙
可以寫一些簡單指令碼進行遷移
什麼是叢集,如何用Nginx管理多叢集?
1、在go-fastdfs中,一個叢集就是一個group。
2、請參閱部署圖
注意:配置中的 support_group_manage 引數設為true時,所有的url中都自動新增組資訊。
例如:http://10.1.5.9:8080/group/status
預設:http://10.1.5.9:8080/status
區別:多了group,對應配置中的 group 引數,這樣主要是為了解決一個Nginx反向代理多個group(叢集)
具體請參閱部署圖
如何搭建叢集?
一、先下載已編譯的可執行檔案(用最新版本)
二、執行可執行檔案(生成配置)
三、修改配置
peers:增加對端的http地址
檢查:
host:自動生成是否正確
peer_id:叢集內是否唯一
四、重新執行服器
五、驗證服務是否OK
適合海量儲存嗎?
答案:適合海量儲存
特別說明:
需然用leveldb作為元資料儲存,但不強依懶leveldb,
並且進行超過1億以上的檔案進行壓測(可以用專案提供的指令碼進行壓測,有問題及時反饋到issue),
1億檔案元資料大小約5G,匯出元資料文字大小22G
還需要安裝nginx麼?
可以不安裝,也可以選擇安裝
go fastdfs 本身就是一個高效能的web檔案伺服器。
能動態載入配置麼?
答案:是可以的,但要更新到最新版本
步驟:
1)修改 conf/cfg.json 檔案
2)訪問 http://10.1.xx.60:8080/reload
3) 注意:每個節點都需要進行同樣的操作
記憶體佔用很高是怎麼回事?
正常情況下,記憶體應該低於2G,除非每天上傳檔案超過百萬
記憶體異常,主要是叢集的檔案沒有同步,同時開啟了自動修復功能
處理辦法,刪除data目錄下當天的errors.md5檔案,關閉自動修復,重啟服務
參閱系統狀態說明
如何檢視叢集檔案資訊?
http://10.1.xx.60:8080/stat
如果出現檔案統計出錯怎麼辦?
請刪除 data目錄下的 stat.json檔案 重啟服務,請系統自動重新計算檔案數。
或者呼叫
http://10.1.xx.60:8080/repair_stat
可靠性怎樣,能用於生產環境麼?
本專案已大規模用於生產環境,如擔心不能滿足
可以在使用前對其各項特性進行壓力測試,有任何
問題可以直接提issue
能不能在一臺機器部置多個服務端?
不能,在設計之初就已考慮到叢集的高可用問題,為了保證叢集的真正可用,必須為不同的ip,ip 不能用 127.0.0.1
錯誤"peers": ["http://127.0.0.1:8080","http://127.0.0.1:8081","http://127.0.0.1:8082"]
正確"peers": ["http://10.0.0.3:8080","http://10.0.0.4:8080","http://10.0.0.5:8080"]
檔案不同步了怎麼辦?
正常情況下,叢集會每小時自動同步修復檔案。(效能較差,在海量情況下建議關閉自動修復)
那異常情況下怎麼?
答案:手動同步(最好在低峰執行)
http://172.16.70.123:7080/sync?date=20190117&force=1 (說明:要在檔案多的伺服器上執行,相關於推送到別的伺服器)
引數說明:date 表示同步那一天的資料force1.表示是否強制同步當天所有(效能差),0.表示只同步失敗的檔案
不同步的情況:
1) 原來執行N臺,現在突然加入一臺變成N+1臺
2)原來執行N臺,某一臺機器出現問題,變成N-1臺
如果出現多天資料不一致怎麼辦?能一次同步所有嗎?
答案是可以:(最好在低峰執行)
http://172.16.70.123:7080/repair?force=1
檔案不同步會影響訪問嗎?
答案:不會影響,會在訪問不到時,自動修復不同步的檔案。
如何檢視系統狀態及說明?
http://172.16.70.123:7080/status
注意:(Fs.Peers是不帶本機的,如果帶有可能出問題)
本機為 Fs.Local
sts["Fs.ErrorSetSize"] = this.errorset.Cardinality() 這個會導致記憶體增加
如何壓測?
先用gen_file.py產生大量檔案(注意如果要生成大檔案,自已在內容中乘上一個大的數即可)
例如:
# -*- coding: utf-8 -*-
import os
j=0
for i in range(0,1000000):
if i%1000==0:
j=i
os.system('mkdir %s'%(i))
with open('%s/%s.txt'%(j,i),'w+') as f:
f.write(str(i)*1024)
接著用benchmark.py進行壓測
也可以多機同時進行壓測,所有節點都是可以同時讀寫的
程式碼為什麼寫在一個檔案中?
一、目前的程式碼還非常簡單,沒必要弄得太複雜。
二、個人理解模組化不是分開多個檔案就表示模組化,大家可以用IDE去看一下程式碼結構,其實是已經模組化的。
支援斷點下載?
答案:支援
curl wget 如何
wget -c http://10.1.5.9:8080/group1/default/20190128/16/10/2G
culr -C - http://10.1.5.9:8080/group1/default/20190128/16/10/2G
Docker如何部署?
步驟:
一、構建映象
docker build . -t fastdfs
二、執行容器(使用環境變數 GO_FASTDFS_DIR 指向儲存目錄。)
docker run --name fastdfs -v ~:/data/fastdfs -e GO_FASTDFS_DIR=/data/fastdfs fastdfs
大檔案如何分塊上傳或斷點續傳?
一般的分塊上傳都要客戶端支援,而語言的多樣性,客戶端難以維護,但分塊上傳的功能又有必要,為此提供一個簡單的實現思路。
方案一、
藉助linux split cat 實現分割與合併,具體檢視 split 與cat 幫助。
分割: split -b 1M filename #按每個文1M
合併: cat x* > filename #合併
方案二、
藉助hjsplit
http://www.hjsplit.org/
具體自行實現
方案三、
建議用go實現hjsplit分割合併功,這樣具有跨平臺功能。(未實現,等你來....)
方案四、
使用內建的繼點續傳功能(使用protocol for resumable uploads協議,[詳情](https://tus.io/))
注意:方案四、只能指定一個上傳伺服器,不支援同時寫,並且上傳的url有變化
原上傳url: http://10.1.5.9:8080/<group>/upload
斷點上傳url: http://10.1.5.9:8080/<group>/big/upload/
上傳完成,再通過秒傳介面,獲取檔案資訊
如何秒傳檔案?
通過http get的方式訪問上傳介面
http://10.0.5.9:8080/upload?md5=filesum&output=json
引數說明:
md5=sum(file) 檔案的摘要演算法要與檔案務器的演算法一致(演算法支援md5|sha1),如果是斷點續傳,可以使用檔案的id,也就是urlolad後的id
output=json|text 返回的格式
叢集如何規劃及如何進行擴容?
建議在前期規劃時,儘量採購大容量的機器作為儲存伺服器,如果要兩個複本就用兩臺組成一個叢集,如果要三個複本
就三臺組成一個叢集。(注意每臺伺服器最好配置保持一樣)
如果提高可用性,只要在現在的叢集peers中加入新的機器,再對叢集進行修復即可。
修復辦法 http://172.16.70.123:7080/repair?force=1 (建議低峰變更)
如何擴容?
為簡單可靠起見,直接搭建一個新叢集即可(搭建就是啟動./fileserver程序,設定一下peers的IP地址,三五分鐘的事)
issue中chengyuansen同學向我提議使用增加擴容特性,我覺得對程式碼邏輯及運維都增加複雜度,暫時沒有加入這特性。
訪問限制問題
出於安全考慮,管理API只能在群集內部呼叫或者用127.0.0.1呼叫.
有問題請點選反饋 或加 二維碼