高可用的MongoDB集群

 

1.序言

  MongoDB 是一个可扩展的高性能,开源,模式自由,面向文档的数据库。 它使用 C++编写。MongoDB 包含一下特点:

  • l  面向集合的存储:适合存储对象及JSON形式的数据。

  • l  动态查询:Mongo 支持丰富的查询方式,查询指令使用 JSON 形式的标记,可轻易查询文档中内嵌的对象及数组。

  • l  完整的索引支持:包括文档内嵌对象及数组。Mongo 的查询优化器会分析查询表达式,并生成一个高效的查询计划。

  • l  查询监视:Mongo包含一个监控工具用于分析数据库操作性能。

  • l  复制及自动故障转移:Mongo 数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目的是提供冗余及自动故障转移。

  • l  高效的传统存储方式:支持二进制数据及大型对象(如:照片或图片)。

  • l  自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。

2.背景

  MongoDB 的主要目标是在键值对存储方式(提供了高性能和高度伸缩性) 以及传统的 RDBMS(关系性数据库)系统,集两者的优势于一身。Mongo 使用 一下场景:

  • l  网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • l  缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由 Mongo 搭建的持久化缓存可以避免下层的数据源过载。
  • l  大尺寸,低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
  • l  高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库
  • l  用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档格式化的存储及查询。

  注:这里需要说明下,本文旨在介绍高可用的 MongoDB 集群;这里不讨论 Hadoop 平台的 HDFS。可根据公司实际业务需求,选择合适的存储系统。

  当然 MongDB 也有不适合的场景:

  • l  高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复制事物的应用程序。

  • l  传统的商业智能应用:针对特定问题的 BI 数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能时更适合的选择(如Hadoop套件中的Hive)。

  • l  需要SQL的问题。

3.搭建

3.1环境准备

  在 Mongo 的官网下载 Linux 版本安装包,然后解压到对应的目录下;由于资源有限,我们采用 Replica Sets + Sharding 方式来配置高可用。结构图如下所示:

  这里我说明下这个图所表达的意思。

  • l Shard服务器:使用Replica Sets确保每个数据节点都具有备份、自动容错转移、自动恢复的能力。
  • l  配置服务器:使用使用3个配置服务器确保元数据完整性。

  • l  路由进程:使用3个路由进程实现平衡,提高客户端接入性能

  • l  3 个分片进程:Shard11,Shard12,Shard13 组成一个副本集,提供Sharding 中 shard1 的功能。

  • l  3 个分片进程:Shard21,Shard22,Shard23 组成一个副本集,提供Sharding 中 Shard2 的功能。

  • l  3个配置服务器进程和3个路由器进程。

  构建一个 mongoDB Sharding Cluster 需要三种角色:shard 服务器(ShardServer)、配置服务器(config Server)、路由进程(Route Process)

  Shard 服务器

  shard 服务器即存储实际数据的分片,每个 shard 可以是一个 mongod 实例, 也可以是一组 mongod 实例构成的 Replica Sets.为了实现每个 Shard 内部的故障 自动转换,MongoDB 官方建议每个 shard 为一组 Replica Sets.
  配置服务器

  为了将一个特定的 collection 存储在多个 shard 中,需要为该 collection 指定 一个 shard key,决定该条记录属于哪个 chunk,配置服务器可以存储以下信息, 每个shard节点的配置信息,每个chunk的shard key范围,chunk在各shard 的分布情况,集群中所有 DB 和 collection 的 sharding 配置信息。
  路由进程

  它是一个前段路由,客户端由此接入,首先询问配置服务器需要到哪个 shard 上查询或保存记录,然后连接相应的 shard 执行操作,最后将结果返回给客户端,客 户端只需要将原本发给 mongod 的查询或更新请求原封不动地发给路由进程,而 不必关心所操作的记录存储在哪个 shard 上。

按照架构图,理论上是需要 16 台机器的,由于资源有限,用目录来替代物理机(有风险,若其中某台机器宕机,配置在该机器的服务都会 down 掉),下面给出配置表格:

服务器

Host

服务和端口

1

10.211.55.28

Shard11:10011 Shard21:10021 ConfigSvr:10031 Mongos:10040

2

10.211.55.28

Shard12:10012 Shard22:10022 ConfigSvr:10032 Mongos:10042

3

10.211.55.28

Shard13:10013 Shard23:10023 ConfigSvr:10033 Mongos:10043

3.2.环境变量

  下面给出 MongoDB 的环境变量配置,输入命令并配置:

[root@mongo ~]# vi /etc/profile
export MONGO_HOME=/root/mongodb-linux-x86_64-2.6.7
export PATH=$PATH:$MONGO_HOME/bin

  然后保存退出,输入以下命令配置文件立即生效:

[root@mongo ~]# . /etc/profile

3.3.配置 Shard+Replica Sets

  我们分别启动 Shard1 的所有进程,并设置副本集为:shard1。下面给出启动 Shard1 的脚本文件。

  • l shard11.conf
dbpath=/mongodb/data/shard11 
logpath=/mongodb/log/shard11.log
pidfilepath=/mongodb/pid/shard11.pid
directoryperdb=true
logappend=true
replSet=shard1
port=10011
fork=true
shardsvr=true
journal=true
  • l shard12.conf
dbpath=/mongodb/data/shard12 
logpath=/mongodb/log/shard12.log
pidfilepath=/mongodb/pid/shard12.pid
directoryperdb=true
logappend=true
replSet=shard1
port=10012
fork=true
shardsvr=true
journal=true
  • l shard13.conf
dbpath=/mongodb/data/shard13
logpath=/mongodb/log/shard13.log
pidfilepath=/mongodb/pid/shard13.pid
directoryperdb=true
logappend=true
replSet=shard1
port=10013
fork=true
shardsvr=true
journal=true
  • l shard21.conf
dbpath=/mongodb/data/shard21
logpath=/mongodb/log/shard21.log
pidfilepath=/mongodb/pid/shard21.pid
directoryperdb=true
logappend=true
replSet=shard2
port=10021
fork=true
shardsvr=true
journal=true
  • l shard22.conf
dbpath=/mongodb/data/shard22
logpath=/mongodb/log/shard22.log
pidfilepath=/mongodb/pid/shard22.pid
directoryperdb=true
logappend=true
replSet=shard2
port=10022
fork=true
shardsvr=true
journal=true
  • l shard23.conf
dbpath=/mongodb/data/shard23
logpath=/mongodb/log/shard23.log
pidfilepath=/mongodb/pid/shard23.pid
directoryperdb=true
logappend=true
replSet=shard2
port=10023
fork=true
shardsvr=true
journal=true
  • l config1.conf
dbpath=/mongodb/config/config1 
logpath=/mongodb/log/config1.log
pidfilepath=/mongodb/pid/config1.pid
directoryperdb=true
logappend=true
port=10031
fork=true
configsvr=true
journal=true
  • l config2.conf
dbpath=/mongodb/config/config2
logpath=/mongodb/log/config2.log
pidfilepath=/mongodb/pid/config2.pid
directoryperdb=true
logappend=true
port=10032
fork=true
configsvr=true
journal=true
  • l config3.conf
dbpath=/mongodb/config/config3
logpath=/mongodb/log/config3.log
pidfilepath=/mongodb/pid/config3.pid
directoryperdb=true
logappend=true
port=10033
fork=true
configsvr=true
journal=true
  • route.conf
configdb=mongo:10031,mongo:10032,mongo:10033 
pidfilepath=/mongodb/pid/route.pid
port=10040
chunkSize=1
logpath=/mongodb/log/route.log
logappend=true
fork=true
  • route2.conf
configdb=mongo:10031,mongo:10032,mongo:10033
pidfilepath=/mongodb/pid/route.pid
port=10042
chunkSize=1
logpath=/mongodb/log/route2.log
logappend=true
fork=true
  • route3.conf
configdb=mongo:10031,mongo:10032,mongo:10033
pidfilepath=/mongodb/pid/route3.pid
port=10043
chunkSize=1
logpath=/mongodb/log/route3.log
logappend=true
fork=true

  注:配置文件中的目录必须存在,不存在需创建。

3.4.启动批处理

  下面给出启动批处理的脚本,内容如下:

mongod -f /etc/shard11.conf
mongod -f /etc/shard12.conf
mongod -f /etc/shard13.conf
mongod -f /etc/shard21.conf
mongod -f /etc/shard22.conf
mongod -f /etc/shard23.conf
mongod -f /etc/config1.conf
mongod -f /etc/config2.conf
mongod -f /etc/config3.conf
mongos -f /etc/route.conf
mongos -f /etc/route2.conf
mongos -f /etc/route3.conf 

3.5.参数说明

dbpath:数据存放目录
logpath:日志存放路径 logappend:以追加的方式记录日志
replSet:replica set 的名字
port:mongodb 进程所使用的端口号,默认为 27017 fork:以后台方式运行进程

journal:写日志
smallfiles:当提示空间不够时添加此参数
其他参数
pidfilepath:进程文件,方便停止 mongodb directoryperdb:为每一个数据库按照数据库名建立文件夹存放 bind_ip:mongodb 所绑定的 ip 地址
oplogSize:mongodb 操作日志文件的最大大小。单位为 Mb,默认为硬盘剩余 空间的 5%
noprealloc:不预先分配存储
shardsvr:分片
configsvr:配置服务节点
configdb:配置 config 节点到 route 节点

3.6.配置分片的表和片键

  首先,我们需要登录到路由节点,这里我们登录到其中一个 10040 端口下的节点。输入如下命令:

mongo mongo:10040
use admin
db.runCommand({addshard:"shard1/mongo:10011,mongo:10012,mongo:10013"})
db.runCommand({addshard:"shard2/mongo:10021,mongo:10022,mongo:10023"})
db.runCommand({ listshards:1 }) #列出 shard 个数
db.runCommand({enablesharding:"friends"}); #创建 friends 库
db.runCommand( { shardcollection : "friends.user",key : {id: 1},unique : true } ) # 使用 user 表来做分片,片键为 id 且唯一

3.7.验证

  至此,整个集群的搭建完成,下面我们测试集群的高可用性。下面给出截图:

  首先是查看集群的状态图 :

  可以看到,集群中存有数据,这是我之前为了测试存的数据,注意,Mongo 只有数据达到一定量才会分片,所有我插入的数据比较大,每次测试都是 10w 的记录插入。

  下面,我 kill 掉 shard11 服务,看会发生什么情况?截图如下:

  这里我已经 kill 了 shard11 的进程服务。接下来,我们在 10040 端口的路由 节点输入:db.user.stats()查看状态,显示运行正常。截图如下所示:

  同样可以在该路由节点插入 10w 条记录,看是否成功,下面给出插入脚本, 内容如下:

for(var i=1;i<=100000;i++)db.user.save({id:i,value1:"1234567890",value2:"1234567890",value3:"123 4567890",value4:"1234567890"});

4.总结

  这片文章就分享到这里,若在研究的过程中有什么问题可以加群讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

联系方式: 
邮箱:smartdengjie@gmail.com 
QQ群(董的博客):306184597

热爱生活,享受编程,与君共勉!

 
分类: MongoDB

MongoDB集群的更多相关文章

  1. MongoDB集群卡死问题

    一年前搭了个MongoDB集群,跑得还算不错,但是有几次遇到过服务卡死的问题.处理起来已经得心应手了,拿来跟大家分享一下: 故障现象: 业务查询缓慢,而且会有连接异常: { "serverU ...

  2. mongodb集群安装及到现在遇到的一些问题

    集群搭建 只有3台服务器,开始搭建mongodb集群里主要参照的是http://www.lanceyan.com/tech/arch/mongodb_shard1.html,端口的设置也是mongos ...

  3. 搭建高可用mongodb集群(四)—— 分片(经典)

    转自:http://www.lanceyan.com/tech/arch/mongodb_shard1.html 按照上一节中<搭建高可用mongodb集群(三)-- 深入副本集>搭建后还 ...

  4. [转]搭建高可用mongodb集群(四)—— 分片

    按照上一节中<搭建高可用mongodb集群(三)—— 深入副本集>搭建后还有两个问题没有解决: 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大? 数据压力大到机器支撑不了的 ...

  5. [转]搭建高可用mongodb集群(二)—— 副本集

    在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...

  6. 搭建高可用mongodb集群(四)—— 分片

    按照上一节中<搭建高可用mongodb集群(三)—— 深入副本集>搭建后还有两个问题没有解决: 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大? 数据压力大到机器支撑不了的 ...

  7. 搭建高可用mongodb集群(三)—— 深入副本集内部机制

    在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...

  8. 搭建高可用mongodb集群(二)—— 副本集

    在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...

  9. 搭建高可用mongodb集群(一)——配置mongodb

    在大数据的时代,传统的关系型数据库要能更高的服务必须要解决高并发读写.海量数据高效存储.高可扩展性和高可用性这些难题.不过就是因为这些问题Nosql诞生了. NOSQL有这些优势: 大数据量,可以通过 ...

  10. MongoDB集群架构及搭建

    MongoDB分布式集群 MongDB分布式集群能够对数据进行备份,提高数据安全性,以及提高集群提高读写服务的能力和数据存储能力.主要通过副本集(replica)对数据进行备份,通过分片(shardi ...

随机推荐

  1. Ribbon 和 Eureka 积分

            Ribbon 这是 Netflix 云服务的中间层宣布开放源代码项目,它的主要功能是提供客户机端软件的负载均衡算法,将 Netflix 中间层服务一起. Eureka 是 RESTfu ...

  2. unity3d 各功能的运行秩序,打回来,订购,的次数

    Update 当MonoBehaviour启用时,其Update在每一帧被调用. 仅调用一次(每帧) LateUpdate 当Behaviour启用时,  每帧调用一次: FixedUpdate 当M ...

  3. File类基本操作之OutputStream字节输出流

    贴代码了,已经測试,可正常编译 package org.mark.streamRW; import java.io.File; import java.io.FileOutputStream; imp ...

  4. HDU 3032 Nim or not Nim? (需求的游戏SG功能)

    意甲冠军:经典Nim游戏转换,给你n礧pi,每个堆栈有pi石头, Alice和Bob轮流石头,意一堆中拿走随意个石子,也能够将某一堆石子分成两个小堆 (每堆石子个数必须不能为0).先拿完者获胜 思路: ...

  5. 我的第一次windows规划

    #include <windows.h>   LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //WinMain功能被分配一 ...

  6. MapXtreme DJ最短路径算法 全路径搜索算法

    包括最短路径,全路径搜索算法演示程序请在http://pan.baidu.com/s/1jG9gKMM#dir/path=%2F%E4%BA%A7%E5%93%81%2FDemos 找 ShortWa ...

  7. SQL Server审计功能入门:CDC(Change Data Capture)

    原文:SQL Server审计功能入门:CDC(Change Data Capture) 介绍 SQL Server 2008引入了CDC(Change Data Capture),它能记录: 1. ...

  8. VB6基本数据库应用(五):数据的查找与筛选

    同系列的第五篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/9633139 数据的查找与筛选 第4篇发布到现在已经过了4天,很抱歉,学 ...

  9. log4cpp日志不能是溶液子体积

     我们的项目用途log4cpp由于日志输出模块,但在使用中发现,假设Services,或者是在Windows Server版本号.不会有一个正常的日志切削现象.该日志已被写入到文件中,持续,即使超 ...

  10. 自动注册 IIS6 的 MIME 类型

    原文 自动注册 IIS6 的 MIME 类型 由于IIS5和IIS6有很多的MIME类型没有设置,其中还包括了FLV(video/x-flv),上篇文章描述了制作<IIS6 自动安装>,而 ...