实验环境

主机              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. malloc() vs new

    Following are the differences between malloc() and operator new. (1)new calls constructors, while ma ...

  2. MySQL(1):SQLyog

    数据库(DataBase,简称DB) 一. 基本数据库操作命令 flush privileges 刷新数据库 show databases 显示所有数据库 use dbname 打开某个数据库 sho ...

  3. 远程调用RPC

    一.简介 RPC,就是Remote Procedure Call的简称呀,翻译成中文就是远程过程调用. 本地调用,就好比你现在在家里,你要想洗碗,那你直接把碗放进洗碗机,打开洗碗机开关就可以洗了.这就 ...

  4. ciscn_2019_es_7

    这是我第一次见到srop的用法的题目,于是在此记录方便以后的复习 拿到程序例行检查 将程序放入ida中 可以看到栈的大小是0x10,却可以显示出0x30的内容,所以我们可以通过这个溢出泄露出/bin/ ...

  5. 我在这里的处女篇(Word技巧集团)

    传说这里的文章可以在Word上打好了发布,Word嘛,有[听写]功能,不用打字了: 写好的文章还可以[大声朗读],边听边看最容易找"通假字"了. 冲这,我的新阵地就定这里了,哈哈~

  6. java 常用类库:时间类LocalDate;LocalTime;LocalDateTime;Calendar 类;Date ;

    LocalDate类 LocalDate类代表不带时区的日期,列入2020-12-20.该类提供了静态的now()方法来获取当前的日期.这个类是线程安全的. LocalTime类 代表不带时区的时间, ...

  7. 几个主流TCP/IP协议栈介绍

    我们知道TCP IP协议栈内包括了诸多协议.那么对于这当中的协议的功能以及作用,我们来具体了解一下吧.现在让我们做一个盘点,帮助大家总结一下,还望对大家能够有所帮助. 1.BSD TCP IP协议栈 ...

  8. SpringBoot整合log4j日志框架

    Spring Boot 2.x默认使用Logback日志框架,要使用 Log4j2必须先排除 Logback. 加入修改依赖 <dependency> <groupId>org ...

  9. 【九度OJ】题目1433:FatMouse 解题报告

    [九度OJ]题目1433:FatMouse 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1433 题目描述: FatMouse pr ...

  10. 【剑指Offer】数组中只出现一次的数字 解题报告(Python)

    [剑指Offer]数组中只出现一次的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...