实验环境

主机              IP                虚拟通道

centos1       192.168.3.10         vmnet8

centos2       192.168.3.11         vmnet8

centos3       192.168.3.12         vmnet8

从图中可以看到有四个组件:mongos、config server、shard、replica set。

mongos,数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

config server,顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,这个可不能丢失!就算挂掉其中一台,只要还有存货, mongodb集群就不会挂掉。

shard,这就是传说中的分片了。上面提到一个机器就算能力再大也有天花板,就像军队打仗一样,一个人再厉害喝血瓶也拼不过对方的一个师。俗话说三个臭皮匠顶个诸葛亮,这个时候团队的力量就凸显出来了。在互联网也是这样,一台普通的机器做不了的多台机器来做,如下图:

一台机器的一个数据表 Collection1 存储了 1T 数据,压力太大了!在分给4个机器后,每个机器都是256G,则分摊了集中在一台机器的压力。也许有人问一台机器硬盘加大一点不就可以了,为什么要分给四台机器呢?不要光想到存储空间,实际运行的数据库还有硬盘的读写、网络的IO、CPU和内存的瓶颈。在mongodb集群只要设置好了分片规则,通过mongos操作数据库就能自动把对应的数据操作请求转发到对应的分片机器上。在生产环境中分片的片键可要好好设置,这个影响到了怎么把数据均匀分到多个分片机器上,不要出现其中一台机器分了1T,其他机器没有分到的情况,这样还不如不分片!

replica set,其实上图4个分片如果没有 replica set 是个不完整架构,假设其中的一个分片挂掉那四分之一的数据就丢失了,所以在高可用性的分片架构还需要对于每一个分片构建 replica set 副本集保证分片的可靠性。生产环境通常是 2个副本 + 1个仲裁。

搭建过程:

分别在每台服务器上创建mongos 、config 、 shard1 、shard2、shard3 五个目录。

因为mongos不存储数据,只需要建立日志文件目录即可。

规划5个组件对应的端口号,由于一个机器需要同时部署 mongos、config server 、shard1、shard2、shard3,所以需要用端口进行区分。

这个端口可以自由定义,在本文 shard1为 1001 , shard2为1002, shard3为1003.

config server 为1004,  mongos为 1005,

第一、创建配置文件目录和先关准备工作

service iptables stop

setenforce 0

mkdir /data

cd /data/

以上操作3台服务器都要操作

在第一台mongo服务器上操作

创建目录和文件

mkdir
/data/{config,shard1,shard2,shard3,mongos,logs,configsvr,keyfile} -pv

touch /data/keyfile/zxl

touch /data/logs/shard{1..3}.log

touch
/data/logs/{configsvr,mongos}.log

touch
/data/config/shard{1..3}.conf

touch
/data/config/{configsvr,mongos}.conf

cd /opt/

tar xf
mongodb-linux-x86_64-rhel62-3.2.7.tgz

mv mongodb-linux-x86_64-rhel62-3.2.7
/data/mongodb

配置环境变量

echo "export
PATH=$PATH:/data/mongodb/bin" >> ~/.bash_profile

source ~/.bash_profile

 

二、创建shard配置文件

vim /data/config/shard1.conf

systemLog:

destination: file

path: /data/logs/shard1.log

logAppend: true

processManagement:

fork: true

pidFilePath: "/data/shard1/shard1.pid"

net:

port: 10001

storage:

dbPath: "/data/shard1"

engine: wiredTiger

journal:

enabled: true

directoryPerDB: true

operationProfiling:

slowOpThresholdMs: 10

mode: "slowOp"

#security:

#  keyFile: "/data/keyfile/zxl"

#  clusterAuthMode: "keyFile"

replication:

oplogSizeMB: 50

replSetName: "shard1_zxl"

secondaryIndexPrefetch: "all"

 

 

vim /data/config/shard2.conf

systemLog:

destination: file

path: /data/logs/shard2.log

logAppend: true

processManagement:

fork: true

pidFilePath: "/data/shard2/shard2.pid"

net:

port: 10002

storage:

dbPath: "/data/shard2"

engine: wiredTiger

journal:

enabled: true

directoryPerDB: true

operationProfiling:

slowOpThresholdMs: 10

mode: "slowOp"

#security:

#  keyFile: "/data/keyfile/zxl"

#  clusterAuthMode: "keyFile"

replication:

oplogSizeMB: 50

replSetName: "shard2_zxl"

secondaryIndexPrefetch: "all"

 

vim /data/config/shard3.conf

systemLog:

destination: file

path: /data/logs/shard3.log

logAppend: true

processManagement:

fork: true

pidFilePath: "/data/shard3/shard3.pid"

net:

port: 10003

storage:

dbPath: "/data/shard3"

engine: wiredTiger

journal:

enabled: true

directoryPerDB: true

operationProfiling:

slowOpThresholdMs: 10

mode: "slowOp"

#security:

#  keyFile: "/data/keyfile/zxl"

#  clusterAuthMode: "keyFile"

replication:

oplogSizeMB: 50

replSetName: "shard3_zxl"

secondaryIndexPrefetch: "all"

在每一台服务器上配置配置服务器

vim /data/config/configsvr.conf

systemLog:

destination: file

path: /data/logs/configsvr.log

logAppend: true

processManagement:

fork: true

pidFilePath: "/data/configsvr/configsvr.pid"

net:

port: 10004

storage:

dbPath: "/data/configsvr"

engine: wiredTiger

journal:

enabled: true

#security:

#  keyFile: "/data/keyfile/zxl"

#  clusterAuthMode: "keyFile"

sharding:

clusterRole: configsvr

 

在每一台服务器上配置mongos服务器

vim /data/config/mongos.conf

systemLog:

destination: file

path: /data/logs/mongos.log

logAppend: true

processManagement:

fork: true

pidFilePath: /data/mongos/mongos.pid

net:

port: 10005

sharding:

configDB: 192.168.3.10:10004,192.168.3.11:10004,192.168.3.12:10004

#security:


keyFile: "/data/keyfile/zxl"


clusterAuthMode: "keyFile"

cd /data/config

[root@localhost config]# scp *
192.168.3.11:/data/config

[root@localhost config]# scp *
192.168.3.12:/data/config

 

启动各个机器节点的mongodshard1shard2shard3

 

[mongodb@localhost ~]$ /data/mongodb/bin/mongod -f
/data/config/shard1.conf

about to fork child process,
waiting until server is ready for connections.

forked process: 26911

child process started
successfully, parent exiting

[mongodb@localhost ~]$ /data/mongodb/bin/mongod -f /data/config/shard2.conf

about to fork child process,
waiting until server is ready for connections.

forked process: 26935

child process started
successfully, parent exiting

[mongodb@localhost ~]$ /data/mongodb/bin/mongod -f
/data/config/shard3.conf

about to fork child process,
waiting until server is ready for connections.

forked process: 26958

child process started
successfully, parent exiting

三、初始化副本集

登陆第一个mongo服务器,连接mongo

[mongodb@localhost ~]$
/data/mongodb/bin/mongo 127.0.0.1:10001

use admin  #切换数据库

config = { _id:"shard1_zxl",
members:[

{_id:0,host:"192.168.3.10:10001"},

{_id:1,host:"192.168.3.11:10001"},

{_id:2,host:"192.168.3.12:10001",arbiterOnly:true}

]

}

#上边的配置是定义副本集配置

rs.initiate(config);

{ "ok" : 1 }

#初始化副本集配置

登陆第二个mongo服务器,连接mongo

[mongodb@localhost ~]$ /data/mongodb/bin/mongo
127.0.0.1:10002

use admin  #切换数据库

config = { _id:"shard2_zxl",
members:[

{_id:0,host:"192.168.3.11:10002"},

{_id:1,host:"192.168.3.12:10002"},

{_id:2,host:"192.168.3.10:10002",arbiterOnly:true}

]

}

rs.initiate(config);

{ "ok" : 1 }

登陆第三个mongo服务器,连接mongo

/data/mongodb/bin/mongo
127.0.0.1:10003

use admin  #切换数据库

config = { _id:"shard3_zxl",
members:[

{_id:0,host:"192.168.3.12:10003"},

{_id:1,host:"192.168.3.10:10003"},

{_id:2,host:"192.168.3.11:10003",arbiterOnly:true}

]

}

rs.initiate(config);

{ "ok" : 1 }

启动三台服务器的configsvr和mongos节点

[root@localhost ~]# /data/mongodb/bin/mongod -f
/data/config/configsvr.conf

about to fork child process,
waiting until server is ready for connections.

forked process: 3028

child process started
successfully, parent exiting

三台服务器全部启动configsvr后在启动mongos

启动三台服务器的mongos服务器

/data/mongodb/bin/mongos -f /data/config/mongos.conf

about to fork child process,
waiting until server is ready for connections.

forked process: 11683

child process started successfully, parent exiting

第四、配置分片

在第一台服务器上配置分片

/data/mongodb/bin/mongo
127.0.0.1:10005

mongos> use admin

mongos>db.runCommand({addshard:"shard1_zxl/192.168.3.10:10001,192.168.3.11:10001,192.168.3.12:10001"});

"shardAdded" :
"shard1_zxl", "ok" : 1 }

mongos>db.runCommand({addshard:"shard2_zxl/192.168.3.10:10002,192.168.3.11:10002,192.168.3.12:10002"});

{ "shardAdded" :
"shard2_zxl", "ok" : 1 }

mongos>db.runCommand({addshard:"shard3_zxl/192.168.3.10:10003,192.168.3.11:10003,192.168.3.12:10003"});

{ "shardAdded" : "shard2_zxl",
"ok" : 1 }

查看shard信息

mongos> sh.status();

shards:

{  "_id" :
"shard1_zxl",  "host"
: "shard1_zxl/192.168.3.10:10001,192.168.3.11:10001" }

{  "_id" :
"shard2_zxl",  "host"
: "shard2_zxl/192.168.3.11:10002,192.168.3.12:10002" }

{  "_id" :
"shard3_zxl",  "host"
: "shard3_zxl/192.168.3.10:10003,192.168.3.12:10003" }

启用shard分片的库名字为'zxl',即为库

mongos>sh.enableSharding("zxl");

{ "ok" : 1 }

测试:

设置集合的名字以及字段,默认自动建立索引,zxl库,haha集合

mongos> sh.shardCollection("zxl.haha",{age:
1, name: 1})

{ "collectionsharded" :
"zxl.haha", "ok" : 1 }

mongos> use zxl

mongos> for (i=1;i<=10000;i++)
db.haha.insert({name: "user"+i, age: (i%150)})

WriteResult({
"nInserted" : 1 })

查看分片状态

mongos> sh.status();

zxl的数据分别存储到了3个shard数据当中

验证:

我们分别登陆3台服务器上的10005

/data/mongodb/bin/mongo
127.0.0.1:10005

shard1_zxl:PRIMARY> use zxl

switched to db zxl

shard1_zxl:PRIMARY> db.haha.find()

{
"_id" : ObjectId("5a0cf9af8ee2c0b83345ac89"),
"name" : "user1", "age" : 1 }

{
"_id" : ObjectId("5a0cf9b08ee2c0b83345ac8a"),
"name" : "user2", "age" : 2 }

..........

{
"_id" : ObjectId("5a0cf9b18ee2c0b83345ac9c"),
"name" : "user20", "age" : 20 }

Type
"it" for more

我们发现数据是一样的

我们分别登陆第一台10001

[root@CentOS6-node1 ~]# /data/mongodb/bin/mongo
127.0.0.1:10001

shard1_zxl:PRIMARY> use zxl

switched to db zxl

shard1_zxl:PRIMARY> db.haha.find()

{ "_id" :
ObjectId("5a0d006a5514f2862537a50c"), "name" : "user22",
"age" : 22 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a50d"), "name" : "user23",
"age" : 23 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a50e"), "name" :
"user24", "age" : 24 }

................

{ "_id" :
ObjectId("5a0d006d5514f2862537a51d"), "name" :
"user39", "age" : 39 }

{ "_id" :
ObjectId("5a0d006d5514f2862537a51e"), "name" :
"user40", "age" : 40 }

{ "_id" :
ObjectId("5a0d006d5514f2862537a51f"), "name" : "user41",
"age" : 41 }

登陆第二台的10002

[root@CentOS6-node1 ~]# /data/mongodb/bin/mongo
127.0.0.1:10002

shard2_zxl:PRIMARY> use zxl

switched to db zxl

shard2_zxl:PRIMARY> db.haha.find()

{ "_id" :
ObjectId("5a0d006a5514f2862537a4f7"), "name" :
"user1", "age" : 1 }

{ "_id" :
ObjectId("5a0d006e5514f2862537a58c"), "name" : "user150",
"age" : 0 }

...........

{ "_id" :
ObjectId("5a0d006f5514f2862537a9a7"), "name" : "user1201", "age"
: 1 }

{ "_id" :
ObjectId("5a0d006f5514f2862537a9a8"), "name" : "user1202",
"age" : 2 }

登陆第三台的10003

shard3_zxl:PRIMARY> use zxl

switched to db zxl

shard3_zxl:PRIMARY> db.haha.find()

{ "_id" :
ObjectId("5a0d006a5514f2862537a4f8"), "name" : "user2", "age"
: 2 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a4f9"), "name" : "user3",
"age" : 3 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a4fa"), "name" : "user4",
"age" : 4 }

......

{ "_id" :
ObjectId("5a0d006a5514f2862537a507"), "name" :
"user17", "age" : 17 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a508"), "name" :
"user18", "age" : 18 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a509"), "name" :
"user19", "age" : 19 }

{ "_id" :
ObjectId("5a0d006a5514f2862537a50a"), "name" :
"user20", "age" : 20 }

{ "_id" : ObjectId("5a0d006a5514f2862537a50b"),
"name" : "user21",
"age" : 21 }

这说明数据是被分片存储的。

mongdb分片的更多相关文章

  1. MongoDB最新4.2.7版本三分片集群修改IP实操演练

    背景 重新组网,需要对现有MongoDB分片集群服务器的IP进行更改,因此也需要对MongoDB分片集群的IP也进行相应的更新,而MongoDB分片集群的IP修改不能单纯的通过配置来进行,需要一番折腾 ...

  2. [MongDB] 主从架构--官方极力不推荐

    一.缘由: 看着数据库大家庭都有主从模式,想着Mongodb应该也不会落下.但从官网看来,先是早先舍弃了Master-Master模式,现在又在不推荐 Master-Slave模式,这是要标新立异呀. ...

  3. HBase与MongDB等NoSQL数据库对照

    HBase概念学习(十)HBase与MongDB等NoSQL数据库对照 转载请注明出处: jiq•钦's technical Blog - 季义钦 一.开篇 淘宝之前使用的存储层架构一直是MySQL数 ...

  4. 搭建mongodb集群(副本集+分片)

    搭建mongodb集群(副本集+分片) 转载自:http://blog.csdn.net/bluejoe2000/article/details/41323051 完整的搭建mongodb集群(副本集 ...

  5. HBase概念学习(十)HBase与MongDB等NoSQL数据库对照

    转载请注明出处: jiq•钦's technical Blog - 季义钦 一.开篇 淘宝之前使用的存储层架构一直是MySQL数据库,配合以MongDB,Tair等存储. MySQL因为开源,而且生态 ...

  6. mongodb分片认证

    启动configsvr 1. 确保mongdb的configsvr是采用service模式启动的,即从/etc/init.d下的脚本启动的,其用户是mongod. 2. 确保mongod的配置文件完全 ...

  7. MongoDB基础之十 shared分片

    水平分片实例分布图: mongodb sharding 服务器架构   1. 添加mongdb两个shared实例 # mkdir -p /home/m17 //home/m18 /home/m20 ...

  8. Mongodb 副本集+分片

    mongodb的分片功能是建立在副本集之上的,所以首先我们尝试着配置副本集. docker启动3个已经安装好mongo的镜像 # docker run -idt --name mongodb_01 m ...

  9. MongDB篇,第一章:数据库知识1

    MongDB    数据库知识1 程序 =  数据结构 + 算法 数据存储阶段 1,文件管理阶段 (.txt .doc .xls) 优点: 数据可以长期保存:可以存储大量的数据:使用简单     缺点 ...

随机推荐

  1. Oracle常用函数(SQL语句)

    使用sql函数,您可以在一个select语句的查询当中,直接计算数据库资料的平均值.总数.最小值.最大值.总和.标准差.变异数等统计.使用recordset对象时,也可使用这些sql函数. sql函数 ...

  2. 【JavaScript】创建全0的Array

    1.创建一个长度为m的全0数组 var arr = new Array(m).fill(0); 2.创建一个m行n列的全0数组 var arr = new Array(m).fill(new Arra ...

  3. Python matplotlib绘图设置坐标轴的标题

    一.语法简介 plt.xlabel("销售月份",fontsize=16,color='red',fontweight='bold',loc='center',background ...

  4. 第46篇-signature_handler与result_handler

    在之前介绍为native方法设置解释执行的入口时介绍过,当Method::native_function为空时会调用InterpreterRuntime::prepare_native_call()函 ...

  5. 逻辑判断(Power Query 之 M 语言)

    逻辑真:true 逻辑假:false 与函数:and true and true,结果为TRUE true and false,结果为FALSE false and false,结果为FALSE 或函 ...

  6. Django中的常用字段类型与参数

    Django中的常用字段类型 1. 数值型 以下都是数值相关的,比如AutoField,它在MySQL中的类型为int(11),而BooleanField在MySQL中对应的类型是tinyint(1) ...

  7. java 常用类库:String ; StringBuilder和StringBuffer类

    1. String 1.String对象是不可变的 String类的value属性是用来存放字符串里面的值的.这个属性是被final修饰的.final修饰的变量不能够被第二次赋值,所以字符串是不可变的 ...

  8. WSL docker打通容器间通信和追加端口映射

    最近在docker中搭建一个服务,需要有多个容器通信.这里简单记录一下如何在容器间进行通信,同时说一下已经存在的容器如何追加端口映射. 增加网桥 容器间通信的目的是不适用IP而是使用容器名称进行网络通 ...

  9. 创建Ubuntu server 服务器git项目

    服务器端: mkdir project.git cd project.git git init --bare cd .. p.p1 { margin: 0; font: 11px Menlo; col ...

  10. 【LeetCode】643. 子数组最大平均数 I Maximum Average Subarray I (Python)

    作者: 负雪明烛 id: fuxuemingzhu 公众号:每日算法题 目录 题目描述 题目大意 解题方法 方法一:preSum 方法二:滑动窗口 刷题心得 日期 题目地址:https://leetc ...