FastDFS --- 分佈式文件系統

FastDFS

什麼是分佈式文件系統

  • 分佈式文件系統解決了海量文件存儲及傳輸訪問的瓶頸問題,對海量視頻的管理、對海量圖片的管理等。
  • 分佈式文件系統(Distributed File System)是指文件系統管理的物理存儲資源不必定直接鏈接在本地節點上,而是經過計算機網絡與節點相連。

爲何會有分佈文件系統

存在問題

  • 分佈式文件系統是面對互聯網的需求而產生,互聯網時代對海量數據如何存儲?
  • 靠簡單的增長硬盤的個數已經知足 不了咱們的要求,由於硬盤傳輸速度有限可是數據在急劇增加,
  • 另外咱們還要要作好數據備份、數據安全等。

解決辦法

  • 採用分佈式文件系統能夠將多個地點的文件系統經過網絡鏈接起來
  • 組成一個文件系統網絡,結點之間經過網絡進行通訊
  • 一臺文件系統的存儲和傳輸能力有限,咱們讓文件在多臺計算機上存儲,經過多臺計算共同傳輸

示例圖

好處

  • 一臺計算機的文件系統處理能力擴充到多臺計算機同時處理
  • 一臺計算機掛了,還有另外的副本計算機提供數據。
  • 每臺計算機能夠放在不一樣的地域,這樣用戶就能夠就近訪問,提升訪問速度

主流的分佈式文件系統

NFS(Network File System),即網絡文件系統

  • 在客戶端上映射NFS服務器的驅動器
  • 客戶端經過網絡訪問NFS服務器的硬盤徹底透明。

結構圖

GFS(Google File System)

  • GFS採用主從結構,一個GFS集羣由一個master和大量的chunkserver組成
  • master存儲了數據文件的元數據,一個文件被分紅了若干塊存儲在多個chunkserver中。
  • 用戶從master中獲取數據元信息,從chunkserver存儲數據

結構圖

HDFS(Hadoop Distributed File System)

  • Hadoop分佈式文件系統主要用於大數據
  • HDFS採用主從結構,一個HDFS集羣由一個名稱結點和若干數據結點組成
  • 名稱結點存儲數據的元信息,一個完整的數據文件分紅若干塊存儲在數據結點。
  • 客戶端從名稱結點獲取數據的元信息及數據分塊的信息,獲得信息客戶端便可從數據塊來存取數據。

結構圖

什麼是fastDFS

簡介

FastDFS是用c語言編寫的一款開源的分佈式文件系統,它是由淘寶資深架構師餘慶編寫並開源。前端

FastDFS專爲互聯 網量身定製,充分考慮了冗餘備份、負載均衡、線性擴容等機制,並注重高可用、高性能等指標java

使用FastDFS很容易搭建一套高性能的文件服務器集羣提供文件上傳、下載等服務linux

爲何要使用fastDFS

通用分佈式文件系統

  • NFS、GFS都是通用的分佈式文件系統
  • 通用的分佈式文件系統的優勢的是開發體驗好,可是系統複雜 性高、性能通常

專用分佈式文件系統

  • 專用的分佈式文件系統雖然開發體驗性差,可是系統複雜性低而且性能高。
  • fastDFS很是適合存儲圖片等那些小文件,fastDFS不對文件進行分塊,因此它就沒有分塊合併的開銷,fastDFS網絡通訊採用 socket,通訊速度很快

fastDFS工做原理

  • FastDFS架構包括 Tracker server和Storage server。
  • 客戶端請求Tracker server進行文件上傳、下載,經過Tracker server調度最終由Storage server完成文件上傳和下載。

結構圖

Tracker

做用
	Tracker Server做用是負載均衡和調度,
	經過Tracker server在文件上傳時能夠根據一些策略找到Storage server提供文件上傳服務。
	能夠將tracker稱爲追蹤服務器或調度服務器。
集羣
	FastDFS集羣中的Tracker server能夠有多臺
	Tracker server之間是相互平等關係同時提供服務.
	客戶端請求Tracker server採用輪詢方式,若是請求的tracker沒法提供服務則換另外一個tracker。

Storage

做用
	Storage Server做用是文件存儲,客戶端上傳的文件最終存儲在Storage服務器上
	
集羣
	 Storage集羣採用了分組存儲方式。storage集羣由一個或多個組構成,集羣存儲總容量爲集羣中全部組的存儲容量之和
	一個組由一臺或多臺存儲服務器組成,組內的Storage server之間是平等關係,
	不一樣組的Storage server之間不會相互通訊
	同組內的Storage server之間會相互鏈接進行文件同步,從而保證同組內每一個storage上的文件是徹底一致的
	一個組的存儲容量爲該組內的存儲服務器容量最小的那個
	採用分組存儲方式的好處
		靈活、可控性較強。好比上傳文件時,能夠由客戶端直接指定上傳到的組也能夠由tracker進行調度選擇。
		一個分組的存儲服務器訪問壓力較大時,能夠在該組增長存儲服務器來擴充服務能力(縱向 擴容)
		當系統容量不足時,能夠增長組來擴充存儲容量(橫向擴容)。

Storage狀態收集
	Storage server會鏈接集羣中全部的Tracker server,定時向他們報告本身的狀態,
	包括磁盤剩餘空間、文件同步 情況、文件上傳下載次數等統計信息。

FastDFS安裝與配置

  • FastDFS是 C 語言開發,建議在 linux 上運行
  • 安裝 FastDFS須要先將官網下載的源碼進行編譯,編譯依賴 gcc 環境,若是沒有 gcc 環境,須要先安裝gcc

1.須要安裝 gccnginx

yum install gcc-c++

2.安裝libevent(FastDFS依賴libevent庫)c++

yum -y install libevent

3.安裝libfastcommon (由 FastDFS 官方提供,包含了 FastDFS 運行所須要的一些基礎庫)spring

將libfastcommonV1.0.7.tar.gz拷貝至/usr/local/下
cd /usr/local/
tar -zxvf libfastcommonV1.0.7.tar.gz 
cd libfastcommon-1.0.7
./make.sh
./make.sh install

libfastcommon安裝好後會自動將庫文件拷貝至/usr/lib64下

4.安裝libeventapache

cd /usr/local/
tar -zxvf libevent-2.0.15-stable.tar.gz 
cd libevent-2.0.15-stable/
./configure
make && make install
ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib/libevent-2.0.so.5

4.安裝libeventjson

cd /usr/local/
tar -zxvf libevent-2.0.15-stable.tar.gz 
cd libevent-2.0.15-stable/
./configure
make && make install
ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib/libevent-2.0.so.5

5.tracker編譯安裝vim

將FastDFS_v5.05.tar.gz拷貝至/usr/local/下 
tar -zxvf FastDFS_v5.05.tar.gz 
cd FastDFS 
./make.sh 
./make.sh install

安裝成功將安裝目錄下的conf下的文件拷貝到/etc/fdfs/下
cp -ri conf/* /etc/fdfs
	
進入/etc/fdfs目錄
cd /etc/fdfs
	
修改tracker.conf 
vim tracker.conf
base_path=/home/fastdfs
http.server_port=80

建立目錄
	mkdir -p /home/fastdfs
			
啓動
	/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart

6.進入/etc/fdfs數組

cd /etc/fdfs
vi storage.conf 
group_name=group1 
base_path=/home/yuqing/FastDFS改成:base_path=/home/fastdfs 
store_path0=/home/fastdfs/fdfs_storage
#配置tracker服務器:IP若是有多個則配置多個tracker
tracker_server=192.168.1.88:22122   
http.server_port=80 

mkdir -p /home/fastdfs/fdfs_storage 
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart

查看是否啓動
ps aux|grep dfs

文件上傳流程

流程圖

文件信息

客戶端上傳文件後,存儲服務器將文件ID返回給客戶端,此文件ID用於之後訪問該文件的索引信息。
文件索引信息 包括:組名,虛擬磁盤路徑,數據兩級目錄,文件名

組名:
	文件上傳後所在的storage組名稱,在文件上傳成功後有storage服務器返回,須要客戶端自行保存。
	
虛擬磁盤路徑:
	storage配置的虛擬路徑,與磁盤選項store_path*對應。若是配置了store_path0則是M00, 若是配置了store_path1則是M01,以此類推。 
	
數據兩級目錄:
	storage服務器在每一個虛擬磁盤路徑下建立的兩級目錄,用於存儲數據文件
	
文件名:
	是由存儲服務器根據特定信息生成,文件名包含:源存儲服務器IP地址、文件創 建時間戳、文件大小、隨機數和文件拓展名等信息

經過客戶端上傳圖片

添加fastdfs依賴

<dependencies>
	<dependency>
		<groupId>org.csource.fastdfs</groupId>
		<artifactId>fastdfs</artifactId>
		<version>1.2</version>
	</dependency>
</dependencies>

在resources當中建立fdfs_client.conf配置文件

# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fastdfs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.1.88:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf

建立測試,上傳圖片

public static void main(String[] args) throws Exception {
        //1. 加載配置文件
        ClientGlobal.init("D:\\Java\\testcode\\fastDFSProject\\src\\main\\resources\\fdfs_client.conf");
        //2. 建立管理端對象
        TrackerClient trackerClient = new TrackerClient();
        //3. 經過管理端對象獲取鏈接
        TrackerServer connection = trackerClient.getConnection();
        //4. 建立存儲端對象
        StorageClient1 storageClient = new StorageClient1(connection, null);

        //建立文件屬性信息對象數組
        NameValuePair[] meta_list = new NameValuePair[3];
        meta_list[0] = new NameValuePair("fileName","idea");
        meta_list[1] = new NameValuePair("ExtName","jpg");
        meta_list[2] = new NameValuePair("zuozhe","gaowei");

        //5. 上傳文件
        String path = storageClient.upload_file1("E:\\idea.jpg", "jpg", meta_list);
        System.out.println("======" + path);
    }

搭建圖片服務虛擬主機

在Storage上安裝nginx

  • 在storage server上安裝nginx的目的是對外經過http訪問storage server 上的文件
  • 使用 nginx 的模塊 FastDFS-nginx-module 的做用是經過 http 方式訪問 storage 中的文件

安裝FastDFS-nginx-module_v1.16

將 FastDFS-nginx-module_v1.16.tar.gz上到usr/local下
cd /usr/local 
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
rm -rf fastdfs-nginx-module_v1.16.tar.gz
cd fastdfs-nginx-module/src
修改config文件將帶有/usr/local/的路徑改成/usr/
vi config
esc後保存並退出 :wq
	
將FastDFS-nginx-module/src下的mod_FastDFS.conf拷貝至/etc/fdfs/下 
cp mod_fastdfs.conf /etc/fdfs/

修改mod_fastdfs.conf
vim /etc/fdfs/mod_fastdfs.conf
base_path=/home/fastdfs
tracker_server=192.168.1.88:22122 
url_have_group_name=true 	
store_path0=/home/fastdfs/fdfs_storage 
esc後保存並退出 :wq
		
將libfdfsclient.so拷貝至/usr/lib下 
	cp /usr/lib64/libfdfsclient.so /usr/lib/
複製 FastDFS的部分配置文件到/etc/fdfs目錄,根據相對應的安裝狀況進入到相對應的路徑
	cd /usr/local/FastDFS/conf/
	cp http.conf mime.types /etc/fdfs/

nginx安裝

將nginx-1.8.1.tar.gz拷貝到/usr/local下

		cd /usr/local

		解壓nginx-1.8.1.tar.gz 
			tar -zxvf nginx-1.8.1.tar.gz

			rm -rf nginx-1.8.1.tar.gz

		安裝依賴包
			sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
		cd nginx-1.8.1/
		執行配置
			./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/usr/local/fastdfs-nginx-module/src
		make
		make install
		useradd -s /sbin/nologin -M nginx
		id nginx

		啓動
			nginx

		中止
			nginx -s stop 

		從新加載配置
			nginx -s reload

		查看是否啓動
			ps -ef|grep nginx

		修改配置文件,添加上
			vim  /opt/nginx/conf/nginx.conf


#監聽域名中帶有group的,交給FastDFS模塊處理
location ~/group([0-9])/ {
	ngx_fastdfs_module;
}

啓動

/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart 
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
nginx

富文本編輯器umedit上傳圖片到FastDFS

修改配置文件plugins/umedit/jsp/config.json接口地址

"imageActionName": "upload/uploadImage.do", /* 執行上傳圖片的action名稱 */
"imageFieldName": "upfile", /* 提交的圖片表單名稱 */
"imageMaxSize": 2048000, /* 上傳大小限制,單位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上傳圖片格式顯示 */
"imageCompressEnable": true, /* 是否壓縮圖片,默認是true */
"imageCompressBorder": 1600, /* 圖片壓縮最長邊限制 */
"imageInsertAlign": "none", /* 插入的圖片浮動方式 */
"imageUrlPrefix": "", /* 圖片訪問路徑前綴 */
"imagePathFormat": "", /* 上傳保存路徑,能夠自定義保存路徑和文件名格式 */

實例化時, 修改文件上傳請求地址

ue.ready(function() {
	UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
	UE.Editor.prototype.getActionUrl = function (action) {
        if (action == 'upload/uploadImage.do') {
            return  "http://localhost:8082/upload/uploadImage.do";
        } else {
            return this._bkGetActionUrl.call(this, action);
        }
    };
});

定義上傳圖片接口

@RequestMapping("/uploadImage")
public Map uploadImage(MultipartFile upfile) throws Exception {
	try {
		FastDFSClient fastDFS = new FastDFSClient("classpath:fastDFS/fdfs_client.conf");
		//上傳文件返回文件保存的路徑和文件名
		String path = fastDFS.uploadFile(upfile.getBytes(), upfile.getOriginalFilename(), upfile.getSize());
		//拼接上服務器的地址返回給前端
		String url  = FILE_SERVER + path;
		Map<String ,Object > result = new HashMap<>();
		result.put("state","SUCCESS");
		result.put("url",url);
		result.put("title",upfile.getOriginalFilename());
		result.put("original",upfile.getOriginalFilename());
		return result;
	} catch (Exception e) {
		e.printStackTrace();
	}
	return null;
}

商品圖片上傳至fastFDS

引入pom文件

<dependency>
	<groupId>org.csource.fastdfs</groupId>
	<artifactId>fastdfs</artifactId>
	<version>1.2</version>
</dependency>

引入fastDFS配置文件和服務地址配置文件

application.properties

FILE_SERVER_URL=http://192.168.1.88/

fdfs_client.conf

# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fastdfs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.1.88:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf

在spring-mvc.xml加載屬性文件

<context:property-placeholder location="classpath:config/application.properties" />

在common中引入上傳工具類 FastDFSClient

import org.apache.commons.io.FilenameUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import java.io.IOException;

public class FastDFSClient {

private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;

public FastDFSClient(String conf) throws Exception {
	if (conf.contains("classpath:")) {
		conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
	}
	ClientGlobal.init(conf);
	trackerClient = new TrackerClient();
	trackerServer = trackerClient.getConnection();
	storageServer = null;
	storageClient = new StorageClient1(trackerServer, storageServer);
}

/**
 * @param file 文件二進制
 * @param fileName 文件名
 * @param fileSize 文件大小
 * @return
 * @throws Exception
    */
    public String uploadFile(byte[] file, String fileName, long fileSize) throws Exception {
    NameValuePair[] metas = new NameValuePair[3];
    metas[0] = new NameValuePair("fileName", fileName);
    metas[1] = new NameValuePair("fileSize", String.valueOf(fileSize));
    metas[2] = new NameValuePair("fileExt", FilenameUtils.getExtension(fileName));
    String result = storageClient.upload_file1(file, FilenameUtils.getExtension(fileName), metas);
    return result;
    }

/**
 *
 * @param storagePath  文件的所有路徑 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
 * @return -1失敗,0成功
 * @throws Exception
    */
    public Integer delete_file(String storagePath){
    int result=-1;
    try {
    	result = storageClient.delete_file1(storagePath);
    } catch (Exception e) {
    	e.printStackTrace();
    }
    return  result;
    }
}

在UploadController方法中上傳圖片

@Value("${FILE_SERVER_URL}")
private String FILE_SERVER;

@RequestMapping("/uploadFile")
public Result uploadFile(MultipartFile file) throws Exception {
	try {
		FastDFSClient fastDFS = new FastDFSClient("classpath:fastDFS/fdfs_client.conf");
		//上傳文件返回文件保存的路徑和文件名
		String path = fastDFS.uploadFile(file.getBytes(), file.getOriginalFilename(), file.getSize());
		//拼接上服務器的地址返回給前端
		return new Result(true, FILE_SERVER + path);
	} catch (Exception e) {
		e.printStackTrace();
		return new Result(false, "上傳失敗!");
	}
}

SPU與SKU

SPU = Standard Product Unit (標準化產品單元)

SPU是商品信息聚合的最小單位,是一組可複用、易檢索的標準化信息的集合
該集合描述了一個產品的特性
spu 屬性,不會影響到庫存和價格的屬性, 又叫關鍵屬性

舉例

Oppo R17這是商品的SPU
但Oppo R17只是一個名詞,單純的理解這個名詞是沒有意義的
SPU是一組商品的屬性組合

【硬件參數】:
CPU 型號:高通驍龍™ 670
CPU 頻率:2.0GHz
核心數:八核
處理器位數:64 位
GPU 型號:Adreno™ 615
電池容量:3500mAh(典型值)*
【尺寸】:
長:約 157.5mm
寬:約 74.9mm
厚:約 7.5mm
重:約 182g
毛重: 420.00 g
產地: 中國大陸

這個SPU屬性組合的名稱叫作Oppo R17

SKU=stock keeping unit(庫存量單位)

會影響到庫存和價格的屬性, 又叫銷售屬性
指的是具體規格單品
買家購買、商家進貨、供應商備貨、工廠生產都是依據SKU進行的
影響價格和庫存的屬性集合, 與商品是多對一的關係,即一個商品有多個SKU

舉例

如流光藍(三種顏色:流光藍、霓光紫、霓光漸變色)+8G+128G(兩種配置:8G+128G、6G+128G)。

即Oppo R17有一個SPU、6種SKU。

如一件M碼(四個尺碼:S碼、M碼、L碼、X碼)的粉色(三種顏色:粉色、黃色、黑色)Zara女士風衣,其中M碼、粉色就是一組SKU的組合

SKU在生成時, 會根據屬性生成相應的笛卡爾積,根據一組SKU能夠肯定商品的庫存狀況,那麼上面的Zara女士風衣一共有4 * 3 = 12個SKU組合
相關文章
相關標籤/搜索