晓夏

YoungCheung

Zhang Sir's technical way

MongoDB数据库集群实战

浏览量:1199

一、分片

     在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。

    那么,为什么要分片?

  •         a.复制所有的写入操作到主节点

  •         b.延迟的敏感数据会在主节点查询

  •         c.单个副本集限制在12个节点

  •         d.当请求量巨大时会出现内存不足。

  •         e.本地磁盘不足

  •         f.垂直扩展价格昂贵

二、MongoDB背景及场景

    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的问题。 

三、MongoDB集群准备

3.1 系统环境:

[root@MongoDB1 ~]# cat /etc/redhat-release 
CentOS Linux release 7.1.1503 (Core) 
[root@MongoDB1 ~]# uname -r
3.10.0-229.el7.x86_64

3.2 主机 ip 及端口

blob.png

3.3 目录规范

集群目录:   

                 /data/mongodb-cluster

各服务目录:    

                  /data/mongodb-cluster/mongo_config

                  /data/mongodb-cluster/mongos

                  /data/mongodb-cluster/mongo_shard1

                  /data/mongodb-cluster/mongo_shard2      

                  /data/mongodb-cluster/mongo_shard3

3.4 集群示意图

blob.png


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


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

  • l  配置服务器:使用使用3个配置服务器确保元数据完整性。

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

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

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

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

  • 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 上。

四、MongoDB集群搭建
4.1 配置环境变量

[root@MongoDB1 ~]# tail -1 /etc/profile
PATH=$PATH:/usr/local/mongodb/bin:/usr/local/mongodb/bin

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

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

4.2 创建相关目录(三台服务器相同)

mkdir  /data/mongodb-cluster -p
mkdir  /data/mongodb-cluster/mongo_config -p
mkdir  /data/mongodb-cluster/mongos -p
mkdir  /data/mongodb-cluster/mongo_shard1 -p
mkdir  /data/mongodb-cluster/mongo_shard2 -p
mkdir  /data/mongodb-cluster/mongo_shard3 -p
mkdir  /data/mongodb-cluster/mongo_config/config -p
mkdir  /data/mongodb-cluster/mongo_config/log  -p
mkdir    /data/mongodb-cluster/mongo_config/data -p
mkdir  /data/mongodb-cluster/mongos/config -p
mkdir  /data/mongodb-cluster/mongos/log -p
mkdir  /data/mongodb-cluster/mongo_shard1/config -p
mkdir  /data/mongodb-cluster/mongo_shard1/log -p
mkdir  /data/mongodb-cluster/mongo_shard1/data -p
mkdir  /data/mongodb-cluster/mongo_shard2/config -p
mkdir  /data/mongodb-cluster/mongo_shard2/log -p
mkdir  /data/mongodb-cluster/mongo_shard2/data -p
mkdir  /data/mongodb-cluster/mongo_shard3/config -p
mkdir  /data/mongodb-cluster/mongo_shard3/log -p
mkdir  /data/mongodb-cluster/mongo_shard3/data -p

目录结构:


blob.png

4.3 配置shard 

配置shard1到复制集s1:

MongoDB1:mongod --replSet s1 --port 20001 --dbpath=/data/mongodb-cluster/mongo_shard1/data/ --logpath=/data/mongodb-cluster/mongo_shard1/log/mongo_shard1.log  --logappend --fork
MongoDB2:mongod --replSet s1 --port 20001 --dbpath=/data/mongodb-cluster/mongo_shard1/data/ --logpath=/data/mongodb-cluster/mongo_shard1/log/mongo_shard1.log  --logappend --fork
MongoDB3:mongod --replSet s1 --port 20001 --dbpath=/data/mongodb-cluster/mongo_shard1/data/ --logpath=/data/mongodb-cluster/mongo_shard1/log/mongo_shard1.log  --logappend --fork

连接任意一个节点初始化复制集s1

[root@MongoDB1 ~]# mongo 192.168.56.10:20001
MongoDB shell version: 3.2.9
connecting to: 192.168.56.10:20001/test
> use admin
switched to db admin
> config = {_id:'s1',members:[{_id:0,host:'192.168.56.10:20001',priority:1},{_id:1,host:'192.168.56.11:20001'},{_id:2,host:'192.168.56.12:20001'}]}
> rs.initiate(config)
>s1:OTHER> rs.status()

结果:

blob.png

blob.png

blob.png


所有节点执行


> db.getMongo().setSlaveOk();

配置shard2到复制集s2:

MongoDB1:mongod --replSet s2 --port 20002 --dbpath=/data/mongodb-cluster/mongo_shard2/data/ --logpath=/data/mongodb-cluster/mongo_shard2/log/mongo_shard2.log  --logappend --fork
MongoDB2:mongod --replSet s2 --port 20002 --dbpath=/data/mongodb-cluster/mongo_shard2/data/ --logpath=/data/mongodb-cluster/mongo_shard2/log/mongo_shard2.log  --logappend --fork
MongoDB3:mongod --replSet s2 --port 20002 --dbpath=/data/mongodb-cluster/mongo_shard2/data/ --logpath=/data/mongodb-cluster/mongo_shard2/log/mongo_shard2.log  --logappend --fork

连接任意一个节点初始化复制集s2

[root@MongoDB1 ~]# mongo 192.168.56.10:20002
MongoDB shell version: 3.2.9
connecting to: 192.168.56.10:20002/test
> use admin
switched to db admin
> config = {_id:'s2',members:[{_id:0,host:'192.168.56.10:20002'},{_id:1,host:'192.168.56.11:20002',priority:1},{_id:2,host:'192.168.56.12:20002'}]}
> rs.initiate(config)
{ "ok" : 1 }
s2:OTHER> rs.status()

结果:

blob.png

blob.png

blob.png所有节点执行


> db.getMongo().setSlaveOk();

配置shard3到复制集s3:(略,提示:配置和前面相似)

4.4 配置config server

MongoDB1:mongod -fork --configsvr --dbpath=/data/mongodb-cluster/mongo_config/data/ --port 20006 --logpath=/data/mongodb-cluster/mongo_config/log/mongo.log
MongoDB2:mongod -fork --configsvr --dbpath=/data/mongodb-cluster/mongo_config/data/ --port 20006 --logpath=/data/mongodb-cluster/mongo_config/log/mongo.log
MongoDB3:mongod -fork --configsvr --dbpath=/data/mongodb-cluster/mongo_config/data/ --port 20006 --logpath=/data/mongodb-cluster/mongo_config/log/mongo.log

4.5 配置route server

MongoDB1:mongos -fork --logpath=/data/mongodb-cluster/mongos/log/mongos.log  --configdb 192.168.56.10:20006,192.168.56.11:20006,192.168.56.12:20006 --port 20000
MongoDB2:mongos -fork --logpath=/data/mongodb-cluster/mongos/log/mongos.log  --configdb 192.168.56.10:20006,192.168.56.11:20006,192.168.56.12:20006 --port 20000
MongoDB3:mongos -fork --logpath=/data/mongodb-cluster/mongos/log/mongos.log  --configdb 192.168.56.10:20006,192.168.56.11:20006,192.168.56.12:20006 --port 20000

4.6 配置shard cluster

连接任意一台mongos执行命令:

mongos> use admin
switched to db admin
mongos> sh.addShard("s1/192.168.56.10:20001,192.168.56.11:20001,192.168.56.12:20001")
{ "shardAdded" : "s1", "ok" : 1 }
mongos> sh.addShard("s2/192.168.56.10:20002,192.168.56.11:20002,192.168.56.12:20002")
{ "shardAdded" : "s2", "ok" : 1 }
mongos> sh.addShard("s3/192.168.56.10:20003,192.168.56.11:20003,192.168.56.12:20003")
{ "shardAdded" : "s3", "ok" : 1 }
mongos> db.printShardingStatus()
--- Sharding Status --- 
  sharding version: {
	"_id" : 1,
	"minCompatibleVersion" : 5,
	"currentVersion" : 6,
	"clusterId" : ObjectId("58c6536526d14963b15b2e22")
}
  shards:
	{  "_id" : "s1",  "host" : "s1/192.168.56.10:20001,192.168.56.11:20001,192.168.56.12:20001" }
	{  "_id" : "s2",  "host" : "s2/192.168.56.10:20002,192.168.56.11:20002,192.168.56.12:20002" }
	{  "_id" : "s3",  "host" : "s3/192.168.56.10:20003,192.168.56.11:20003,192.168.56.12:20003" }
  active mongoses:
	"3.2.9" : 3
  balancer:
	Currently enabled:  yes
	Currently running:  no
	Failed balancer rounds in last 5 attempts:  0
	Migration Results for the last 24 hours: 
		No recent migrations
  databases:

4.7 激活数据库及集合分片功能

连接任意mongos执行一下命令

mongos> use admin
switched to db admin
mongos> db.runCommand({enablesharding:"testdb"})
{ "ok" : 1 }
mongos> db.runCommand({shardcollection:"testdb.collection_test",key:{_id:1}})
{ "collectionsharded" : "testdb.collection_test", "ok" : 1 }

4.8 登录mongos添加用户

use admin   
db.createUser(    
  {    
    user: "test",    
    pwd: "123456",    
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]    
  }    
)

登录测试:

mongo --port 20000 -u test -p 123456 --authenticationDatabase admin

blob.png

到此,MongoDB集群搭建完成。

神回复

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。