Fundebug是这样备份数据的

摘要: 数据还是要备份的,万一删库了呢?

Fundebug是这样备份数据的

本文代码仓库: fundebug-mongodb-backup

引言

今年8月,腾讯云竟然把客户前沿数据的数据弄没了,Fundebug在第一时间进行了一些简单的技术分析:

一方面,腾讯云对这件事负有不可推卸的责任,他们刚开始说是什么硬盘固件版本bug(该声明已删),后来承认是人为操作失误导致的。
另一方面,前沿数据没有备份业务数据,也是一种非常不专业的行为,导致业务无法恢复,必须完全重新开始。

因此,所有的开发者都应该从这个事件吸取教训,不要偷懒,严格备份业务数据,否则数据一旦出问题,损失将无法挽回。

Fundebug数据备份方案

我们还分享了Fundebug的数据备份方案,供大家参考:

备份方案 时间粒度 细节
MongoDB复制集   实时   搭建3个节点(1个Primary和2个Secondary)的MongoDB复制集,实时同步数据。  
阿里云磁盘快照   每天   每天凌晨自动快照所有磁盘,包括系统盘和备份数据盘。  
mongodump导出核心数据   每天   每天凌晨将MongoDB核心数据导出到复制集之外的服务器磁盘(该磁盘会每天进行快照)。  
阿里云对象存储   每天   每天凌晨将mongodump导出的数据使用gpg非对称加密之后,上传到阿里云深圳数据中心的对象存储,设置跨区域复制,自动同步到杭州数据中心,每份数据保留1个月。  
本地硬盘备份   每周   每周六中午从阿里云对象存储下载加密的备份数据,存储到本地磁盘。  

大概是因为我们没有公布备份方案的技术细节,我们受到了质疑:

要么多重备份是假的

对于这种指责,我的原则是必须怼回去。那么,这篇博客我来详细介绍一下我们数据备份方案吧~所有源代码都在GitHub仓库Fundebug/fundebug-mongodb-backup,欢迎star。

MongoDB复制集

生产环境使用单节点的MongoDB数据库,除非访问量非常低或者不在乎服务可用性,否则基本上是不可能的,这辈子都不可能。单节点MongoDB存在单点故障(single point of failure),一旦挂了,整个应用就挂了。更糟糕的是,如果数据损坏,恢复将非常麻烦。

MongoDB有多种可能性会挂掉,最常见的就是高峰期内存使用量飙升,导致Linux的Out of Memory (OOM) killer将mongod进程杀死,这种情况Fundebug遇见过不少次,那我们是如何安全渡过的呢?答案是复制集(replica set)

复制集由多个MongoDB节点构成,它们的数据是实时同步的,因此数据几乎完全相同。当某个节点挂掉时,应用可以自动切换到其他节点,这样保证了服务的可用性。

Fundebug的MongoDB都运行在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" oplog

复制集一个非常重要的参数是oplog的大小,使用--oplogSize选项可以指定。我们设定的值是25600MB,即25GB。oplog(operation log)是复制集节点同步数据的关键,Primary节点将数据库写操作记录到oplog中,Secondary节点从Primary节点处复制oplog并应用到本地数据库中。因此,oplog大小决定了Primary和Secondary节点可以接受的数据最大"时间差"。使用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小时的数据库写操作,假设复制集中某个节点由于宕机有4个小时没有同步数据,则重启该节点也无法与其他节点同步了!这时会出现"too stale to catch up -- entering maintenance mode"的错误,只能手动同步数据。

因此,我们建议oplog的值应该尽量设大一些,否则以后修改oplog的步骤挺麻烦的。事实上,25GB的oplog大小对于Fundebug的MongoDB复制集来说已经不够了,我们需要修改。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjgfx.html