一:FastDFS簡介
1:FastDFS簡介
FastDFS是一個開源的輕量級分散式檔案系統,功能包括:檔案儲存、檔案同步、檔案訪問(檔案上傳、檔案下載)等,解決了大容量儲存和負載均衡的問題。特別適合中小檔案(建議範圍:4KB < file_size <500MB),對以檔案為載體的線上服務,如相簿網站、視訊網站等。
(1):單機時代 初創時期由於時間緊迫,在各種資源有限的情況下,通常就直接在專案目錄下建立靜態資料夾,用於使用者存放專案中的檔案資源。 如果按不同型別再細分,可以在專案目錄下再建立不同的子目錄來區分。如resources\static\file、resources\static\img等 # 優點:這樣做比較便利,專案直接引用就行,實現起來也簡單,無需任何複雜技術,儲存資料庫記錄和訪問起來也很方便。 # 缺點:如果只是後臺系統的使用一般也不會有什麼問題,但是作為一個前端網站使用的話就會存在弊端。一方面,檔案和程式碼耦合 在一起,檔案越多存放越混亂;另一方面,如果流量比較大,靜態檔案訪問會佔據一定的資源,影響正常業務進行,不利於網站 快速發展。 (2):獨立檔案伺服器 隨著公司業務不斷髮展,將程式碼和檔案放在同一伺服器的弊端就會越來越明顯。為了解決上面的問題引入獨立圖片伺服器,工作 流程如下:專案上傳檔案時,首先通過ftp或者ssh將檔案上傳到圖片伺服器的某個目錄下,再通過ngnix或者apache來訪問此 目錄下的檔案,返回一個獨立域名的圖片URL地址,前端使用檔案時就通過這個URL地址讀取。 # 優點:圖片訪問是很消耗伺服器資源的(因為會涉及到作業系統的上下文切換和磁碟I/O操作),分離出來後,Web/App伺服器 可以更專注發揮動態處理的能力;獨立儲存,更方便做擴容、容災和資料遷移;方便做圖片訪問請求的負載均衡,方便應用各 種快取策略(HTTP Header、Proxy Cache等),也更加方便遷移到CDN。 # 缺點:單機存在效能瓶頸,容災、垂直擴充套件性稍差 (3):分散式檔案系統 通過獨立檔案伺服器可以解決一些問題,如果某天儲存檔案的那臺服務突然down了怎麼辦?可能你會說,定時將檔案系統備份, 這臺down機的時候,迅速切換到另一臺就OK了,但是這樣處理需要人工來干預。另外,當儲存的檔案超過100T的時候怎麼辦? 單臺伺服器的效能問題?這個時候我們就應該考慮分散式檔案系統了。業務繼續發展,單臺伺服器儲存和響應也很快到達了瓶頸, 新的業務需要檔案訪問具有高響應性、高可用性來支援系統。分散式檔案系統,一般分為三塊內容來配合,服務的儲存、訪問的 仲裁系統,檔案儲存系統,檔案的容災系統來構成,仲裁系統相當於檔案伺服器的大腦,根據一定的演算法來決定檔案儲存的位置, 檔案儲存系統負責儲存檔案,容災系統負責檔案系統和自己的相互備份。 # 優點:擴充套件能力: 毫無疑問,擴充套件能力是一個分散式檔案系統最重要的特點;高可用性: 在分散式檔案系統中,高可用性包含兩 層,一是整個檔案系統的可用性,二是資料的完整和一致性;彈性儲存: 可以根據業務需要靈活地增加或縮減資料儲存以及增刪 儲存池中的資源,而不需要中斷系統執行 # 缺點:系統複雜度稍高,需要更多伺服器
2:FastDFS系統架構
FastDFS由跟蹤伺服器(Tracker Server)、儲存伺服器(Storage Server)和客戶端(Client)構成。
(1)跟蹤伺服器Tracker Server
主要做排程工作,起到均衡的作用;負責管理所有的 storage server和 group,每個 storage 在啟動後會連線 Tracker,告知自己所屬 group 等資訊,並保持週期性心跳。tracker根據storage的心跳資訊,建立group==>[storage serverlist]的對映表。
Tracker需要管理的元資訊很少,會全部儲存在記憶體中;另外tracker上的元資訊都是由storage彙報的資訊生成的,本身不需要持久化任何資料,這樣使得tracker非常容易擴充套件,直接增加tracker機器即可擴充套件為tracker cluster來服務,cluster裡每個tracker之間是完全對等的,所有的tracker都接受stroage的心跳資訊,生成後設資料資訊來提供讀寫服務。
(2)儲存伺服器Storage Server
主要提供容量和備份服務;以 group 為單位,每個 group 內可以有多臺 storage server,資料互為備份。以group為單位組織儲存能方便的進行應用隔離、負載均衡、副本數定製(group內storage server數量即為該group的副本數),比如將不同應用資料存到不同的group就能隔離應用資料,同時還可根據應用的訪問特性來將應用分配到不同的group來做負載均衡;缺點是group的容量受單機儲存容量的限制,同時當group內有機器壞掉時,資料恢復只能依賴group內地其他機器,使得恢復時間會很長。
group內每個storage的儲存依賴於本地檔案系統,storage可配置多個資料儲存目錄,比如有10塊磁碟,分別掛載在/data/disk1-/data/disk10,則可將這10個目錄都配置為storage的資料儲存目錄。storage接受到寫檔案請求時,會根據配置好的規則選擇其中一個儲存目錄來儲存檔案。為了避免單個目錄下的檔案數太多,在storage第一次啟動時,會在每個資料儲存目錄裡建立2級子目錄,每級256個,總共65536個檔案,新寫的檔案會以hash的方式被路由到其中某個子目錄下,然後將檔案資料作為本地檔案儲存到該目錄中。
(3)客戶端Client
主要是上傳下載資料的伺服器,也就是我們自己的專案所部署在的伺服器。每個客戶端伺服器都需要安裝Nginx
Tracker相當於FastDFS的大腦,不論是上傳還是下載都是通過tracker來分配資源;客戶端一般可以使用ngnix等靜態伺服器來呼叫或者做一部分的快取;儲存伺服器內部分為卷(或者叫做組),卷於卷之間是平行的關係,可以根據資源的使用情況隨時增加,卷內伺服器檔案相互同步備份,以達到容災的目的。
(4)FastDFS的儲存策略
為了支援大容量,儲存節點(伺服器)採用了分卷(或分組)的組織方式。儲存系統由一個或多個卷組成,卷與卷之間的檔案是相互獨立的,所有卷的檔案容量累加就是整個儲存系統中的檔案容量。一個卷可以由一臺或多臺儲存伺服器組成,一個卷下的儲存伺服器中的檔案都是相同的,卷中的多臺儲存伺服器起到了冗餘備份和負載均衡的作用。
在卷中增加伺服器時,同步已有的檔案由系統自動完成,同步完成後,系統自動將新增伺服器切換到線上提供服務。當儲存空間不足或即將耗盡時,可以動態新增捲。只需要增加一臺或多臺伺服器,並將它們配置為一個新的卷,這樣就擴大了儲存系統的容量。
(5)FastDFS的上傳過程
FastDFS向使用者提供基本檔案訪問介面,比如upload、download、append、delete等,以客戶端庫的方式提供給使用者使用。
我們知道Storage Server會定期的向Tracker Server傳送自己的儲存資訊。當Tracker Server Cluster中的Tracker Server不止一個時,各個Tracker之間的關係是對等的,所以客戶端上傳時可以選擇任意一個Tracker。
當Tracker收到客戶端上傳檔案的請求時,會為該檔案分配一個可以儲存檔案的group,當選定了group後就要決定給客戶端分配group中的哪一個storage server。當分配好storage server後,客戶端向storage傳送寫檔案請求,storage將會為檔案分配一個資料儲存目錄。然後為檔案分配一個fileid,最後根據以上的資訊生成檔名儲存檔案。檔名的格式如下:
(6)FastDFS的檔案同步
寫檔案時,客戶端將檔案寫至group內一個storage server即認為寫檔案成功,storage server寫完檔案後,會由後臺執行緒將檔案同步至同group內其他的storage server。
每個storage寫檔案後,同時會寫一份binlog,binlog裡不包含檔案資料,只包含檔名等元資訊,這份binlog用於後臺同步,storage會記錄向group內其他storage同步的進度,以便重啟後能接上次的進度繼續同步;進度以時間戳的方式進行記錄,所以最好能保證叢集內所有server的時鐘保持同步。
storage的同步進度會作為後設資料的一部分彙報到tracker上,tracke在選擇讀storage的時候會以同步進度作為參考。
(7)FastDFS的檔案下載
客戶端uploadfile成功後,會拿到一個storage生成的檔名,接下來客戶端根據這個檔名即可訪問到該檔案。
跟upload file一樣,在downloadfile時客戶端可以選擇任意tracker server。tracker傳送download請求給某個tracker,必須帶上檔名資訊,tracke從檔名中解析出檔案的group、大小、建立時間等資訊,然後為該請求選擇一個storage用來服務讀請求。
二:搭建FastDFS環境(單機版)
1:基本準備
(1):系統準備 ①:剛重置的騰訊雲 CentOS 7.6 系統 (2):檔案準備 ①:libfastcommon :是FastDFS檔案系統執行需要的公共 C 語言函式庫 ②:FastDFS :主體檔案需要安裝部署在Linux環境下 ③:fastdfs-client-java : java客戶端基本程式碼(需maven手動編譯) ④:fastdfs-nginx-module :擴充套件模組,整合Nginx裡實現負載均衡等功能 ⑤:Nginx :實現負載均衡及檔案的訪問是用到
(3):上傳準備的檔案,出fastdfs-client-java 其它全部上傳
切換到根目錄下上傳 個人喜好 cd /root
執行上傳命令:rz -y
(1):環境檢查是否有 gcc 、libevent 、libevent-devel
檢查命令:
yum list installed | grep gcc
yum list installed | grep libevent
yum list installed | grep libevent-devel
安裝命令,如果有新版則更新
yum install gcc libevent libevent-devel -y
2:安裝 libfastcommon 庫
libfastcommon 庫是 FastDFS 檔案系統執行需要的公共 C 語言函式庫;注意:v1.0.39和FastDFS5.11不相容
>>解壓
tar -zxvf libfastcommon-1.0.48.tar.gz
>>進入解壓後的目錄
cd libfastcommon-1.0.48/
>>編譯解壓的檔案 這裡需要gcc環境
./make.sh
>>安裝編譯後的檔案
./make.sh install
>>完成
3:安裝 FastDFS 主體檔案
FastDFS沒有Windows版本,不能在Windows下使用。FastDFS需要安裝部署在Linux環境下
>>解壓
tar -zxvf fastdfs-6.07.tar.gz
>>進入解壓後的目錄
cd fastdfs-6.07/
>>編譯解壓的檔案 和 安裝編譯的檔案
./make.sh && ./make.sh install
>>檢查是否安裝了 (安裝後命令會存在/usr/bin)
ls /usr/bin | grep fdfs
(1):檢視 FastDFS 配置檔案
安裝FastDFS後配置檔案存放在 /etc/fdfs 下;注:另外注意需要把之前解壓的fastdfs-6.0.7/conf目錄下的兩個檔案拷貝到安裝後產生的/etc/fdfs/目錄下 ,否則後續會有很多奇怪問題不好解決 http.conf 和 mime.types
cp /root/fastdfs-6.07/conf/http.conf /etc/fdfs
cp /root/fastdfs-6.07/conf/mime.types /etc/fdfs
因為這些檔案字尾都是 .sample 示例的,所有我們把 .sample字尾都去除
mv /etc/fdfs/client.conf.sample client.conf
mv /etc/fdfs/tracker.conf.sample tracker.conf
mv /etc/fdfs/storage.conf.sample storage.conf
mv /etc/fdfs/storage_ids.conf.sample storage_ids.conf
4:FastDFS的配置 /etc/fdfs/xx.conf
要想執行我們的FastDFS服務,我們得配置我們必要的資訊,啟動tracker服務則需要配置tracker.conf,啟動storage服務也需要配置對應檔案
(1):負載均衡 tracker.conf 配置檔案的配置修改
如果不方便使用vim更改的話,可以使用 rz -y 上傳 和 sz file名稱 下載 到本地編輯
配置 tracker 儲存資料的目錄(自定義配置後期tracker產生的資料和日誌儲存的地方)
配置:base_path = /opt/fastdfs/tracker 注:設定的路徑我們必須要手動建立
# 配置tracker.conf 檔案是否生效 false生效 true遮蔽 disabled = false # 程式的監聽地址,如果不設定則監聽所有地址(0.0.0.0) bind_addr = # tracker監聽的埠 port = 22122 # 連線超時時間(秒)。 # 預設值為30。 # 注意:在內網(LAN)中,2秒就足夠了。 connect_timeout = 5 # 傳送和接收的網路超時時間(秒)。 # 預設值為30 # tracker server的網路超時,單位為秒。傳送或接收資料時,如果在超時時間後還不能傳送 # 或接收資料,則本次網路通訊失敗。 network_timeout = 60 # ------------------------------------------------------ # base_path 目錄地址(根目錄必須存在,子目錄會自動建立) # 附目錄說明: # tracker server目錄及檔案結構: # ${base_path} # |__data # | |__storage_groups.dat:儲存分組資訊 # | |__storage_servers.dat:儲存伺服器列表 # |__logs # |__trackerd.log:tracker server日誌檔案 # 資料檔案storage_groups.dat和storage_servers.dat中的記錄之間以換行符(\n)分隔,欄位之間以西文逗號(,)分隔。 # storage_groups.dat中的欄位依次為: # 1. group_name:組名 # 2. storage_port:storage server埠號 # # storage_servers.dat中記錄storage server相關資訊,欄位依次為: # 1. group_name:所屬組名 # 2. ip_addr:ip地址 # 3. status:狀態 # 4. sync_src_ip_addr:向該storage server同步已有資料檔案的源伺服器 # 5. sync_until_timestamp:同步已有資料檔案的截至時間(UNIX時間戳) # 6. stat.total_upload_count:上傳檔案次數 # 7. stat.success_upload_count:成功上傳檔案次數 # 8. stat.total_set_meta_count:更改meta data次數 # 9. stat.success_set_meta_count:成功更改meta data次數 # 10. stat.total_delete_count:刪除檔案次數 # 11. stat.success_delete_count:成功刪除檔案次數 # 12. stat.total_download_count:下載檔案次數 # 13. stat.success_download_count:成功下載檔案次數 # 14. stat.total_get_meta_count:獲取meta data次數 # 15. stat.success_get_meta_count:成功獲取meta data次數 # 16. stat.last_source_update:最近一次源頭更新時間(更新操作來自客戶端) # 17. stat.last_sync_update:最近一次同步更新時間(更新操作來自其他storage server的同步) base_path = /home/yuqing/fastdfs # 此伺服器支援的最大併發連線數。 # 預設值為256 max_connections = 1024 # 接受執行緒數。 # 預設值為1,推薦使用。 # 從V4.07開始 # 該引數決定接收客戶端連線的執行緒數,預設值為1,適當放大該引數可改善Storage處理連線的能力,改 # 成2[線上環境cpu為32核心可支援足夠多的執行緒數]。 accept_threads = 1 # 工作執行緒數。 # 處理網路IO的工作執行緒數。 # 預設值為4。 # 從V2.00開始 # 工作執行緒用來處理網路IO,預設值為4,該引數影響Stroage可以同時處理的連線數 work_threads = 4 # 最小網路緩衝區大小。 # 預設值8KB # 接收/傳送資料的buff大小,必須大於8KB min_buff_size = 8KB # 最大網路緩衝區大小。 # 預設值128KB # 接收/傳送資料的buff大小必須小於128KB max_buff_size = 128KB # 在儲存檔案時選擇group的策略。 # 0:輪詢。 # 1:指定組。 # 2:負載均衡,選擇上傳檔案的最大可用空間組 store_lookup = 2 # 上傳檔案到哪組。 # 當 store_lookup設定為1時,必須將 store_group設定為指定上傳的組名 store_group = group2 # 上傳檔案到哪臺儲存伺服器。 # 0:迴圈(預設)。 # 1:第一臺按IP地址排序的伺服器。 # 2:根據優先順序排序,第一個(最小)。 # 注意:如果 use_trunk_file設定為 true,則必須將 set store_server設定為1或2 store_server = 0 # 選擇檔案上傳到storage中的哪個(目錄/掛載點),storage可以有多個存放檔案的base # path 0:輪訓策略 2:負載均衡,選擇空閒空間最大的 store_path = 0 # 選擇那個storage作為主下載伺服器, # 0:輪訓策略 1:主上傳storage作為主下載伺服器 download_server = 0 # 系統預留空間,當一個group中的任何storage的剩餘空間小於定義的值,整個group就不能上傳檔案了 reserved_storage_space = 20% # 設定日誌級別 ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level = info # 程式以那個使用者/使用者組執行,不指定預設是當前使用者 run_by_group= run_by_user = # 允許那些機器連線tracker預設是所有機器 allow_hosts = * # 定時將日誌緩衝區同步到磁碟。 # 預設值為10秒 sync_log_buff_interval = 1 # 檢測 storage server 存活的時間隔,單位為秒。 # storage server定期向 tracker server 發心跳,如果tracker server在一個check_active_interval # 內還沒有收到storage server的一次心跳,那就認為該storage server已經下線。所以本引數值必須大於 # storage server配置的心跳時間間隔。通常配置為storage server心跳時間間隔的2倍或3倍。 check_active_interval = 120 # 執行緒棧的大小。FastDFS server端採用了執行緒方式。更正一下, # tracker server執行緒棧不應小於64KB,不是512KB。 thread_stack_size = 256KB # 儲存伺服器IP地址更改時自動調整。 # 預設值為true # storage的ip改變後服務端是否自動調整,storage程式重啟時才自動調整 storage_ip_changed_auto_adjust = true # 儲存同步檔案最大延遲秒數。 # 預設值為86400秒(一天)。 # 從V2.00開始 storage_sync_file_max_delay = 86400 # 檔案同步最大儲存時間。 # 預設值為300秒。 # 從V2.00開始 # 就是儲存伺服器同步一個檔案需要消耗的最大時間,單位為300s,即5分鐘。 storage_sync_file_max_time = 300 # 是否使用小檔案合併儲存特性 [false代表關閉] use_trunk_file = false # 最小插槽大小,應<=4KB。 # 預設值為256位元組。 # 從V3.00開始 # trunk file分配的最小位元組數。比如檔案只有16個位元組,系統也會分配 slot_min_size個位元組。 slot_min_size = 256 # 最大插槽大小,應>插槽最小大小。 # 當上傳檔案大小<=此值時,將上傳檔案儲存到主幹檔案。 # 預設值為16MB。 # 從V3.00開始 # 只有檔案大小<=這個引數值的檔案,才會合併儲存。 # 如果一個檔案的大小大於這個引數值,將直接儲存到一個檔案中(即不採用合併儲存方式) slot_max_size = 1MB # 對齊大小越大,磁碟碎片的可能性越小,但浪費的空間也更多。 trunk_alloc_alignment_size = 256 # 是否合併中繼檔案的連續可用空間 # since V6.05 trunk_free_space_merge = true # files 刪除/回收未使用的中繼檔案 # since V6.05 delete_unused_trunk_files = false # trunk file 大小 # since V3.00 trunk_file_size = 64MB # 是否提前建立 trunk file # since V3.06 trunk_create_file_advance = false # 提前建立trunk file的起始時間點(基準時間),02:00表示第一次建立的時間點是凌晨2點 trunk_create_file_time_base = 02:00 # 建立 trunk file 時間間隔, 86400 即隔一天 trunk_create_file_interval = 86400 # 提前建立trunk file時,需要達到的空閒trunk大小 # 比如本引數為20G,而當前空閒trunk為4GB,那麼只需要建立16GB的trunk file即可。 trunk_create_file_space_threshold = 20G # trunk初始化時,是否檢查可用空間是否被佔用 trunk_init_check_occupying = false # 是否無條件從trunk binlog中載入trunk可用空間資訊 # FastDFS預設是從快照檔案storage_trunk.dat中載入trunk可用空間, # 該檔案的第一行記錄的是trunk binlog的offset,然後從binlog的offset開始載入 trunk_init_reload_from_binlog = false # 壓縮 trunk binlog 檔案的最小間隔 trunk_compress_binlog_min_interval = 86400 # 壓縮 trunk binlog 檔案的間隔時間 (預設1天) trunk_compress_binlog_interval = 86400 # 壓縮 trunk binlog 檔案的時間點 trunk_compress_binlog_time_base = 03:00 # trunk binlog 檔案最大備份數 trunk_binlog_max_backups = 7 # 是否使用server ID作為storage server標識 use_storage_id = false # 指定儲存ID檔名,可以使用相對路徑或絕對路徑。 # 只有當use_storage_id設定為true時,該引數才有效。 storage_ids_filename = storage_ids.conf # 檔名中儲存伺服器的#id型別,值為: ## IP:儲存伺服器的IP地址。 ## id:儲存伺服器的伺服器id。 # 僅當use_storage_id設定為true時,此引數才有效。 # 預設值為ip。 # since V4.03 id_type_in_filename = id # 儲存從檔案是否使用符號連結 store_slave_file_use_link = false # 是否定期輪轉error log,目前僅支援一天輪轉一次 rotate_error_log = false # error log定期輪轉的時間點,只有當rotate_error_log設定為true時有效 error_log_rotate_time = 00:00 # 是否壓縮舊的錯誤日誌 compress_old_error_log = false # 壓縮幾天前的錯誤日誌 (compress_old_error_log = false本引數不生效) compress_error_log_days_before = 7 # 當日志檔案超過此大小時輪換錯誤日誌。 # 設定為0表示不按檔案大小輪轉,否則當error log達到該大小,就會輪轉到新檔案中 rotate_error_log_size = 0 # 日誌檔案保留幾天(0代表永久保留) log_file_keep_days = 0 # 是否使用連線池 use_connection_pool = true # 連線空閒時長,超過則連線被關閉 (單位秒) connection_pool_max_idle_time = 3600 # 此跟蹤器伺服器上的HTTP埠 http.server_port = 8080 # 檢查儲存HTTP伺服器活動間隔秒數。 # <=0表示從不檢查。 # 預設值為30 http.check_alive_interval = 30 # 檢查儲存HTTP伺服器活動型別,值為: # TCP:僅使用HTTP埠連線到儲存伺服器。 # 不請求,不獲取響應。 # http:儲存檢查活動url必須返回http狀態200。 # 預設值為tcp http.check_alive_type = tcp # 檢查儲存HTTP伺服器活動uri/url。 # 注意:Storage Embedded HTTP伺服器支援uri:/status.html http.check_alive_uri = /status.html
(2):檔案儲存伺服器 storage.conf 配置檔案的配置修改
配置 storage.conf 是指定後期執行產生的資料和真實的檔案儲存位置,注設定的路徑我們必須手動建立
配置storage儲存資料的目錄:base_path = /opt/fastdfs/storage
配置真正存放檔案的目錄: store_path0=/opt/fastdfs/storage/files
配置當前儲存節點的跟蹤器地址(就是tracker):tracker_server=119.29.68.209:22122
# 配置storage.conf 檔案是否生效 false生效 true遮蔽 disabled = false # 該儲存伺服器所屬的組名。 # 註釋或刪除此專案以從跟蹤器伺服器獲取, # 在這種情況下,tracker.conf中的use_storage_id必須設定為true。 # 和storage_ids.conf必須正確配置。 group_name = group1 # 程式的監聽地址,如果不設定則監聽所有地址(0.0.0.0) bind_addr = # bind_addr通常是針對server的。當指定bind_addr時,本引數才有效。 # 本storage server作為client連線其他伺服器(如tracker server、 # 其他storage server),是否繫結bind_addr。 client_bind = true # storage 預設埠 port = 23000 # 連線超時時間(秒)。 # 預設值為30。 # 注意:在內網(LAN)中,2秒就足夠了。 connect_timeout = 5 # 傳送和接收的網路超時時間(秒)。 # 預設值為30 network_timeout = 60 # 心跳間隔(秒)。 # 儲存伺服器定期向Tracker伺服器傳送心跳。 # 預設值為30 heart_beat_interval = 30 # 磁碟使用情況報告間隔(秒)。 # 儲存伺服器定期向Tracker伺服器傳送磁碟使用情況報告。 # 預設值為300 stat_report_interval = 60 # 資料儲存目錄地址 base_path = /home/yuqing/fastdfs # 最大連線數 max_connections = 1024 # 設定佇列結點的buffer大小。工作佇列消耗的記憶體大小 = buff_size * max_connections # 設定得大一些,系統整體效能會有所提升。 buff_size = 256KB # 接收資料的執行緒數 accept_threads = 1 # 工作執行緒數,一般為cpu個數,當然CPU核數太多的話可以稍小一點。如我們是12CPU,這裡設定為8 work_threads = 4 # 磁碟IO讀寫是否分離。磁碟讀/寫分離為false則為混合讀寫, # 如果為true則為分離讀寫的。預設值為V2.00以後為true。 disk_rw_separated = true # 針對單個儲存路徑的讀執行緒數,預設值為1。 # 讀寫分離時: # 系統中的讀執行緒數 = disk_reader_threads * store_path_count # 讀寫混合時: # 系統中的讀寫執行緒數 = (disk_reader_threads + disk_writer_threads) * store_path_count disk_reader_threads = 1 # 針對單個儲存路徑的寫執行緒數,預設值為1。 # 讀寫分離時: # 系統中的寫執行緒數 = disk_writer_threads * store_path_count # 讀寫混合時: # 系統中的讀寫執行緒數 = (disk_reader_threads + disk_writer_threads) * store_path_count disk_writer_threads = 1 # 同步檔案時,如果從binlog中沒有讀到要同步的檔案,休眠N毫秒後重新讀取。0表示不休眠,立即再次嘗試讀取。 # 出於CPU消耗考慮,不建議設定為0。如何希望同步儘可能快一些,可以將本引數設定得小一些,比如設定為10ms sync_wait_msec = 50 # 同步上一個檔案後,再同步下一個檔案的時間間隔,單位為毫秒,0表示不休眠,直接同步下一個檔案。 sync_interval = 0 # 下面二個一起解釋。允許系統同步的時間段 (預設是全天) 。一般用於避免高峰同步產生一些問題而設定 sync_start_time = 00:00 sync_end_time = 23:59 # 同步 N 個檔案後就寫入標記檔案 write_mark_file_freq = 500 # 硬碟恢復執行緒數 disk_recovery_threads = 3 # storage在儲存檔案時支援多路徑,預設只設定一個 store_path_count = 1 # store_path(0~⚮),根據0配置儲存檔案的儲存路徑。 # 如果store_path0不存在,則取值為base_path(不推薦)。 # 路徑必須存在 store_path0 = /home/yuqing/fastdfs #store_path1 = /home/yuqing/fastdfs2 # subdir_count * subdir_count個目錄會在store_path下建立,採用兩級儲存 subdir_count_per_path = 256 # 設定tracker_server 伺服器地址 多個代表多個Tracker叢集 tracker_server = 192.168.209.121:22122 tracker_server = 192.168.209.122:22122 # 日誌級別 ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level = info # 程式以那個使用者/使用者組執行,不指定預設是當前使用者 run_by_group = run_by_user = # 允許那些機器連線tracker預設是所有機器 allow_hosts = * # 檔案分發到資料路徑的方式。 # 0: 輪流存放,在一個目錄下儲存設定的檔案數後 #(引數file_distribute_rotate_count中設定檔案數),使用下一個目錄進行儲存。 # 1: 隨機儲存,根據檔名對應的hash code來分散儲存。 file_distribute_path_mode = 0 # 當上面的引數file_distribute_path_mode配置為0(輪流存放方式)時,本引數有效。 # 當一個目錄下的檔案存放的檔案數達到本引數值時,後續上傳的檔案儲存到下一個目錄中。 file_distribute_rotate_count = 100 # 當寫入大檔案時,每寫入N個位元組,呼叫一次系統函式fsync將內容強行同步到硬碟。0表示從不呼叫fsync fsync_after_written_bytes = 0 # 同步或重新整理日誌資訊到硬碟的時間間隔,單位為秒 # 注意:storage server 的日誌資訊不是時時寫硬碟的,而是先寫記憶體。 sync_log_buff_interval = 1 # 同步binglog(更新操作日誌)到硬碟的時間間隔,單位為秒 # 本引數會影響新上傳檔案同步延遲時間 sync_binlog_buff_interval = 1 # 把storage的stat檔案同步到磁碟的時間間隔,單位為秒。 # 注:如果stat檔案內容沒有變化,不會進行同步 sync_stat_file_interval = 300 # 執行緒棧大小,執行緒棧越大,一個執行緒佔用的系統資源就越多。 thread_stack_size = 512KB # 本storage server作為源伺服器,上傳檔案的優先順序,可以為負數。值越小, # 優先順序越高。這裡就和 tracker.conf 中store_server= 2時的配置相對應了 upload_priority = 10 # 網路卡別名,用ifconfig -a可以看到很多本機的網路卡別名,類似eth0,eth0:0等等。 # 多個網路卡別名使用逗號分割,預設為空,讓系統自動選擇。 if_alias_prefix = # 是否檢測上傳檔案已經存在。如果已經存在,則不存在檔案內容,建立一個符號連結以節省磁碟空間。 # 這個應用要配合FastDHT 使用,所以開啟前要先安裝FastDHT # 1或yes 是檢測,0或no 是不檢測 check_file_duplicate = 0 # 檔案去重時,檔案內容的簽名方式: ## hash:4個hash code ## md5:MD5 file_signature_method = hash #當check_file_duplicate設定為1時,此值必須設定 key_namespace = FastDFS # FastDHT建立連線的方式 0:短連線 1:長連線 keep_alive = 0 # 是否將檔案操作記錄到access log use_access_log = false # 是否定期輪轉access log,目前僅支援一天輪轉一次 rotate_access_log = false # access log定期輪轉的時間點,只有當rotate_access_log設定為true時有效 access_log_rotate_time = 00:00 # 是否壓縮舊的訪問日誌 compress_old_access_log = false # 壓縮幾天前的訪問日期 compress_access_log_days_before = 7 # 是否每天輪轉錯誤日誌 rotate_error_log = false # 錯誤日誌輪轉時間 error_log_rotate_time = 00:00 # 壓縮舊的錯誤日誌 compress_old_error_log = false # 壓給它幾天前的錯誤日誌 compress_error_log_days_before = 7 # access log按檔案大小輪轉 # 設定為0表示不按檔案大小輪轉,否則當access log達到該大小,就會輪轉到新檔案中 rotate_access_log_size = 0 # error log按檔案大小輪轉 # 設定為0表示不按檔案大小輪轉,否則當error log達到該大小,就會輪轉到新檔案中 rotate_error_log_size = 0 # 保留日誌檔案的日期0表示不刪除舊的日誌檔案 log_file_keep_days = 0 # 檔案同步的時候,是否忽略無效的binlog記錄 file_sync_skip_invalid_record = false # 是否使用連線池 use_connection_pool = true # 連線的空閒時間超過這個時間將被關閉,單位:秒 connection_pool_max_idle_time = 3600 # 是否使用gzip壓縮二進位制日誌檔案 compress_binlog = true # 壓給它二進位制日誌時間點 compress_binlog_time = 01:30 # 是否檢查儲存路徑的標記以防止混淆,建議開啟,如果兩個服務使用 # 一個相同的儲存路徑,此引數要設定為 false check_store_path_mark = true # 服務域名, 如果為空則表示使用 IP 地址 http.domain_name = # http 埠 http.server_port = 8888
(3):建立我們之前在配置裡指定的一些路徑
必須建立,否則無法啟動
mkdir -p /opt/fastdfs/tracker
mkdir -p /opt/fastdfs/storage
mkdir -p /opt/fastdfs/storage/files
5:啟動FastDFS服務
我們修改好配置後,並且在配置檔案配置的檔案路徑也被我們手動建立後就可以來啟動服務了
# 啟動 Tracker 追蹤器服務 fdfs_trackerd /etc/fdfs/tracker.conf # 啟動 Storage 儲存伺服器服務 fdfs_storaged /etc/fdfs/storage.conf # 重啟 fdfs_trackerd /etc/fdfs/tracker.conf restart fdfs_storaged /etc/fdfs/storage.conf restart # 關閉 fdfs_trackerd /etc/fdfs/tracker.conf stop fdfs_storaged /etc/fdfs/storage.conf stop
(1):查詢tracker檔案下是否被自動建立了data 和 log 檔案
命令:ls /opt/fastdfs/tracker/
(2):查詢storage檔案下是否自動建立了data 和 log 和files具體檔案路徑
6:FastDFS測試上傳、刪除
我們完成了上面的配置後並且也可以執行服務後,我們就可以來測試我們的FastDFS是否存在問題了,在測試前我們需要配置一個 /etc/fdfs/client.conf 的檔案
配置client儲存資料的目錄:base_path = /opt/fastdfs/client 注:別忘了把資料夾建立出來
配置當前儲存節點的跟蹤器地址(就是tracker):tracker_server=119.29.68.209:22122
# 連線的超時時間 connect_timeout = 5 # 網路超時(秒),預設值 60s network_timeout = 60 # 儲存日誌檔案的基本路徑 base_path = /home/yuqing/fastdfs # tracker server的列表 多個tracker就設定多個 tracker_server = 192.168.0.196:22122 tracker_server = 192.168.0.197:22122 # 日誌級別 ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level = info # 是否使用連線池 use_connection_pool = false # 連線的空閒時間超過這個時間將被關閉,單位:秒 connection_pool_max_idle_time = 3600 # 是否載入來自跟蹤伺服器的FastDFS引數,預設值為false。這裡可以設定為true。 load_fdfs_parameters_from_tracker = false # 是否使用storage id替換ip作為storage server標識,預設為false use_storage_id = false # 在檔案中設定組名、server ID和對應的IP地址 storage_ids_filename = storage_ids.conf # 埠 http.tracker_server_port = 80
我們要使用測試則需要使用到 fdfs_test 命令來完成測試
命令:fdfs_test /etc/fdfs/client.conf upload 上傳的檔名稱
查詢檔案 這裡儲存到../00/00裡
測試刪除
fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/dx1E0WArYHCALYE2AAAADEQKaqU633_big.txt
三:分散式檔案系統之FastDFS的HTTP訪問
在檔案上傳的時候,上傳成功的資訊中有提示我們可以通過某個路徑去訪問上傳的檔案,但是我們直接訪問這個路徑,卻不可以,那麼已經上傳到FastDFS檔案系統中的檔案,我們如何在瀏覽器中訪問呢?FastDFS提供了一個Nginx擴充套件模組,利用該模組,我們可以通過Nginx訪問已經上傳到FastDFS上的檔案
1:安裝Nginx並新增fastDFS模組
安裝Nginx環境檢查:
gcc編譯器是否安裝
檢查是否安裝:yum list installed | grep gcc
執行安裝:yum install gcc -y
openssl庫是否安裝
檢查是否安裝:yum list installed | grep openssl
執行安裝:yum install openssl openssl-devel -y
pcre庫是否安裝
檢查是否安裝:yum list installed | grep pcre
執行安裝:yum install pcre pcre-devel -y
zlib庫是否安裝
檢查是否安裝:yum list installed | grep zlib
執行安裝:yum install zlib zlib-devel -y
全安裝:
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
>>解壓:fastdfs-nginx-module-1.22.tar.gz
tar -zxvf fastdfs-nginx-module-1.22.tar.gz
>>解壓:nginx-1.19.6.tar.gz
tar -zxvf nginx-1.19.6.tar.gz
>>進入:nginx-1.19.6
cd nginx-1.19.6/
>>安裝前配置
./configure --prefix=/usr/local/nginx_fdfs --add-module=/root/fastdfs-nginx-module-1.22/src
--prefix:指定準備安裝到哪 --add-module:指定整合的fdfs模組
>>編譯 && 安裝
make && make install
2:配置Nginx訪問設定
(1):拷貝模組檔案到 /etc/fdfs
我們需要先把擴充套件模組 fastdfs-nginx-module-master/src 裡的 mod_fastdfs.conf 檔案拷貝到 /etc/fdfs/ 目錄下,這樣才可以正常啟動Nginx
命令:cp /root/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs
(2):修改拷貝過來的 /etc/fdfs/mod_fastdfs.conf 檔案
# 配置儲存執行產生的日誌資料等等 檔案路徑必須存在 base_path=/opt/fastdfs/nginx_mod # 設定tracker服務地址 tracker_server=119.29.68.209:22122 # 設定檔案url中是否有group名 url_have_group_name = true # 檔案資料儲存路徑 store_path0=/opt/fastdfs/storage/files
# 連線超時時間(秒)。 # 預設值為30s connect_timeout=2 # 網路接收和傳送超時(秒)。 # 預設值為30s network_timeout=30 # 日誌儲存路徑 base_path=/tmp # 從跟蹤器伺服器載入FastDFS引數。 # 從V1.12開始。 # 預設值為False load_fdfs_parameters_from_tracker=true # 儲存同步檔案最大延遲秒數。 # 與tracker.conf相同。 # 僅當load_fdfs_Parameters_from_tracker為FALSE時有效。 # 從V1.12開始。 # 預設值為86400秒(一天) storage_sync_file_max_delay = 86400 # 如果使用儲存ID而不是IP地址。 # 與tracker.conf相同。 # 僅當load_fdfs_Parameters_from_tracker為FALSE時有效。 # 預設值為False。 # 從V1.13開始 use_storage_id = false # 指定儲存ID檔名,可以使用相對路徑或絕對路徑。 # 與tracker.conf相同。 # 僅當load_fdfs_Parameters_from_tracker為FALSE時有效。 # 從V1.13開始 storage_ids_filename = storage_ids.conf # tracker 服務列表 tracker_server=tracker:22122 # storage server埠號 storage_server_port=23000 # 本地儲存伺服器的組名 group_name=group1 # 檔案url中是否有group名 url_have_group_name = false # 儲存路徑個數,需要和store_path個數匹配 store_path_count=1 # store_path#,以0為基數,如果store_path0不存在,則其值為base_path。 # 路徑必須存在。 # 必須與storage.conf相同 store_path0=/home/yuqing/fastdfs #store_path1=/home/yuqing/fastdfs1 # 日誌級別: ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level=info # 設定日誌檔名,如/usr/local/apache2/logs/mod_fast dfs.log。 # Empty表示輸出到stderr(apache和nginx error_log檔案) log_filename= # 本地檔案系統中不存在檔案時的響應方式。 ## proxy:從其他儲存伺服器獲取內容,然後傳送給客戶端。 ## redirect:重定向到原儲存伺服器(HTTP Header為Location) response_mode=proxy # 網路卡別名字首,如Linux中的eth,可以通過ifconfig-a檢視。 # 多個別名以逗號分隔。空值表示按作業系統型別自動設定。 # 該引數用於獲取本地主機的所有IP地址。 # 預設值為空 if_alias_prefix= # IF支援FLV。 # 預設值為False。 # 從v1.15開始 flv_support = true # FLV副檔名。 # 預設值為flv。 # 從v1.15開始 flv_extension = flv # 設定群數。 # 設定為無零以支援此儲存伺服器上的多組。 # 僅針對單個組設定為0。 # 將設定部分分組為[group1]、[group2]、...、[groupn]。 # 預設值為0。 # 從v1.14開始 group_count = 0 # group settings for group #1 # since v1.14 # when support multi-group on this storage server, uncomment following section [group1] # 組名稱# group_name=group1 # 組埠 storage_server_port=23000 # 儲存路徑個數,需要和store_path個數匹配 store_path_count=2 store_path0=/home/yuqing/fastdfs store_path1=/home/yuqing/fastdfs1 # group settings for group #2 # since v1.14 # when support multi-group, uncomment following section as neccessary [group2] group_name=group2 storage_server_port=23000 store_path_count=1 store_path0=/home/yuqing/fastdfs
(3):修改Nginx配置檔案
完成上面,我們就得開始配置我們的Nginx配置了,這個配置按照之前的安裝是在 /usr/local/nginx_fdfs/conf/nginx.conf
命令:vim /usr/local/nginx_fdfs/conf/nginx.conf
#攔截請求路徑中包含 /group[1-9]/M[0-9][0-9] 的請求,用 fastdfs的Nginx 模組進行轉發 location ~ /group[1-9]/M[0-9][0-9] { ngx_fastdfs_module; } #注:ngx_fastdfs_module:這個指令不是Nginx本身提供的,是擴充套件模組提供的,根據這個指令找 # 到FastDFS提供的Nginx模組配置檔案,然後找到Tracker,最終找到Stroager
(4):執行Nginx服務
切換到Nginx sbin目錄下:cd /usr/local/nginx_fdfs/sbin/ 執行nginx目錄:./nginx 查詢是否啟動:ps -ef | grep nginx
(5):測試,上傳一個檔案並在本地瀏覽器訪問
我們隨便上傳一個檔案後,上傳成功後會給我們返回一個帶http的具體連結,我們直接在本地瀏覽器就可以訪問(開啟80埠)
# 上傳檔案測試 fdfs_test /etc/fdfs/client.conf upload abc.txt # 返回獲取的http地址準備本地訪問 http://119.29.68.209/group1/M00/00/00/dx1E0WArksiARSeLAAAADEQKaqU125.txt
四:FastDFS在Java專案中開發
在真實開發中我們肯定不會使用如 fdfs_test 命令來上傳檔案,通常使用java程式碼來編寫指定的上傳程式碼,但是我們想使用得要一個jar包,就是我們最初下載的 fastdfs-client-java-1.28.tar.gz ,由於是原始碼,我們使用 maven 的 mvn 命令編譯一下即可
1:編譯原始碼來生成jar包
安裝過後就會出現到你的maven倉庫了..\org\csource\fastdfs-client-java
2:程式碼編寫
我們以建立一個簡單的maven專案為例
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>demo_001</artifactId> <version>1.0-SNAPSHOT</version> <!--maven編譯版本--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <!--匯入座標--> <dependencies> <!--匯入FastDFS客戶端jar包--> <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.28-SNAPSHOT</version> </dependency> </dependencies> </project>
完成了 pom.xml 檔案的編寫,我們就去resource下建立一個 fastdfs.conf 的配置檔案指定 tracker地址
tracker_server = 119.29.68.209:22122
public class Test { public static void main(String[] args) { //上傳 //upload(); //下載 //download(); //刪除 delete(); } //上傳方法 //注意22122 23000埠的開放 public static void upload() { try { //載入配置檔案 ClientGlobal.init("fastdfs.conf"); //建立 TrackerClient跟蹤器客戶端 TrackerClient trackerClient = new TrackerClient(); //通過 TrackerClient跟蹤器客戶端 獲取 TrackerServer跟蹤器服務端 TrackerServer trackerServer = trackerClient.getTrackerServer(); //通過 TrackerClient跟蹤器客戶端 獲取 StorageServer儲存伺服器服務端 StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer); //建立儲存伺服器客戶端 StorageClient storageClient = new StorageClient(trackerServer, storeStorage); //開始上傳 // 第一個引數檔案路徑,也可以是二進位制陣列 // 第二個引數是檔案型別 String[] strings = storageClient.upload_file("h:\\1.jpg", "jpg", null); for (String str : strings) { System.out.println(str); //列印: // group1 // M00/00/00/dx1E0WArsfeAWVTvAAEoDtcZimw368.jpg } //關閉資源 storageClient.close(); } catch (IOException | MyException e) { e.printStackTrace(); } } //下載 public static void download() { try { //載入配置檔案 ClientGlobal.init("fastdfs.conf"); //建立 TrackerClient跟蹤器客戶端 TrackerClient trackerClient = new TrackerClient(); //通過 TrackerClient跟蹤器客戶端 獲取 TrackerServer跟蹤器服務端 TrackerServer trackerServer = trackerClient.getTrackerServer(); //通過 TrackerClient跟蹤器客戶端 獲取 StorageServer儲存伺服器服務端 StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer); //建立儲存伺服器客戶端 StorageClient storageClient = new StorageClient(trackerServer, storeStorage); //開始下載 byte[] bytes = storageClient.download_file("group1", "M00/00/00/dx1E0WArsfeAWVTvAAEoDtcZimw368.jpg"); //寫出檔案 new FileOutputStream("H:\\downloadfile.jpg").write(bytes); //關閉資源 storageClient.close(); } catch (IOException | MyException e) { e.printStackTrace(); } } //刪除 public static void delete() { try { //載入配置檔案 ClientGlobal.init("fastdfs.conf"); //建立 TrackerClient跟蹤器客戶端 TrackerClient trackerClient = new TrackerClient(); //通過 TrackerClient跟蹤器客戶端 獲取 TrackerServer跟蹤器服務端 TrackerServer trackerServer = trackerClient.getTrackerServer(); //通過 TrackerClient跟蹤器客戶端 獲取 StorageServer儲存伺服器服務端 StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer); //建立儲存伺服器客戶端 StorageClient storageClient = new StorageClient(trackerServer, storeStorage); //開始刪除 int result = storageClient.delete_file("group1", "M00/00/00/dx1E0WArsfeAWVTvAAEoDtcZimw368.jpg"); System.out.println(result == 0 ? "刪除成功" : "刪除失敗"); //0成功,返回其它數字都是失敗 //關閉資源 storageClient.close(); } catch (IOException | MyException e) { e.printStackTrace(); } } }
.