备份
1. 只有在有信心能在紧急情况下完成迅速部署的情况下,备份才是有用的。所以,无论选择了哪种备份技术,一定要对备份及恢复备份的操作进行练习,知道了然于心。
2. 通常情况下,应对副本集的非主节点(与主节点相对)进行备份。
3. 对服务器进行备份
1). 文件系统快照:使用快照备份需要开启日记系统。该方法无需其他准备,只需生成快照即可,时间不限。
如果是对正在运行的系统生成快照,那么快照的数据内容本质让相当于使用kill -9 命令强制终止后的数据内容。因此,mongod在启动时会对日志文件进行重放,然后开始正常运行。
2). 复制数据文件:
方法一:
a. 锁定数据库,禁止任何写入,并进行同步(fsync),即将所有脏页面刷新至硬盘,以确保数据目录中的文件是最新的,且不会被更改。db.fsyncLock()
b. 当fsynclock命令返回命令行后,复制数据目录中的所有文件到备份位置。在Linux中,可使用以下命令等:cp -R /data/db/* /mnt/external-drive/backup
c. 数据复制完成后,解锁数据库,使其能够再次进行写入操作:db.fsyncUnlock()
注意,身份验证和fsynclock命令存在一些锁定问题。如果启用了身份验证,则在调用fsyncLock()和fsyncUnlock()期间不要关闭shell。如果在这期间断开了连接,则可能无法进行重连,并不得不重启mongod。
fsyncLock()的设定在重启后不会保持生效,mongod总是以非锁定模式启动。
方法二:
关闭mongod,复制文件,然后重启mongod。
3). 恢复数据目录备份:保证mongod没有在运行,且所有待恢复的目录为空。将备份的数据文件复制到数据目录,然后重新启动mongod。只要知道要复制哪些文件,即可使用这种方式备份单独的数据库。
4). 使用mongodump : 优点:可以备份单独的数据库、集合甚至集合中的子集 缺点:备份和恢复速度慢,在处理副本集时存在一些问题。
如果要在同一台机器上运行mongod和mongodump,只需指定mongod运行时占用的端口即可:mongodump -p 31000 mongodump会在当前目录建立一个转储目录。
在任何集合中,如果存在除_id 以外的其他唯一索引,则应该拒绝使用mongodump和mongorestore进行备份。
4. 对副本集进行备份:通常,应该对备份节点进行备份。这会为主节点减轻负担,也可以在不影响应用的情况下锁定备份节点(只要应用不向备份节点发送读取请求)。
可使用之前提到过的是那种方式中的一种,对副本集中的成员进行备份,但推荐使用文件系统快照或复制数据文件的方式。这两种方式无需做任何修改。
5. 对分片集群进行备份:在面对分片集群时,我们更关注分块的备份,即单独备份配置服务器和副本集。在对分片集群进行备份和恢复操作前,应先关闭均衡器。这是因为在过于混乱的环境中无法得到一份前后一致的快照。
1). 备份和恢复整个集群(不推荐):
2). 备份和恢复单独的分片:更多时候,只需要恢复集群中的某个单独分片。如果不是很挑剔的话,可使用刚刚在前面提到单独服务器的处理方法进行备份恢复。
6. 使用mongooplog进行增量备份:我们只需要进行一次备份,然后使用oplog来备份这之后的所有操作。这种技术比之前体积的技术都要复杂,因此除非确实需要,否则应尽量选择其他技术。
部署MongoDB
1. 设计系统结构
1). 选择存储介质:如果只考虑性能,应按一下顺序进行选择:内存,固态硬盘,机械磁盘。
a. 由于条件限制,一般标准的部署方案是使用较少的内存空间和较大的机械盘空间。这种情况下需注意,工作集大小应小于内存容量,同时应做好在工作集增长时进行设备扩展的准备。
b. 即使更快的机械硬盘,也不会使硬盘读取时间缩短太多,所以没有必要花太多时间在这种磁盘上。更多的内存和固态硬盘效果更好。
c. 通常我们不能向已有的副本集中添加固态硬盘,如果副本集中存在机械硬盘的话。如果使用固态硬盘的机器成为主成员,并接管处理它所能处理的一切工作,则其他成员受速度所限,无法及时复制数据,
从而被落在后面。因此,如果要引入固态硬盘的话,向集群中增加一个新的分片不失为一种更好的选择。
d. 可以考虑用机械硬盘来记录日志,而用固态硬盘记录数据。
2). 推荐的RAID配置
a. RAID: 独立磁盘冗余阵列,旧称廉价磁盘冗余阵列,是一种可以让我们把多块磁盘当做单独一个块磁盘来使用的技术。可以使用它来提高磁盘的可靠性或性能,或二者兼有。
一组使用RAID技术的磁盘被称为RAID磁盘阵列。
b. RAID10:数据被分割以提升速度,又被复制镜像以提高可靠性。
3). CPU: MongoDB对于CPU的负载很轻。如需在内存和CPU间选择一个进行硬件投资,一定要选内存。如需在速度和核数间做出选择,应选择前者。相比更多的并行运算,MongoDB能更好地利用
单处理器上的更多周期进行运算。
4). 选择操作系统:64位Linux操作系统是运行在MongoDB的最好选择。ContOS和RedHat企业版可能是最普遍的选择。应使用最新发布的稳定版本,因为老旧的、存在缺陷的软件包或内核有时会产生问题。
5). 交换空间:应分配一小块交换空间,以防止系统内存使用过多,从而导致内核终止MongoDB的运行。然后,MongoDB通常并不会使用任何交换空间。
MongoDB所使用的大部分内存都是"不稳定的":只要系统因某些原因而请求内存空间,这部分内存中的内存就会被刷新到磁盘中,然后元内存则被替换成其他内容。因此,书库数据绝不应该被写入交换空间,
因为它首先会被刷新磁盘。然而,MongoDB在需要对数据进行排序,即建立索引或进行排序操作时,会使用操作空间。在进行此类操作时,MongoDB会尽量不去使用过多内存,但如果同时进行很多这种操作,
最终会使用到交换空间。如果应用程序在服务器上用到了交换空间,则应想办法重新设计应用程序,或者减少那台服务器上的负载。
5). 文件系统:在linux系统上,推荐使用ext4或XFS文件系统作为数据卷。具有一个能够在备份时进行文件系统快照的文件系统是不错的,但是会影响到性能。尽量避免使用NFS文件系统。
2. 虚拟化:运用虚拟化技术可以方便地使用廉价的硬件来部署系统,并且能够迅速做出扩展。然后,虚拟化也存在缺点,尤其是无法预知的网络和磁盘IO状况。
1). 禁止内存过度分配:
a. 内存过度分片的设置决定了当前进程向操作系统请求过多内存时应采取的策略。基于这个设置,内核可能会为进程分配内存,哪怕那些内存当前是不可用的(期望的结果是,当前进程用到这段内存时
它变成可用的)。这种内核向进程许诺不存的内存行为,就叫做内存过度分配。这一特性使得MongoDB无法很好地运作。
将此值设为2所代表的
意义最为复杂,同时也是最佳选择。运行以下命令将此值设为2 : $echo 2 > /proc/sys/vm/overcommit_memory 更改这一设置后无需重启MongoDB
2). 神秘的内存:
3). 处理网络磁盘的IO问题
a. 不要将MongoDB托管在云端
b. 选择能够保证一定数量IOPS(IO Operations Per Second,每秒IO操作)的实例。
c. 监视MongoDB所使用的卷。一旦某个卷的速度变慢,立即终止这一实例的运行,接着启动一个使用另一个数据卷的实例。监控内容:IO利用率的峰值(MMS中的"IO延迟"),也缺失发生频率的峰值,TCP丢包增长情况,
MongoDB读写队列的峰值。
4). 使用非网络硬盘:临时驱动器是真正和虚拟机(VM)所在的机器键存在物理连接的磁盘,所以并不存在很多网络存储中出现的问题。这些磁盘是临时的,不能用来保存重要数据。
3. 系统配置:
1). 禁用NUMA:禁用每个CPU都访问内存中的所有内容。MongoDB 倾向于访问更多的数据,哪怕效率低,而非高效地访问一小部分数据。禁用NUMA是一个能够提升性能的魔法按钮,一定要按下它。它就像使用固态硬盘
一样,禁用NUMA可提升所有事物的性能。
a. 如果可能的话,应通过BIOS禁用来禁用NUMA。 例如,如果在使用grub,可在grub.cfg中添加numa=off选项:kernel /boot/vmlinuz-2.6.38-8-generic root=/dev/sda ro quiet numa=off
b. 如果系统无法在BIOS中禁用NUMA,则可在启动mongod时使用以下选项:$ numactl --interleave=all mongod [options] 将这一命令添加到所有使用的初始化脚本中。
c. 禁用zone-reclaim_mode选项,可以把该选项认为是超级NUMA,它会将内存中的内容来回移动到CPU的本地内容:$ echo 0 > /proc/sys/vm/zone_reclaim_mode ,无需重启mongod , 即可生效。
e. 启用NUMA后,主机上的MMS上会被显示为黄色。禁用NUMA后,会变为蓝色。
2). 更智能地预读取数据:预读是一种优化手段,即操作系统从磁盘中读取比实际请求更多的数据。这一优化的原理是:计算机所处理的大部分工作都是连续的,即如果载入一个视频文件的前20M内容,则接下来很可能需要
用到紧随其后的若干MB内容。于是,系统会从磁盘中读取比实际请求更多的内容,并将其放到内存中,以方便随后调用。
a. MongoDB并非是典型的工作负载,设置预读也是MongoDB系统中常见问题。MongoDB倾向于从磁盘中随机读取很多小块的数据,所以默认的系统设置并不能很好的运作。如果预读内容过多,内存中会逐渐充满
MongoDB没有请求的内容,迫使MongoDB更多的访问磁盘。
b. 使用blockdev命令,可查看当前的预读设定
c. 可以通过--setra 选项更改预读大小设置:$ sduo blockdev --setra 16 /dev/sdb3 推荐值是16到256之间。
预读大小不应设得过小,否则读取一个单独的文件则需要多次访问磁盘。如文旦过较大(大于1M),则应考虑预读更多的内容。如果文档较小,预读的数值则应小一些,例如32。即使文档非常小,也不要将预读大小的值
设为16以下。这会导致读取索引信息时效率低下。
d. 需要重启MongoDB才能使预读设置生效。这是因为进程会在启动时复制一份预读大小的设置值,并一直按照该值运作,直到进程停止运行。
3). 禁用大内存页面:MongoDB需载入数量众多小块内存,所以启用大页面会导致更多的磁盘IO。
4). 选择一种磁盘调度算法:磁盘控制器从操作系统接收到请求后,会使用一种调度算法来决定处理这些请求的顺序。有时改变这一算法可提高磁盘性能。
在使用固态硬盘或者使用RAID控制器进行缓存时,应使用noop调度算法。
可在启动配置中使用--elevator选项来更改调度算法。很多时候调度算法都能很好的运作,差别不大。
5). 不要记录访问时间:系统默认记录文件最后访问时间。Mongod操作频繁,禁用这一操作,会得到性能上的提升。在linux系统中,可以在/etc/fstab里将atime更改为noatime,已禁止记录访问时间。
6). 修改限制:MongoDB可能会受到两个限制的影响:进程可建立线程的数量和进程能够打开文件描述符(file descriptor)的数量。二者都应该被设置为无限制。
4. 网络配置
5. 系统管理:
1). 时钟同步:一般来讲,各系统的时钟误差不超过一秒最为安全。
2). OOM Killer : 如果MongoDB进程突然被终止,而日志中又没有出现错误或退出信息,则应检查/var/log/message(或内核记录这些内容的其他位置,查看是否存在关于终止mongod进程的信息。
当系统没有交换空间,并且可用内存开始减少时,OOM Killer就会变得尤为敏感,因此为了避免麻烦,不妨配置适当的交换空间。MongoDB应不会用到该交换空间,但这可让OOM Killer放松下来。
如果OOM killer终止了一个mongos进程,重启它即可。
3). 关闭定期任务:检查是否存在计划任务或后台进程,它们可能定期被激活并消耗系统资源,比如软件包管理器的自动更新。这些程序被激活后会消耗大量的内存和CPU资源,然后又消失不见。我们不会
希望在生产服务器上见到这些东西。
设置交换空间的方法步骤:
1、创建swapfile:
root权限下,创建swapfile,假设当前目录为"/",执行如下命令:
# dd if=/dev/zero of=swapfile bs=1024 count=500000
则在根目录下创建了一个swapfile,名称为“swapfile”,大小为500M,也可以把文件输出到自己想要的任何目录中,个人觉得还是直接放在根目录下比较好,www.linuxidc.com一目了然,不容易误破坏,放在其他目录下则不然了;
命令中选项解释:
---of:输出的交换文件的路径及名称;
---bs:块大小,单位byte,一般为1k即1024个byte;
---count:总块数即空间总大小,单位为块即k;
---if:读取的源空闲空间,为什么是zero,不清楚,先固定这么写吧;
2、将swapfile设置为swap空间
# mkswap swapfile
3、启用交换空间,这个操作有点类似于mount操作(个人理解):
# swapon swapfile
至此增加交换空间的操作结束了,可以使用free命令查看swap空间大小是否发生变化;
4、如果不再使用空间可以选择关闭交换空间,这个操作有点类似于umount操作(个人理解)::
# swapoff swapfile
使用这种方法在每次系统启动时都需要手动设置、开启swapfile,比较麻烦,解决方法:
在 /etc/rc.d/rc.local 文件的末行下追加加以下内容:(编辑这个文件当然是用vi了~)
/sbin/swapon /swapfile
保存后退出,这样在系统启动后,swap空间就会自动加载了;
总结:在安装OS时一定要规划后swap大小,通常为内存的2倍,但是要考虑到以后增加内存的可能,所以可以考虑设的稍大一些,不过在我们目前普遍使用的i386 PC机上,最大也不能超过2G。