記一次企業級存儲規劃及重大事故

存儲規劃是企業必須考慮到的因素,無限增大的資源不但須要管理維護,還須要考慮容災備份的機制。我公司在存儲變化上,發現磁盤使用率立刻超標的狀況,發起了數據存儲遷移的規劃方案php

1、靜態資源架構

①實施前節點架構:

clipboard.png

res1-res10爲10個靜態資源節點,數據目錄於/data/下掛載有2TB數據盤,經過nfs掛載32TB共享存儲塊位於/mnt下,數據經過rsync+sersync同步於/mnt目錄,與32TB共享存儲塊保持實時狀態node

②實施後節點架構:

clipboard.png

單數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

2、實施操做

①購入5塊共享存儲塊
②10個實例每兩個實例掛載一塊共享存儲,一共5塊,採用nfs
③之前備份用了16T的共享存儲塊依舊作備份
④更改res靜態目錄,將2T中靜態資源對拷入新存儲塊路徑中,node1和node2節點的靜態數據導入新塊存儲,將node3和node4的靜態數據導入新塊存儲,將node5和node6的靜態數據導入新塊存儲,每兩個節點數據導入一新塊,以此類推
⑤確認新數據同步到5塊存儲後開始實施更新
⑥將nginx中靜態根路徑更改成新res路徑,更改中心配置config項目中resource項目的目錄參數爲新res路徑
⑦逐調權重爲0,重啓項目平滑升級,重載nginx使得新路徑生效
⑧確認項目輸出日誌是否異常
⑨測試功能上傳與訪問
⑩恢復權重,更改fstab,與備份塊rsync+sersync路徑

3、發生的問題

①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

4、解決問題

①問題一的解決:運維過程當中,發生漏配,誤配的問題,必定是自動化統一運維沒有作到位。以後的架構運維中採用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命令。在使用它時,請明知它會帶來的後果

相關文章
相關標籤/搜索