FastDFS是一個開源的輕量級的分佈式文件系統。他解決了大量數據存儲和負載均衡等問題。特別適合以中小文件(4KB < FileSize < 500MB)爲載體的在線服務,如視頻,音頻,圖片網站等等。
FastDFS是一款開源的輕量級分佈式文件系統,他是由純 C 實現,支持Linux,FreeBSD等UNIX系統類,不是通用的文件系統,只能經過專有的API訪問,目前提供了C、Java和PHP API爲互聯網應用量身定作,解決大容量文件存儲問題,追求高性能和高擴展性FastDFS能夠看作是基於文件的key value pair存儲系統,稱做分佈式文件存儲服務更爲合適。html
Web Server
,也能夠和其餘的Web Server
配合使用跟蹤服務器,主要作調度工做,起負載均衡的做用。在內存中記錄集羣中所存在的全部存儲組和存儲服務器的狀態信息,是客戶端和數據服務器交互的樞紐。相比GlastFS中的master 更爲精簡,不記錄文件索引悉信息,佔用的內存量不多。
Tracker 是FastDFS的協調者,負責管理全部的 storgae server 和 Group,每一個storage在啓動後會鏈接tracker,並告知tarcker本身所屬的group等信息,並保持週期性的心跳,tracker根據storage的心跳悉信息,創建group --> storage server list 的映射表。mysql
Tracker 須要管理的元信息不多,會所有存儲在內存中。另外tracker上的元信息都是由storage彙報的信息生成的,自己不須要持久任何數據,這樣使得tracker很是容易擴展,直接增長tracker機器便可擴展爲tracker cluster 來服務,cluster裏每一個tracker之間是徹底對等的,全部的 tracker都接受storage的心跳信息。生成元數據信息來提供讀寫服務。nginx
存儲服務器,又稱爲存儲節點或者數據服務器,文件和文件屬性(meta-data)都保存在存儲服務器上。storage server直接利用OS的文件系統調用管理文件。sql
stroage 以組(group)爲單位組織,一個group內包含多臺stroage機器,數據互爲備份,存儲空間以group內容量最小的storage爲準,因此建議同一個group 裏面的storage容量是相同的,防止資源浪費。docker
以group爲單位組織存儲能方便的進行應用隔離,負責均衡,副本數定義(group內storage的數量即爲該group的副本數)。好比將不一樣服務的數據寫到不一樣的group裏面,來作到資源隔離,咱們也能夠把一個服務的數據寫到多個group裏面來作負載均衡。shell
group的容量受單機存儲容量的限制,同時當group內有storag損壞,數據恢復只能依賴於group中其餘storage機器,使得恢復時間會很長。數組
group內每一個storage的存儲依賴於本地文件系統,storage可配置多個數據存儲目錄。bash
storage接受到寫文件操做時,會根據配置好的規則,選擇其中一個存儲目錄來存儲文件。爲了不單個目錄下的文件數太多,在storage第一次啓動時,會在每一個數據存儲目錄裏建立2級子目錄,每級256個,一共65536個目錄,新寫的文件會以hash的方式被路由到其中某個子目錄下,而後將文件數據直接做爲一個本地文件存儲到該目錄中。服務器
客戶端做爲業務請求的發起方,經過專有接口,使用TCP/IP協議與跟蹤服務器或存儲節點發生數據交互。網絡
組,又可稱爲卷。,同組內服務器上的文件是徹底相同的,同一組內的storage server 之間是對等的,文件上傳,刪除等操做能夠在任意一臺storage server 上進行,一個storage server上上面能夠對應着多少組,每一個組在storage server上能夠對應一個設備。
鍵值對( Key Value Pair) 方式,如:width=1024,heigth=768
首先客戶端請求Tracker服務獲取到要操做的group組對應的存儲服務器的ip地址和端口,而後客戶端根據返回的IP地址和端口號請求上傳文件,存儲服務器接收到請求後生產文件,而且將文件內容寫入磁盤並返回給客戶端file_id、路徑信息、文件名等信息,客戶端保存相關信息上傳完畢。
FastDFS內存存儲機制:
1,選擇tracker server
當集羣中不止一個tracker server
時,因爲tracker server
之間是徹底對等的關係,客戶端在upload文件時能夠任意選擇一個tracker。當tracker接收到upload file的請求時,會爲該文件分配一個能夠存儲該文件的group,支持以下選擇group的規則:
2,選擇storage server
當選定group後,tracker會在group內選擇一個storage server 給客戶端,支持以下選擇storage的規則
3,選擇storage path
當分配好storage server後,客戶端將向storage發送寫文件請求,storage將會爲文件分配一個數據存儲目錄,支持以下規則:
4,生成FileID
選定目錄以後,storage會爲文件生成一個FileID,由storage server ip + 文件建立時間 + 文件大小 + 文件crc32 +隨機數
拼接。而後將這個二進制串進行base64編碼,轉換爲可打印的字符串。選擇兩級目錄 當選定存儲目錄以後,storage會爲文件分配一個fileid,每一個存儲目錄下有兩級256*256的子目錄,storage會按文件fileid進行兩次hash(猜想),路由到其中一個子目錄,而後將文件以fileid爲文件名存儲到該子目錄下。
5,生成文件名
當文件存儲到某個子目錄後,即認爲該文件存儲成功,接下來會爲該文件生成一個文件名,文件名由group、存儲目錄、兩級子目錄、fileid、文件後綴名(由客戶端指定,主要用於區分文件類型)拼接而成。
6,storage寫入磁盤
每一個storage寫文件後,同時會寫一份binlog
,binlog
裏面不包含文件數據,值包含文件名等元信息,這份binlog
用於後臺同步,storage會記錄向Group內其餘storage同步的進度,以便重啓後能接上上次的進度繼續同步;進度以時間戳的方式進行記錄。
7,按期向tracker彙報信息
storage同步進度會做爲元數據的一部分會報道全部的tracker上,tracker在選擇storage的時候會以此做參考(看下面下載機制)
storage生成的文件名中,包含源頭storage ID/IP地址和文件建立時間戳。storage 定時向tracker報告文件同步狀況,包括向同組內其餘storage同步到的文件時間戳。tracker 收到storage的文件同步報告後,找出該組內每臺storage唄同步到的最小時間戳,做爲storage屬性保存到內存中。
客戶端帶上文件名信息請求Tracker服務獲取到storage服務器的IP和Port,而後client更具返回的IP地址和端口號請求下載文件,存儲服務器沒收到請求後返回文件給客戶端。
跟Upload file 同樣,在下載文件時客戶端能夠選擇任意的tracker server。tracker發送下載請求給某個trakcer,必須帶上文件名信息,tracker從文件名中解析出文件的group、大小、建立時間等信息,而後爲該請求選擇一個storage用來服務讀取請求。因爲group內的文件同步時在後臺異步進行的,因此有可能出如今讀的時候,文件尚未同步到某些storage server上,爲了儘可能避免訪問到這樣的storage,tracker按照以下規則選擇group內可讀的storage:
上述文件同步延遲閥值和同步一個文件的最大時長這兩個參數,在tracker.conf中配置,配置項分別是 storage_sync_file_max_delay 和 storage_sync_file_max_time。
由於FastDFS利用時間戳來解決文件同步延遲帶來的文件訪問問題。集羣內部服務器的時間須要保持一致,要求時間偏差不超過1S,因此建議使用NTP時間服務器來確保時間一致。
咱們上面一直在說文件同步,可是文件真正的同步機制又是什麼樣子的呢?
FastDFS同步文件採用binlog
異步複製方式。stroage server 使用binlog(記錄文件的元數據)文件記錄文件上傳、刪除等操做,根據binlog進行文件同步。下面 給出幾行binlog文件內容實例:
binlog文件的路徑$base_path/data/sync/binlog.*
1574850031 C M00/4C/2D/rBCo3V3eTe-AP6SRAABk7o3hUY4681.wav 1574850630 C M00/4C/2D/rBCo3V3eUEaAPMwRAABnbqEmTEs918.wav 1574851230 C M00/4C/2D/rBCo3V3eUp6ARGlEAABhzomSJJo079.wav 1574851230 C M00/4C/2D/rBCo3V3eUp6ABSZWAABoDiunCqc737.wav 1574851830 C M00/4C/2D/rBCo3V3eVPaAYKlIAABormd65Ds168.wav 1574851830 C M00/4C/2D/rBCo3V3eVPaAPs-CAABljrrCwyI452.wav 1574851830 C M00/4C/2D/rBCo3V3eVPaAdSeKAABrLhlwnkU907.wav 1574852429 C M00/4C/2D/rBCo3V3eV02Ab4yKAABmLjpCyas766.wav 1574852429 C M00/4C/2D/rBCo3V3eV02AASzFAABorpw6oJw030.wav 1574852429 C M00/4C/2D/rBCo3V3eV02AHSM7AAB0jpYtHQA019.wav
從上面能夠看出,binlog文件有三列,以此爲時間戳、操做類型和文件ID(不帶group名稱)
文件操做類型採用單個字母編碼,其中源頭操做用大寫字母表示,被同步的操做做爲對應的小鞋字母
C:上傳文件(upload)
D:刪除文件(delete)
A:追加文件(append)
M:部分文件更新(modify)
U:整個文件更新(set metadata)
T:截斷文件(truncate)
L:建立符號鏈接(文件去重功能,相同內容的只保存一份)
同組內的storage server之間是對等的,文件上傳、刪除等操做能夠在任意一臺storage server上進行。文件同步只在同組內的storage server之間進行,採用push方式,即源頭服務器同步給本組的其餘存儲服務器。對於同組的其餘storage server,一臺storage server分別啓動一個線程進行文件同步。
文件同步採用增量方式,記錄已同步的位置到mark文件中。mark文件存放路徑爲 $base_path/data/sync/。mark文件內容示例:
binlog_index=3 binlog_offset=382 need_sync_old=1 sync_old_done=1 until_timestamp=1571976211 scan_row_count=2033425 sync_row_count=2033417
採用binlog的異步複製方式,必然存在同步延遲的問題,好比mysql的主從數據同步。
當咱們Group中一個storage磁盤存在損壞的時候,咱們想更換磁盤的時候,磁盤換上以後自動恢復數據。
如何判斷是否須要單盤數據恢復:檢測$Store_path/data目錄下的兩個子目錄00/00 和FF/FF (每級子目錄採用默認256個的狀況下)是否存在,若其中一個不存在,則自動創建所需子目錄,並啓動單盤數據自動恢復。
單盤數據恢復邏輯:
咱們這邊採用season/fastdfs:1.2
這個鏡像,咱們獲取他的dockerfile看一下是如何啓動的
cat > Obtain_dockerfile.sh <<-'EOF' #!/bin/bash #DOC 這是一個經過docker images 來獲取dockerfile,看一下怎麼啓動的 export PATH=$PATH if [ $# -eq 1 ];then docker history --format {{.CreatedBy}} --no-trunc=true $1 |sed "s/\/bin\/sh\ -c\ \#(nop)\ //g"|sed "s/\/bin\/sh\ -c/RUN/g" | tac else echo "sh Obtain_dockerfile.sh $DOCKER_IMAGE" fi EOF
執行腳本獲取到的dockerfile以下
# sh Obtain_dockerfile.sh season/fastdfs:1.2 ADD file:b908886c97e2b96665b7afc54ff53ebaef1c62896cf83a1199e59fceff1dafb5 in / CMD ["/bin/bash"] MAINTAINER season summer summer@season RUN apt-get update && apt-get install -y gcc gcc-multilib libc6-dev-i386 make nano htop --no-install-recommends RUN rm -rf /var/lib/apt/lists/* COPY dir:9bb2976272b997f08c6435eb1f63b3801cec525f269b6a1de45ef02ba72dc919 in /FastDFS_v4.08 COPY dir:a74a73cd25b708ddc7dc6556b6f9608066876c344de608fb0f2e14dda04a48ba in /libevent-2.0.14 COPY dir:d5fde946a90870a8850d6e9b0b8b7be4e5e41c0b0f2d18cc19589e6caa56061e in /zlib-1.2.8 COPY dir:46967139f210ec8160e07010de80fea21e3950bf7cc680ccd10f3d01d458afce in /fastdfs-nginx-module COPY dir:d39817fa72b763e78b1fe17483b6fcbebe769e79caf0a2411a9b35b5b104c5f7 in /nginx-1.8.0 COPY file:232f9aba296194eae5e61a56594f2d9b7fc4f03bfb7739e423335b36c7866653 in /entrypoint.sh WORKDIR /libevent-2.0.14 RUN ./configure --prefix=/usr/local/libevent-2.0.14 && make && make install && make clean RUN echo '/usr/local/libevent-2.0.14/include' >> /etc/ld.so.conf RUN echo '/usr/local/libevent-2.0.14/lib' >> /etc/ld.so.conf RUN ldconfig WORKDIR /FastDFS_v4.08 RUN ./make.sh C_INCLUDE_PATH=/usr/local/libevent-2.0.14/include LIBRARY_PATH=/usr/local/libevent-2.0.14/lib && ./make.sh install && ./make.sh clean WORKDIR /nginx-1.8.0 RUN ./configure --user=root --group=root --prefix=/etc/nginx --with-http_stub_status_module --with-zlib=/zlib-1.2.8 --without-http_rewrite_module --add-module=/fastdfs-nginx-module/src RUN make RUN make install RUN make clean RUN ln -sf /etc/nginx/sbin/nginx /sbin/nginx RUN mkdir /fastdfs RUN mkdir /fastdfs/tracker RUN mkdir /fastdfs/store_path RUN mkdir /fastdfs/client RUN mkdir /fastdfs/storage RUN mkdir /fdfs_conf RUN cp /FastDFS_v4.08/conf/* /fdfs_conf RUN cp /fastdfs-nginx-module/src/mod_fastdfs.conf /fdfs_conf WORKDIR / RUN chmod a+x /entrypoint.sh ENTRYPOINT &{["/entrypoint.sh"]}
能夠看到咱們啓動都是執行這個腳原本實現的,咱們如今來看一下這個腳本里面的內容以下:
#!/bin/bash #set -e TRACKER_BASE_PATH="/fastdfs/tracker" TRACKER_LOG_FILE="$TRACKER_BASE_PATH/logs/trackerd.log" STORAGE_BASE_PATH="/fastdfs/storage" STORAGE_LOG_FILE="$STORAGE_BASE_PATH/logs/storaged.log" TRACKER_CONF_FILE="/etc/fdfs/tracker.conf" STORAGE_CONF_FILE="/etc/fdfs/storage.conf" NGINX_ACCESS_LOG_FILE="/etc/nginx/logs/access.log" NGINX_ERROR_LOG_FILE="/etc/nginx/logs/error.log" MOD_FASTDFS_CONF_FILE="/etc/fdfs/mod_fastdfs.conf" # remove log files if [ -f "/fastdfs/tracker/logs/trackerd.log" ]; then rm -rf "$TRACKER_LOG_FILE" fi if [ -f "/fastdfs/storage/logs/storaged.log" ]; then rm -rf "$STORAGE_LOG_FILE" fi if [ -f "$NGINX_ACCESS_LOG_FILE" ]; then rm -rf "$NGINX_ACCESS_LOG_FILE" fi if [ -f "$NGINX_ERROR_LOG_FILE" ]; then rm -rf "$NGINX_ERROR_LOG_FILE" fi if [ "$1" = 'shell' ]; then /bin/bash fi if [ "$1" = 'tracker' ]; then echo "start fdfs_trackerd..." if [ ! -d "/fastdfs/tracker/logs" ]; then mkdir "/fastdfs/tracker/logs" fi n=0 array=() #循環讀取配置文件 while read line do array[$n]="${line}"; ((n++)); done < /fdfs_conf/tracker.conf rm "$TRACKER_CONF_FILE" #${!array[@]} 爲數組的下標 for i in "${!array[@]}"; do #判斷組名是否爲空 if [ ${STORE_GROUP} ]; then #若是不爲空,則判斷是否包含storage_group 這個字段,而後把這行地換掉 [[ "${array[$i]}" =~ "store_group=" ]] && array[$i]="store_group=${STORE_GROUP}" fi # 循環追加配置 echo "${array[$i]}" >> "$TRACKER_CONF_FILE" done touch "$TRACKER_LOG_FILE" ln -sf /dev/stdout "$TRACKER_LOG_FILE" fdfs_trackerd $TRACKER_CONF_FILE sleep 3s #delay wait for pid file # tail -F --pid=`cat /fastdfs/tracker/data/fdfs_trackerd.pid` /fastdfs/tracker/logs/trackerd.log # wait `cat /fastdfs/tracker/data/fdfs_trackerd.pid` tail -F --pid=`cat /fastdfs/tracker/data/fdfs_trackerd.pid` /dev/null fi if [ "$1" = 'storage' ]; then echo "start fdfs_storgaed..." n=0 array=() while read line do array[$n]="${line}"; ((n++)); done < /fdfs_conf/storage.conf rm "$STORAGE_CONF_FILE" for i in "${!array[@]}"; do if [ ${GROUP_NAME} ]; then [[ "${array[$i]}" =~ "group_name=" ]] && array[$i]="group_name=${GROUP_NAME}" fi if [ ${TRACKER_SERVER} ]; then [[ "${array[$i]}" =~ "tracker_server=" ]] && array[$i]="tracker_server=${TRACKER_SERVER}" fi echo "${array[$i]}" >> "$STORAGE_CONF_FILE" done if [ ! -d "/fastdfs/storage/logs" ]; then mkdir "/fastdfs/storage/logs" fi touch "$STORAGE_LOG_FILE" ln -sf /dev/stdout "$STORAGE_LOG_FILE" fdfs_storaged "$STORAGE_CONF_FILE" sleep 3s #delay wait for pid file # tail -F --pid=`cat /fastdfs/storage/data/fdfs_storaged.pid` /fastdfs/storage/logs/storaged.log #wait -n `cat /fastdfs/storage/data/fdfs_storaged.pid` tail -F --pid=`cat /fastdfs/storage/data/fdfs_storaged.pid` /dev/null fi if [ "$1" = 'nginx' ]; then echo "starting nginx..." # ln log files to stdout/stderr touch "$NGINX_ACCESS_LOG_FILE" ln -sf /dev/stdout "$NGINX_ACCESS_LOG_FILE" touch "$NGINX_ERROR_LOG_FILE" ln -sf /dev/stderr "$NGINX_ERROR_LOG_FILE" # change mod_fastfdfs.conf n=0 array=() while read line do array[$n]="${line}"; ((n++)); done < /fdfs_conf/mod_fastdfs.conf if [ -f "$MOD_FASTDFS_CONF_FILE" ]; then rm -rf "$MOD_FASTDFS_CONF_FILE" fi for i in "${!array[@]}"; do if [ ${GROUP_NAME} ]; then [[ "${array[$i]}" =~ "group_name=" ]] && array[$i]="group_name=${GROUP_NAME}" fi if [ ${TRACKER_SERVER} ]; then [[ "${array[$i]}" =~ "tracker_server=" ]] && array[$i]="tracker_server=${TRACKER_SERVER}" fi if [ ${URL_HAVE_GROUP_NAME} ]; then [[ "${array[$i]}" =~ "url_have_group_name=" ]] && array[$i]="url_have_group_name=${URL_HAVE_GROUP_NAME}" fi if [ ${STORAGE_SERVER_PORT} ]; then [[ "${array[$i]}" =~ "storage_server_port=" ]] && array[$i]="storage_server_port=${STORAGE_SERVER_PORT}" fi echo "${array[$i]}" >> "$MOD_FASTDFS_CONF_FILE" done nginx -g "daemon off;"
咱們簡單的分析下這個腳本,發現這個腳本是按照啓動後面傳遞的參數來判斷是啓動trakcer
、storage
仍是nginx
,腳本什麼的咱們也看了 如今來啓動測試下
docker run -ti -d --name trakcer \ -v /etc/localtime:/etc/localtime -v /tracker_data:/fastdfs/tracker/data \ --net=host \ --restart=always \ season/fastdfs tracker
啓動以後tracker 會監聽在22122 上,咱們也能夠經過傳遞環境變量的方式來更改端口
-e port=22222
全部配置文件裏面的配置咱們均可以經過環境變量的方式傳遞進去
#tracker 能夠傳遞的環境變量和默認值 disabled=false bind_addr= port=22122 connect_timeout=30 network_timeout=60 base_path=/fastdfs/tracker max_connections=256 accept_threads=1 work_threads=4 store_lookup=2 store_group=group1 store_server=0 store_path=0 download_server=0 reserved_storage_space = 10% log_level=info run_by_group= run_by_user= allow_hosts=* sync_log_buff_interval = 10 check_active_interval = 120 thread_stack_size = 64KB storage_ip_changed_auto_adjust = true storage_sync_file_max_delay = 86400 storage_sync_file_max_time = 300 use_trunk_file = false slot_min_size = 256 slot_max_size = 16MB trunk_file_size = 64MB trunk_create_file_advance = false trunk_create_file_time_base = 02:00 trunk_create_file_interval = 86400 trunk_create_file_space_threshold = 20G trunk_init_check_occupying = false trunk_init_reload_from_binlog = false use_storage_id = false storage_ids_filename = storage_ids.conf id_type_in_filename = ip store_slave_file_use_link = false rotate_error_log = false error_log_rotate_time=00:00 rotate_error_log_size = 0 use_connection_pool = false connection_pool_max_idle_time = 3600 http.server_port=8080 http.check_alive_interval=30 http.check_alive_type=tcp http.check_alive_uri=/status.html
docker run -di --name storage \ --restart=always \ -v /storage_data:/fastdfs/storage/data \ -v /store_path:/fastdfs/store_path \ --net=host \ -e TRACKER_SERVER=172.16.1.170:22122 season/fastdfs:1.2 storage
可傳遞的環境變量
disabled=false group_name=group1 bind_addr= client_bind=true port=23000 connect_timeout=30 network_timeout=60 heart_beat_interval=30 stat_report_interval=60 base_path=/fastdfs/storage max_connections=256 buff_size = 256KB accept_threads=1 work_threads=4 disk_rw_separated = true disk_reader_threads = 1 disk_writer_threads = 1 sync_wait_msec=50 sync_interval=0 sync_start_time=00:00 sync_end_time=23:59 write_mark_file_freq=500 store_path_count=1 store_path0=/fastdfs/store_path subdir_count_per_path=256 tracker_server=172.16.1.170:22122 log_level=info run_by_group= run_by_user= allow_hosts=* file_distribute_path_mode=0 file_distribute_rotate_count=100 fsync_after_written_bytes=0 sync_log_buff_interval=10 sync_binlog_buff_interval=10 sync_stat_file_interval=300 thread_stack_size=512KB upload_priority=10 if_alias_prefix= check_file_duplicate=0 file_signature_method=hash key_namespace=FastDFS keep_alive=0 use_access_log = false rotate_access_log = false access_log_rotate_time=00:00 rotate_error_log = false error_log_rotate_time=00:00 rotate_access_log_size = 0 rotate_error_log_size = 0 file_sync_skip_invalid_record=false use_connection_pool = false connection_pool_max_idle_time = 3600 http.domain_name= http.server_port=8888
進入到tracker容器裏面
docker exec -it tracker bash grep 22122 /home/fdfs/client.conf sed -i "s#`grep 22122 /home/fdfs/client.conf`#tracker_server=172.16.1.170:22122#g" /home/fdfs/client.conf #使用下面命令查看fastdfs集羣狀態 fdfs_monitor /etc/fdfs/client.conf #上傳一個文件測試下 fdfs_upload_file /etc/fdfs/client.conf /etc/hosts group1/M00/00/00/rBABql33W5CAK7yFAAAAnrLoM8Y9254622 #下載文件 root@test01:/etc/fdfs# fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/rBABql33W5CAK7yFAAAAnrLoM8Y9254622 root@test01:/etc/fdfs# ls -l rBABql33W5CAK7yFAAAAnrLoM8Y9254622 -rw-r--r-- 1 root root 158 Dec 16 10:26 rBABql33W5CAK7yFAAAAnrLoM8Y9254622 root@test01:/etc/fdfs# cat rBABql33W5CAK7yFAAAAnrLoM8Y9254622 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 #刪除文件 fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/rBABql33W5CAK7yFAAAAnrLoM8Y9254622
docker run -id --name fastdfs_nginx \ --restart=always \ -v /store_path:/fastdfs/store_path \ -p 8888:80 \ -e GROUP_NAME=group1 \ -e TRACKER_SERVER=172.16.1.170:22122 \ -e STORAGE_SERVER_PORT=23000 \ season/fastdfs:1.2 nginx
注意:
```nginx.conf
server {
listen 8888;
server_name localhost;
location ~ /group([0-9])/M00 {
root //fastdfs/store_path/data;
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
可更改的配置文件 ```bash grep -Ev "^#|^$" mod_fastdfs.conf connect_timeout=2 network_timeout=30 base_path=/tmp load_fdfs_parameters_from_tracker=true storage_sync_file_max_delay = 86400 use_storage_id = false storage_ids_filename = storage_ids.conf tracker_server=tracker:22122 storage_server_port=23000 group_name=group1 url_have_group_name=true store_path_count=1 #storage_path0 要和storage的相同 store_path0=/fastdfs/store_path log_level=info log_filename= response_mode=proxy if_alias_prefix= flv_support = true flv_extension = flv group_count = 0
咱們只須要在另一臺機器啓動storage和nginx便可,而後作個負載均衡爲全部的