存儲規劃是企業必須考慮到的因素,無限增大的資源不但須要管理維護,還須要考慮容災備份的機制。我公司在存儲變化上,發現磁盤使用率立刻超標的狀況,發起了數據存儲遷移的規劃方案php
res1-res10爲10個靜態資源節點,數據目錄於/data/下掛載有2TB數據盤,經過nfs掛載32TB共享存儲塊位於/mnt下,數據經過rsync+sersync同步於/mnt目錄,與32TB共享存儲塊保持實時狀態node
單數res節點爲nfs-master,雙數res節點爲nfs-slave,每兩節點共享一塊32T的存儲塊,2T SSD數據盤依舊爲程序目錄,將之前靜態資源目錄/data/webapps/nginx/res/upload/cdn/node*
變動爲新路徑/resource_nginx/res/upload/cdn/node*
。10個節點依舊爲db共享存儲的nfs-slave,實時同步靜態資源nginx
①購入5塊共享存儲塊
②10個實例每兩個實例掛載一塊共享存儲,一共5塊,採用nfs
③之前備份用了16T的共享存儲塊依舊作備份
④更改res靜態目錄,將2T中靜態資源對拷入新存儲塊路徑中,node1和node2節點的靜態數據導入新塊存儲,將node3和node4的靜態數據導入新塊存儲,將node5和node6的靜態數據導入新塊存儲,每兩個節點數據導入一新塊,以此類推
⑤確認新數據同步到5塊存儲後開始實施更新
⑥將nginx中靜態根路徑更改成新res路徑,更改中心配置config項目中resource項目的目錄參數爲新res路徑
⑦逐調權重爲0,重啓項目平滑升級,重載nginx使得新路徑生效
⑧確認項目輸出日誌是否異常
⑨測試功能上傳與訪問
⑩恢復權重,更改fstab,與備份塊rsync+sersync路徑
①8月1日更新事後,8月2日任務是須要恢復靜態資源的備份方案,從新調整rsync+sersync的配置文件。因爲運維過程當中的疏忽,10臺res節點少更改了res6的配置,下面附正常更改的文件與res6當時未更改的文件es6
須要恢復的正常rsyncd.conf的配置文件(舉例爲res1的)
[root@hmf_res1 ~]# cat /etc/rsyncd.confweb
#rsync_config_________________start #created by wang 2017-04-18 00:08 ##rsyncd.conf start## uid = root gid = root use chroot = no max connections = 200 timeout = 300 pid file = /var/run/rsyncd.pid lock file = /var/run/rysnc.lock log file = /var/log/rsyncd.log ignore errors read only = false list = false hosts allow = 127.0.0.1/8 #hosts deny = 0.0.0.0/32 #auth users = rsync_backup #secrets file = /etc/rsync.password [node1] path = /mnt/node1 [node2] path = /mnt/node2 [node3] path = /mnt/node3 [node4] path = /mnt/node4 [node5] path = /mnt/node5 [node6] path = /mnt/node6 [node7] path = /mnt/node7 [node8] path = /mnt/node8 [node9] path = /mnt/node9 [node10] path = /mnt/node10
須要恢復的正常sersync中config.xml配置文件
[root@hmf_res1 ~]# cat /data/server/sersync/config/config.xmlexpress
<?xml version="1.0" encoding="ISO-8859-1"?> <head version="2.5"> <host hostip="localhost" port="8008"></host> <debug start="false"/> <fileSystem xfs="false"/> <filter start="false"> <exclude expression="(.*)\.svn"></exclude> <exclude expression="(.*)\.gz"></exclude> <exclude expression="^info/*"></exclude> <exclude expression="^static/*"></exclude> </filter> <inotify> <delete start="true"/> <createFolder start="true"/> <createFile start="false"/> <closeWrite start="true"/> <moveFrom start="true"/> <moveTo start="true"/> <attrib start="false"/> <modify start="false"/> </inotify> <sersync> <localpath watch="/resource_nginx/res/upload/cdn/node1"> <remote ip="127.0.0.1" name="node1"/> <!--<remote ip="192.168.8.39" name="tongbu"/>--> <!--<remote ip="192.168.8.40" name="tongbu"/>--> </localpath> <rsync> <commonParams params="-az"/> <auth start="false" users="rsync_backup" passwordfile="/etc/rsync.password"/> <userDefinedPort start="false" port="874"/><!-- port=874 --> <timeout start="true" time="600"/><!-- timeout=100 --> <ssh start="false"/> </rsync> <failLog path="/data/server/sersync/logs/rsync_fail.log" timeToExecute="60"/><!--default every 60mins execute once--> <crontab start="false" schedule="600"><!--600mins--> <crontabfilter start="false"> <exclude expression="*.php"></exclude> <exclude expression="info/*"></exclude> </crontabfilter> </crontab> <plugin start="false" name="command"/> </sersync> <plugin name="command"> <param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix--> <filter start="false"> <include expression="(.*)\.php"/> <include expression="(.*)\.sh"/> </filter> </plugin> <plugin name="socket"> <localpath watch="/opt/tongbu"> <deshost ip="192.168.138.20" port="8009"/> </localpath> </plugin> <plugin name="refreshCDN"> <localpath watch="/data0/htdocs/cms.xoyo.com/site/"> <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/> <sendurl base="http://pic.xoyo.com/cms"/> <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/> </localpath> </plugin> </head>
當時未更改res6中rsyncd.conf配置文件,也就是規劃項目以前的配置
[root@hmf_res6 ~]# cat /etc/rsyncd.conf服務器
#rsync_config_________________start #created by wang 2017-04-18 00:08 ##rsyncd.conf start## uid = root gid = root use chroot = no max connections = 200 timeout = 300 pid file = /var/run/rsyncd.pid lock file = /var/run/rysnc.lock log file = /var/log/rsyncd.log ignore errors read only = false list = false hosts allow = 127.0.0.1/8 #hosts deny = 0.0.0.0/32 #auth users = rsync_backup #secrets file = /etc/rsync.password [node1] path = /mnt/node1 [node2] path = /mnt/node2 [node3] path = /mnt/node3 [node4] path = /mnt/node4 [node5] path = /mnt/node5 [node6] path = /mnt/node6 [node7] path = /mnt/node7 [node8] path = /mnt/node8 [node9] path = /mnt/node9 [node10] path = /mnt/node10 [resource] #此處未刪除配置,繼續往新塊裏同步 path = /resource_nginx/res/upload/cdn/node6
未更改res6中sersync config.xml配置文件
[root@hmf_res6 ~]# cat /data/server/sersync/config/config.xml架構
<?xml version="1.0" encoding="ISO-8859-1"?> <head version="2.5"> <host hostip="localhost" port="8008"></host> <debug start="false"/> <fileSystem xfs="false"/> <filter start="false"> <exclude expression="(.*)\.svn"></exclude> <exclude expression="(.*)\.gz"></exclude> <exclude expression="^info/*"></exclude> <exclude expression="^static/*"></exclude> </filter> <inotify> <delete start="true"/> <createFolder start="true"/> <createFile start="false"/> <closeWrite start="true"/> <moveFrom start="true"/> <moveTo start="true"/> <attrib start="false"/> <modify start="false"/> </inotify> <sersync> <localpath watch="/data/webapps/nginx/res/upload/cdn/node6"> #此處未更改爲新存儲路徑,還一直監聽着原2T路徑,但此路徑已經再也不寫入數據 <remote ip="127.0.0.1" name="node6"/> <!--<remote ip="192.168.8.39" name="tongbu"/>--> <!--<remote ip="192.168.8.40" name="tongbu"/>--> </localpath> <rsync> <commonParams params="-az"/> <auth start="false" users="rsync_backup" passwordfile="/etc/rsync.password"/> <userDefinedPort start="false" port="874"/><!-- port=874 --> <timeout start="true" time="600"/><!-- timeout=100 --> <ssh start="false"/> </rsync> <failLog path="/data/server/sersync/logs/rsync_fail.log" timeToExecute="60"/><!--default every 60mins execute once--> <crontab start="false" schedule="600"><!--600mins--> <crontabfilter start="false"> <exclude expression="*.php"></exclude> <exclude expression="info/*"></exclude> </crontabfilter> </crontab> <plugin start="false" name="command"/> </sersync> <plugin name="command"> <param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix--> <filter start="false"> <include expression="(.*)\.php"/> <include expression="(.*)\.sh"/> </filter> </plugin> <plugin name="socket"> <localpath watch="/opt/tongbu"> <deshost ip="192.168.138.20" port="8009"/> </localpath> </plugin> <plugin name="refreshCDN"> <localpath watch="/data0/htdocs/cms.xoyo.com/site/"> <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/> <sendurl base="http://pic.xoyo.com/cms"/> <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/> </localpath> </plugin> </head>
②根據sersync同步的默認規則中,<delete start="true"/>
,此項參數爲監聽源服務器目錄位置,若是在源服務器目錄沒有的文件,會進行刪除,有的文件進行同步,保持文件相同狀態。這是一個致命的導火索
③8月7日事後一週,沒有發現任何異常。可是,在這段時間裏res6節點中已經沒有任何上傳的新文件內容,由於在新路徑一直在監聽舊路徑目錄,舊路徑必定是沒有新文件的,res6接到上傳的新文件就被刪除,接到就被刪除,遵循<delete start="true"/>
規則。此時已經res6早已經有大量的404,靜態資源訪問狀態碼的監控也沒有作到位
④正好在這天接到了能夠刪除舊路徑數據的許可,運維過程當中使用rm命令刪除舊數據app
rm -rf /data/webapps/nginx/res/cdn/upload/node1/* rm -rf /data/webapps/nginx/res/cdn/upload/node2/* rm -rf /data/webapps/nginx/res/cdn/upload/node3/* rm -rf /data/webapps/nginx/res/cdn/upload/node4/* rm -rf /data/webapps/nginx/res/cdn/upload/node5/* rm -rf /data/webapps/nginx/res/cdn/upload/node6/* rm -rf /data/webapps/nginx/res/cdn/upload/node7/* rm -rf /data/webapps/nginx/res/cdn/upload/node8/* rm -rf /data/webapps/nginx/res/cdn/upload/node9/* rm -rf /data/webapps/nginx/res/cdn/upload/node10/*
8月8日,事故發生,res6節點靜態資源訪問狀態碼大量404,第一時間查看訪問日誌,發如今刪除舊數據到如今的時間裏已經逐漸報出404,等到7日半夜時已經所有404。意識到是數據出了問題,發現新塊存儲中數據不存在/resource_nginx/res/cdn/upload/node6/
,準備恢復備份,卻又發現備份的數據也不存在了/mnt/node6/
運維
緣由是sersync監聽路徑/data/webapps/nginx/res/cdn/upload/node6/
同步到目標服務器兩個路徑中/resource_nginx/res/cdn/upload/node六、/mnt/node6
①問題一的解決:運維過程當中,發生漏配,誤配的問題,必定是自動化統一運維沒有作到位。以後的架構運維中採用saltstack,設置主機組,實現統一cmd,統一分發文件以及監控
nodegroups: hmf_res: 'L@hmf_res1,hmf_res2,hmf_res3,hmf_res4,hmf_res5,hmf_res11,hmf_res7,hmf_res8,hmf_res9,hmf_res10' salt -N 'hmf_res' cmd.run 'command' #指定分組統一管理
②問題二的解決:在生產環境中,若是沒有刻意要求源服務器與目標服務器的文件一致性的話,請務必關閉此默認項
更改sersync主配文件
<delete start="false"/>
③問題三的解決:在監控服務器上增強完善監控腳本,對出現大量的404 500 502狀態碼上作優化
④存儲的規劃眼界必定要放遠,計劃趕不上變化,無限增大的資源絕對不能拘束於成本。請慎用rm命令。在使用它時,請明知它會帶來的後果