高可用的MongoDB集群部署实践.docx
《高可用的MongoDB集群部署实践.docx》由会员分享,可在线阅读,更多相关《高可用的MongoDB集群部署实践.docx(13页珍藏版)》请在冰豆网上搜索。
高可用的MongoDB集群部署实践
高可用的MongoDB集群
1.序言
MongoDB是一个可扩展的高性能,开源,模式自由,面向文档的数据库。
它使用C++编写。
MongoDB包含一下特点:
•面向集合的存储:
适合存储对象及JSON形式的数据。
l
•动态查询:
Mongo支持丰富的查询方式,查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
l
•完整的索引支持:
包括文档内嵌对象及数组。
Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
l
•查询监视:
Mongo包含一个监控工具用于分析数据库操作性能。
l
•复制及自动故障转移:
Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。
复制的主要目的是提供冗余及自动故障转移。
l
•高效的传统存储方式:
支持二进制数据及大型对象(如:
照片或图片)。
l
•自动分片以支持云级别的伸缩性:
自动分片功能支持水平的数据库集群,可动态添加额外的机器。
l
2.背景
MongoDB的主要目标是在键值对存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS(关系性数据库)系统,集两者的优势于一身。
Mongo使用一下场景:
•网站数据:
Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
l
•缓存:
由于性能很高,Mongo也适合作为信息基础设施的缓存层。
在系统重启之后,由Mongo搭建的持久化缓存可以避免下层的数据源过载。
l
•大尺寸,低价值的数据:
使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
l
•高伸缩性的场景:
Mongo非常适合由数十或数百台服务器组成的数据库l
•用于对象及JSON数据的存储:
Mongo的BSON数据格式非常适合文档格式化的存储及查询。
l
注:
这里需要说明下,本文旨在介绍高可用的MongoDB集群;这里不讨论Hadoop平台的HDFS。
可根据公司实际业务需求,选择合适的存储系统。
当然MongDB也有不适合的场景:
•高度事务性的系统:
例如银行或会计系统。
传统的关系型数据库目前还是更适用于需要大量原子性复制事物的应用程序。
l
•传统的商业智能应用:
针对特定问题的BI数据库会对产生高度优化的查询方式。
对于此类应用,数据仓库可能时更适合的选择(如Hadoop套件中的Hive)。
l
•需要SQL的问题。
l
3.搭建
3.1环境准备
在Mongo的官网下载Linux版本安装包,然后解压到对应的目录下;由于资源有限,我们采用ReplicaSets+Sharding方式来配置高可用。
结构图如下所示:
这里我说明下这个图所表达的意思。
•Shard服务器:
使用ReplicaSets确保每个数据节点都具有备份、自动容错转移、自动恢复的能力。
l
•配置服务器:
使用使用3个配置服务器确保元数据完整性。
l
•路由进程:
使用3个路由进程实现平衡,提高客户端接入性能l
•3个分片进程:
Shard11,Shard12,Shard13组成一个副本集,提供Sharding中shard1的功能。
l
•3个分片进程:
Shard21,Shard22,Shard23组成一个副本集,提供Sharding中Shard2的功能。
l
•3个配置服务器进程和3个路由器进程。
l
构建一个mongoDBShardingCluster需要三种角色:
shard服务器(ShardServer)、配置服务器(configServer)、路由进程(RouteProcess)Shard服务器
shard服务器即存储实际数据的分片,每个shard可以是一个mongod实例,也可以是一组mongod实例构成的ReplicaSets.为了实现每个Shard内部的故障自动转换,MongoDB官方建议每个shard为一组ReplicaSets.配置服务器
为了将一个特定的collection存储在多个shard中,需要为该collection指定一个shardkey,决定该条记录属于哪个chunk,配置服务器可以存储以下信息,每个shard节点的配置信息,每个chunk的shardkey范围,chunk在各shard的分布情况,集群中所有DB和collection的sharding配置信息。
路由进程
它是一个前段路由,客户端由此接入,首先询问配置服务器需要到哪个shard上查询或保存记录,然后连接相应的shard执行操作,最后将结果返回给客户端,客户端只需要将原本发给mongod的查询或更新请求原封不动地发给路由进程,而不必关心所操作的记录存储在哪个shard上。
按照架构图,理论上是需要16台机器的,由于资源有限,用目录来替代物理机(有风险,若其中某台机器宕机,配置在该机器的服务都会down掉),下面给出配置表格:
服务器
Host
服务和端口
1
10.211.55.28
Shard11:
10011Shard21:
10021ConfigSvr:
10031
Mongos:
10040
2
10.211.55.28
Shard12:
10012Shard22:
10022ConfigSvr:
10032
Mongos:
10042
3
10.211.55.28
Shard13:
10013Shard23:
10023ConfigSvr:
10033
Mongos:
10043
3.2.环境变量
下面给出MongoDB的环境变量配置,输入命令并配置:
[root@mongo~]#vi/etc/profile
exportMONGO_HOME=/root/mongodb-linux-x86_64-2.6.7exportPATH=$PATH:
$MONGO_HOME/bin
然后保存退出,输入以下命令配置文件立即生效:
[root@mongo~]#./etc/profile
我们分别启动Shard1的所有进程,并设置副本集为:
shard1。
下面给出启动Shard1的脚本文件。
•shard11.confl
dbpath=/mongodb/data/shard11logpath=/mongodb/log/shard11.logpidfilepath=/mongodb/pid/shard11.piddirectoryperdb=truelogappend=truereplSet=shard1port=10011fork=trueshardsvr=truejournal=true
•shard12.confl
dbpath=/mongodb/data/shard12logpath=/mongodb/log/shard12.logpidfilepath=/mongodb/pid/shard12.piddirectoryperdb=truelogappend=truereplSet=shard1port=10012fork=trueshardsvr=truejournal=true
•shard13.confl
dbpath=/mongodb/data/shard13logpath=/mongodb/log/shard13.logpidfilepath=/mongodb/pid/shard13.piddirectoryperdb=true
logappend=truereplSet=shard1port=10013fork=trueshardsvr=truejournal=true
•shard21.confl
dbpath=/mongodb/data/shard21logpath=/mongodb/log/shard21.logpidfilepath=/mongodb/pid/shard21.piddirectoryperdb=truelogappend=truereplSet=shard2port=10021fork=trueshardsvr=truejournal=true
•shard22.confl
dbpath=/mongodb/data/shard22logpath=/mongodb/log/shard22.logpidfilepath=/mongodb/pid/shard22.piddirectoryperdb=truelogappend=truereplSet=shard2port=10022fork=trueshardsvr=truejournal=true
•shard23.confl
dbpath=/mongodb/data/shard23logpath=/mongodb/log/shard23.logpidfilepath=/mongodb/pid/shard23.pid
directoryperdb=truelogappend=truereplSet=shard2port=10023fork=trueshardsvr=truejournal=true
•config1.confl
dbpath=/mongodb/config/config1logpath=/mongodb/log/config1.logpidfilepath=/mongodb/pid/config1.piddirectoryperdb=truelogappend=trueport=10031fork=trueconfigsvr=truejournal=true
•config2.confl
dbpath=/mongodb/config/config2logpath=/mongodb/log/config2.logpidfilepath=/mongodb/pid/config2.piddirectoryperdb=truelogappend=trueport=10032fork=trueconfigsvr=truejournal=true
•config3.confl
dbpath=/mongodb/config/config3logpath=/mongodb/log/config3.logpidfilepath=/mongodb/pid/config3.piddirectoryperdb=truelogappend=true
port=10033fork=trueconfigsvr=truejournal=true
•route.conf
configdb=mongo:
10031,mongo:
10032,mongo:
10033pidfilepath=/mongodb/pid/route.pid
port=10040chunkSize=1
logpath=/mongodb/log/route.loglogappend=truefork=true
•route2.conf
configdb=mongo:
10031,mongo:
10032,mongo:
10033pidfilepath=/mongodb/pid/route.pid
port=10042chunkSize=1
logpath=/mongodb/log/route2.loglogappend=truefork=true
3.4.启动批处理
dbpath:
数据存放目录logpath:
日志存放路径logappend:
以追加的方式记录日志
replSet:
replicaset的名字
port:
mongodb进程所使用的端口号,默认为27017fork:
以后台方式运行进程
journal:
写日志
smallfiles:
当提示空间不够时添加此参数其他参数
pidfilepath:
进程文件,方便停止mongodbdirectoryperdb:
为每一个数据库按照数据库名建立文件夹存放bind_ip:
mongodb所绑定的ip地址oplogSize:
mongodb操作日志文件的最大大小。
单位为Mb,默认为硬盘剩余空间的5%noprealloc:
不预先分配存储shardsvr:
分片configsvr:
配置服务节点configdb:
配置config节点到route节点
3.6.配置分片的表和片键
首先,我们需要登录到路由节点,这里我们登录到其中一个10040端口下的节点。
输入如下命令:
mongomongo:
10040useadmin
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(vari=1;i<=100000;i++)db.user.save({id:
i,value1:
"1234567890",value2:
"12345
67890",value3:
"1234567890",value4:
"1234567890"});