摘要: 數(shù)據(jù)還是要備份的,萬(wàn)一刪庫(kù)了呢?
我們一直強(qiáng)調(diào)成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站對(duì)于企業(yè)的重要性,如果您也覺(jué)得重要,那么就需要我們慎重對(duì)待,選擇一個(gè)安全靠譜的網(wǎng)站建設(shè)公司,企業(yè)網(wǎng)站我們建議是要么不做,要么就做好,讓網(wǎng)站能真正成為企業(yè)發(fā)展過(guò)程中的有力推手。專業(yè)網(wǎng)站建設(shè)公司不一定是大公司,成都創(chuàng)新互聯(lián)作為專業(yè)的網(wǎng)絡(luò)公司選擇我們就是放心。今年8月,騰訊云竟然把客戶前沿?cái)?shù)據(jù)的數(shù)據(jù)弄沒(méi)了,F(xiàn)undebug在第一時(shí)間進(jìn)行了一些簡(jiǎn)單的技術(shù)分析:
一方面,騰訊云對(duì)這件事負(fù)有不可推卸的責(zé)任,他們剛開(kāi)始說(shuō)是什么硬盤(pán)固件版本bug(該聲明已刪),后來(lái)承認(rèn)是人為操作失誤導(dǎo)致的。
另一方面,前沿?cái)?shù)據(jù)沒(méi)有備份業(yè)務(wù)數(shù)據(jù),也是一種非常不專業(yè)的行為,導(dǎo)致業(yè)務(wù)無(wú)法恢復(fù),必須完全重新開(kāi)始。
因此,所有的開(kāi)發(fā)者都應(yīng)該從這個(gè)事件吸取教訓(xùn),不要偷懶,嚴(yán)格備份業(yè)務(wù)數(shù)據(jù),否則數(shù)據(jù)一旦出問(wèn)題,損失將無(wú)法挽回。
我們還分享了Fundebug的數(shù)據(jù)備份方案,供大家參考:
備份方案 | 時(shí)間粒度 | 細(xì)節(jié) |
---|---|---|
MongoDB復(fù)制集 | 實(shí)時(shí) | 搭建3個(gè)節(jié)點(diǎn)(1個(gè)Primary和2個(gè)Secondary)的MongoDB復(fù)制集,實(shí)時(shí)同步數(shù)據(jù)。 |
阿里云磁盤(pán)快照 | 每天 | 每天凌晨自動(dòng)快照所有磁盤(pán),包括系統(tǒng)盤(pán)和備份數(shù)據(jù)盤(pán)。 |
mongodump導(dǎo)出核心數(shù)據(jù) | 每天 | 每天凌晨將MongoDB核心數(shù)據(jù)導(dǎo)出到復(fù)制集之外的服務(wù)器磁盤(pán)(該磁盤(pán)會(huì)每天進(jìn)行快照)。 |
阿里云對(duì)象存儲(chǔ) | 每天 | 每天凌晨將mongodump導(dǎo)出的數(shù)據(jù)使用gpg非對(duì)稱加密之后,上傳到阿里云深圳數(shù)據(jù)中心的對(duì)象存儲(chǔ),設(shè)置跨區(qū)域復(fù)制,自動(dòng)同步到杭州數(shù)據(jù)中心,每份數(shù)據(jù)保留1個(gè)月。 |
本地硬盤(pán)備份 | 每周 | 每周六中午從阿里云對(duì)象存儲(chǔ)下載加密的備份數(shù)據(jù),存儲(chǔ)到本地磁盤(pán)。 |
大概是因?yàn)槲覀儧](méi)有公布備份方案的技術(shù)細(xì)節(jié),我們受到了質(zhì)疑:
要么多重備份是假的
對(duì)于這種指責(zé),我的原則是必須懟回去。那么,這篇博客我來(lái)詳細(xì)介紹一下我們數(shù)據(jù)備份方案吧~所有源代碼都在GitHub倉(cāng)庫(kù)Fundebug/fundebug-mongodb-backup,歡迎star。
生產(chǎn)環(huán)境使用單節(jié)點(diǎn)的MongoDB數(shù)據(jù)庫(kù),除非訪問(wèn)量非常低或者不在乎服務(wù)可用性,否則基本上是不可能的,這輩子都不可能。單節(jié)點(diǎn)MongoDB存在單點(diǎn)故障(single point of failure),一旦掛了,整個(gè)應(yīng)用就掛了。更糟糕的是,如果數(shù)據(jù)損壞,恢復(fù)將非常麻煩。
MongoDB有多種可能性會(huì)掛掉,最常見(jiàn)的就是高峰期內(nèi)存使用量飆升,導(dǎo)致Linux的Out of Memory (OOM) killer將mongod進(jìn)程殺死,這種情況Fundebug遇見(jiàn)過(guò)不少次,那我們是如何安全渡過(guò)的呢?答案是復(fù)制集(replica set)。
復(fù)制集由多個(gè)MongoDB節(jié)點(diǎn)構(gòu)成,它們的數(shù)據(jù)是實(shí)時(shí)同步的,因此數(shù)據(jù)幾乎完全相同。當(dāng)某個(gè)節(jié)點(diǎn)掛掉時(shí),應(yīng)用可以自動(dòng)切換到其他節(jié)點(diǎn),這樣保證了服務(wù)的可用性。
Fundebug的MongoDB都運(yùn)行在Docker容器中,其Docker Compose配置文件如下:
version: '2.2'
services:
mongo:
image: mongo:3.2
network_mode: "host"
restart: always
cpus: 7
mem_limit: 30g
command: --replSet rs0 --oplogSize 25600
volumes:
- /mongodb/data:/data/db
logging:
driver: "json-file"
options:
max-size: "5g"
復(fù)制集一個(gè)非常重要的參數(shù)是oplog的大小,使用--oplogSize選項(xiàng)可以指定。我們?cè)O(shè)定的值是25600MB,即25GB。oplog(operation log)是復(fù)制集節(jié)點(diǎn)同步數(shù)據(jù)的關(guān)鍵,Primary節(jié)點(diǎn)將數(shù)據(jù)庫(kù)寫(xiě)操作記錄到oplog中,Secondary節(jié)點(diǎn)從Primary節(jié)點(diǎn)處復(fù)制oplog并應(yīng)用到本地?cái)?shù)據(jù)庫(kù)中。因此,oplog大小決定了Primary和Secondary節(jié)點(diǎn)可以接受的數(shù)據(jù)大"時(shí)間差"。使用rs.printReplicationInfo()可以查看oplog信息:
rs.printReplicationInfo()
configured oplog size: 25600MB
log length start to end: 11409secs (3.17hrs)
oplog first event time: Sat Sep 22 2018 12:02:04 GMT+0800 (CST)
oplog last event time: Sat Sep 22 2018 15:12:13 GMT+0800 (CST)
now: Sat Sep 22 2018 15:12:13 GMT+0800 (CST)
可知oplog中記錄了最近3.17小時(shí)的數(shù)據(jù)庫(kù)寫(xiě)操作,假設(shè)復(fù)制集中某個(gè)節(jié)點(diǎn)由于宕機(jī)有4個(gè)小時(shí)沒(méi)有同步數(shù)據(jù),則重啟該節(jié)點(diǎn)也無(wú)法與其他節(jié)點(diǎn)同步了!這時(shí)會(huì)出現(xiàn)"too stale to catch up -- entering maintenance mode"的錯(cuò)誤,只能手動(dòng)同步數(shù)據(jù)。
因此,我們建議oplog的值應(yīng)該盡量設(shè)大一些,否則以后修改oplog的步驟挺麻煩的。事實(shí)上,25GB的oplog大小對(duì)于Fundebug的MongoDB復(fù)制集來(lái)說(shuō)已經(jīng)不夠了,我們需要修改。
Fundebug的MongoDB復(fù)制集由1個(gè)Primary節(jié)點(diǎn)和2個(gè)Secondary節(jié)點(diǎn)構(gòu)成,為保證我們服務(wù)可用性發(fā)揮了非常關(guān)鍵的作用!我之后所介紹的備份方案都是冗余措施,我們從來(lái)沒(méi)有真正使用過(guò)那些備份數(shù)據(jù),而復(fù)制集"拯救"了我們不少次,強(qiáng)烈建議大家都配置一下。
關(guān)于MongoDB復(fù)制集的更多技術(shù)細(xì)節(jié),以后我再單獨(dú)詳述,歡迎關(guān)注Fundebug微信公眾號(hào)。
快照能夠保留某一時(shí)間點(diǎn)的磁盤(pán)數(shù)據(jù)狀態(tài),因此可以作為一種數(shù)據(jù)備份方式。很簡(jiǎn)單,配置一下自動(dòng)快照策略就好了:
我備份了系統(tǒng)盤(pán),萬(wàn)一數(shù)據(jù)丟失比如被刪庫(kù),至少還能回滾磁盤(pán)。每周快照1次,保存7天。因?yàn)榉?wù)全部運(yùn)行在Docker里面,服務(wù)器本身基本上沒(méi)有什么配置,備份的需求不大,實(shí)際上我們也從來(lái)沒(méi)有回滾過(guò)磁盤(pán)。
另外,我沒(méi)有對(duì)MongoDB數(shù)據(jù)盤(pán)直接進(jìn)行快照,因?yàn)榘l(fā)現(xiàn)快照后的數(shù)據(jù)無(wú)法恢復(fù)(這一點(diǎn)有待進(jìn)一步確認(rèn))。
我只是將mongodump導(dǎo)出的核心數(shù)據(jù)所在磁盤(pán)進(jìn)行了快照。每天快照1次,保存兩天。這樣做可以確保核心數(shù)據(jù)的安全性。
使用mongodump命令,可以全量導(dǎo)出MongoDB數(shù)據(jù)。對(duì)應(yīng)的,之后可以使用mongorestore命令將備份數(shù)據(jù)導(dǎo)入MongoDB。
導(dǎo)出數(shù)據(jù)的腳本dump-data.sh如下:
#!/bin/sh
# 刪除前一天導(dǎo)出的數(shù)據(jù)
rm -rf /data/mongodb_backup
DIR=`date +%Y%m%d%H%M`
OUT=/data/mongodb_backup/$DIR
mkdir -p $DEST
# 全量導(dǎo)出MongoDB數(shù)據(jù)(排除部分集合)
mongodump --host "rs0/192.168.59.11:27017,192.168.59.12:27017,192.168.59.13:27017" \
--db fundebug-production \
--excludeCollection events \
--out $OUT
使用--excludeCollection選項(xiàng),可以排除部分不需要備份的集合。例如,F(xiàn)undebug累計(jì)處理了6億+的錯(cuò)誤事件,存在event集合中,因?yàn)槲覀円呀?jīng)聚合過(guò)了,所以沒(méi)有必要備份,而且數(shù)據(jù)量太大,備份也不現(xiàn)實(shí)。
使用crontab腳本定期執(zhí)行dump-data.sh腳本:
# 每天凌晨4點(diǎn)導(dǎo)出數(shù)據(jù)
0 4 * * * /root/fundebug-mongodb-backup/dump-data.sh
使用mongodump導(dǎo)出的數(shù)據(jù)保存在測(cè)試服務(wù)器的數(shù)據(jù)磁盤(pán)上,從地域?qū)用嫔蟻?lái)說(shuō)都在同一個(gè)地方,即阿里云深圳數(shù)據(jù)中心。如果要做到異地備份,可以借助阿里云的對(duì)象存儲(chǔ)服務(wù)的跨區(qū)域復(fù)制功能,將備份數(shù)據(jù)自動(dòng)同步到阿里云杭州數(shù)據(jù)中心。
在上傳備份數(shù)據(jù)之前,使用gpg命令進(jìn)行非對(duì)稱加密,可以保證數(shù)據(jù)安全性。加密導(dǎo)出數(shù)據(jù)的腳本encrypt-data.sh腳本如下:
#!/bin/bash
DIR=`find /data/mongodb_backup/ -maxdepth 1 -type d ! -path /data/mongodb_backup/`
source=$DIR/fundebug-production
cd $source
# 將導(dǎo)出數(shù)據(jù)加密
for file in * ; do
gpg --batch --yes -v -e -r fundebug --output $source/$file.gpg --always-trust $file
done ;
除了加密,gpg還有一定的壓縮效果,這樣可以減少備份數(shù)據(jù)量,一舉兩得。關(guān)于gpg命令的細(xì)節(jié),可以查看參考博客。
使用阿里云提供的Node.js客戶端ali-oss,可以將加密之后的.gpg文件上傳到阿里云的對(duì)象存儲(chǔ)服務(wù)中。使用multipartUpload方法即可,upload.js部分代碼如下:
// 上傳單個(gè)文件
async function uploadFile(fileName, filePath) {
try {
const result = await store.multipartUpload(fileName, filePath, {
parallel: 4,
partSize: 1024 * 1024,
progress: function(p) {
logger.info("Progress: " + p);
}
});
if (result.res.statusCode === 200) {
logger.info(`upload file success! ${fileName}`);
} else {
const message = `upload file fail! ${fileName}`;
logger.error(message);
logger.error(result);
fundebug.notifyError(new Error(message), {
metaData: {
message: message,
result: result
}
});
}
} catch (error) {
const message = `upload file fail! ${fileName}`;
logger.error(message);
logger.error(error);
fundebug.notifyError(error, {
metaData: {
message: message,
error: error
}
});
}
}
代碼運(yùn)行在Docker容器中,使用curl命令訪問(wèn)HTTP接口/upload即可觸發(fā)執(zhí)行上傳操作,使用crontab定期執(zhí)行:
# 每天凌晨4點(diǎn)備份數(shù)據(jù)
0 4 * * * /root/mongodb-backup/dump-data.sh && /root/mongodb-backup/encrypt-data.sh && docker restart mongodb-backup && sleep 1m && curl http://127.0.0.1:9160/upload
備份數(shù)據(jù)通過(guò)數(shù)據(jù)卷(volume)映射到容器中,每天需要重啟容器,才能訪問(wèn)每天導(dǎo)出的新數(shù)據(jù)。
在阿里云上為備份數(shù)據(jù)的存儲(chǔ)空間配置跨區(qū)域復(fù)制,即可實(shí)現(xiàn)自動(dòng)異地備份,非常方便。其他對(duì)象存儲(chǔ)云服務(wù)應(yīng)該也支持這種功能吧。
前文提到的備份方式,其實(shí)都是在阿里云內(nèi)部COPY數(shù)據(jù)。那么問(wèn)題來(lái)了,阿里云掛了怎么辦?這種事情當(dāng)然基本上不可能發(fā)生,畢竟我們有多處備份,甚至實(shí)現(xiàn)了異地備份。
既然備份數(shù)據(jù)都上傳到阿里云對(duì)象存儲(chǔ)了,下載到本地也不是什么難事。使用ali-oss的list和get方法即可實(shí)現(xiàn),download.js部分代碼如下:
// 獲取當(dāng)天上傳到阿里OSS的文件列表
async function listFilesToDownload(day) {
const result = await store.list({ prefix: day });
return result.objects;
}
// 將阿里云OSS中的文件下載到本地
async function downloadFile(fileName, path) {
try {
const file = fileName.split("/")[1];
const filepath = `${path}/${file}`;
await store.get(fileName, filepath);
} catch (error) {
const message = `download file fail! ${fileName}`;
logger.error(message);
logger.error(error);
fundebug.notifyError(error, {
metaData: {
error: error,
message: message
}
});
}
}
代碼運(yùn)行在Docker容器中,部署在本地機(jī)器,使用curl命令訪問(wèn)HTTP接口/download即可觸發(fā)執(zhí)行下載操作,使用crontab定期執(zhí)行:
# 每周六中午從阿里云下載備份數(shù)據(jù)
0 12 * * 6 curl http://127.0.0.1:9160/download
本文提到的所有的數(shù)據(jù)備份方式完全自動(dòng)化執(zhí)行,沒(méi)有什么技術(shù)難度,成本也不高,可以極大提高數(shù)據(jù)安全性。
Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了8億+錯(cuò)誤事件,得到了Google、360、金山軟件等眾多知名用戶的認(rèn)可。歡迎免費(fèi)試用!
轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/09/27/how-does-fundebug-backup-data/
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
當(dāng)前題目:Fundebug是這樣備份數(shù)據(jù)的-創(chuàng)新互聯(lián)
本文地址:http://vcdvsql.cn/article28/iicjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、全網(wǎng)營(yíng)銷推廣、企業(yè)網(wǎng)站制作、云服務(wù)器、面包屑導(dǎo)航、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容