MongoDB复制集及数据分片详解

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

前言

MongoDB是一个由C++语言编写的基于分布式文件存储的数据库,是当前NoSQL数据库中比较热门的一种,旨在为Web应用提供可扩展的高性能数据存储解决方案。本文介绍MongoDB复制集及数据分片。

MongoDB

简介

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,因此可以存储比较复杂的数据类型。最大的特点是其支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

特点及功能特性

特点:高性能、易部署、易使用,存储数据非常方便

主要功能特性有:

面向集合存储,易存储对象类型的数据

模式自由

支持动态查询

支持完全索引,包含内部对象

支持查询

支持复制和故障恢复

使用高效的二进制数据存储,包括大型对象(如视频等)

自动处理碎片,以支持云计算层次的扩展性

支持Ruby,Python,Java,C++,PHP等多种语言

文件存储格式为Bson(一种Json的扩展)

可通过网络访问

优缺点

与关系型数据库相比,MongoDB的优点:

弱一致性(最终一致),更能保证用户的访问速度

文档结构的存储方式,能够更便捷的获取数据

内置GridFS,支持大容量的存储

内置Sharding

第三方支持丰富(这是与其他的NoSQL相比,MongoDB也具有的优势)

性能优越

与关系型数据库相比,MongoDB的缺点:

不支持事务操作

占用空间过大

没有成熟的维护工具

MongoDB复制集

复制集

工作特性:

至少三个,且应该为奇数个节点,可使用arbiter(仲裁者)来参与选举

复制集可实现失效自动转移(通过选举方式实现)

复制集的中特殊类型的节点:

0优先级的节点:冷备节点,不会被选举成为主节点,但可以参与选举

被隐藏的从节点:首先是一个0优先级的从节点,且对客户端不可见

延迟复制的从节点:首先是一个0优先级的从节点,且复制时间落后于主节点一个固定时长

arbiter: 仲裁者

复制集架构

wKiom1WjeEzBZzG-AAFIL7klLVc870.jpg

实验拓扑

wKiom1WjiuDwGwjbAAB4f8khcgU434.jpg

1
2
#系统环境:CentOS6.6
#各节点时间已同步

配置过程

安装所需软件

1
2
3
4
5
6
7
[root@node1 ~] # cd mongodb/
[root@node1 mongodb] # ls
mongodb-org-server-2.6.10-1.x86_64.rpm  mongodb-org-tools-2.6.10-1.x86_64.rpm
mongodb-org-shell-2.6.10-1.x86_64.rpm
[root@node1 mongodb] # yum install *.rpm -y      #3个包都安装
 
#所有节点都执行以上安装操作

编辑配置文件

1
2
3
4
5
6
7
8
9
10
11
12
[root@node1 ~] # vim /etc/mongod.conf 
 
logpath= /var/log/mongodb/mongod .log
logappend= true
fork= true
dbpath= /mongodb/data                         #数据位置
pidfilepath= /var/run/mongodb/mongod .pid
#bind_ip=127.0.0.1                          #默认监听本机,注释掉监听所有
httpinterface= true                           #开放web
rest= true
replSet=testSet                              #复制集名,可自定义
replIndexPrefetch=_id_only

同步配置文件至各节点

1
2
3
4
5
6
[root@node1 ~] # scp /etc/mongod.conf node3:/etc
root@node3's password: 
mongod.conf                                             100% 1567     1.5KB /s    00:00    
[root@node1 ~] # scp /etc/mongod.conf node4:/etc
root@node4's password: 
mongod.conf                                             100% 1567     1.5KB /s    00:00

创建数据目录

1
2
3
4
5
6
[root@node1 ~] # mkdir /mongodb/data -pv
mkdir : created directory ` /mongodb '
mkdir : created directory ` /mongodb/data '
[root@node1 ~] # chown -R mongod.mongod /mongodb
 
#各节点都执行以上操作

启动服务

1
2
3
4
5
6
[root@node1 ~] # service mongod start
Starting mongod:                                           [  OK  ]
[root@node1 mongodb] # ss -tnl | grep 27017
LISTEN     0      128                       *:27017                    *:*   
 
#各节点启动服务,启动过程中需要初始化数据,故启动较慢

连接数据库做初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@node1 ~] # mongo
MongoDB shell version: 2.6.10
connecting to:  test
Welcome to the MongoDB shell.
For interactive help,  type  "help" .
For  more  comprehensive documentation, see
     http: //docs .mongodb.org/
Questions? Try the support group
     http: //groups .google.com /group/mongodb-user
> rs.initiate()
{
     "info2"  "no configuration explicitly specified -- making one" ,
     "me"  "node1.scholar.com:27017" ,
     "info"  "Config now saved locally.  Should come online in about a minute." ,
     "ok"  : 1
}
 
#初始化成功,查看状态信息
> rs.status()
{
     "set"  "testSet" ,
     "date"  : ISODate( "2015-07-13T12:33:27Z" ),
     "myState"  : 1,
     "members"  : [
         {
             "_id"  : 0,
             "name"  "node1.scholar.com:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 1111,
             "optime"  : Timestamp(1436790736, 1),
             "optimeDate"  : ISODate( "2015-07-13T12:32:16Z" ),
             "electionTime"  : Timestamp(1436790737, 1),
             "electionDate"  : ISODate( "2015-07-13T12:32:17Z" ),
             "self"  true
         }
     ],
     "ok"  : 1
}
testSet:PRIMARY> 
 
#已成为主节点

添加节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
testSet:PRIMARY> rs.add( "172.16.10.125" )
"ok"  : 1 }
testSet:PRIMARY> rs.add( "172.16.10.126" )
"ok"  : 1 }
 
#查看各节点状态
testSet:PRIMARY> rs.status()
{
     "set"  "testSet" ,
     "date"  : ISODate( "2015-07-13T12:41:07Z" ),
     "myState"  : 1,
     "members"  : [
         {
             "_id"  : 0,
             "name"  "node1.scholar.com:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 1571,
             "optime"  : Timestamp(1436791178, 1),
             "optimeDate"  : ISODate( "2015-07-13T12:39:38Z" ),
             "electionTime"  : Timestamp(1436790737, 1),
             "electionDate"  : ISODate( "2015-07-13T12:32:17Z" ),
             "self"  true
         },
         {
             "_id"  : 1,
             "name"  "172.16.10.125:27017" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 98,
             "optime"  : Timestamp(1436791178, 1),
             "optimeDate"  : ISODate( "2015-07-13T12:39:38Z" ),
             "lastHeartbeat"  : ISODate( "2015-07-13T12:41:06Z" ),
             "lastHeartbeatRecv"  : ISODate( "2015-07-13T12:41:05Z" ),
             "pingMs"  : 1,
             "syncingTo"  "node1.scholar.com:27017"
         },
         {
             "_id"  : 2,
             "name"  "172.16.10.126:27017" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 89,
             "optime"  : Timestamp(1436791178, 1),
             "optimeDate"  : ISODate( "2015-07-13T12:39:38Z" ),
             "lastHeartbeat"  : ISODate( "2015-07-13T12:41:06Z" ),
             "lastHeartbeatRecv"  : ISODate( "2015-07-13T12:41:06Z" ),
             "pingMs"  : 1,
             "syncingTo"  "node1.scholar.com:27017"
         }
     ],
     "ok"  : 1
}

创建数据,验证是否同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#主节点
testSet:PRIMARY> use testdb
switched to db testdb
testSet:PRIMARY> db.students.insert({name:  "ZhangSan" ,age:  "21" })
WriteResult({  "nInserted"  : 1 })
 
#从节点
testSet:SECONDARY> rs.slaveOk()      #每个从节点首先申明从节点准备完毕才可同步
testSet:SECONDARY> use testdb
switched to db testdb
testSet:SECONDARY> show collections
students
system.indexes
testSet:SECONDARY> db.students.findOne()
{
     "_id"  : ObjectId( "55a3b494ebcafd9edbdfce4d" ),
     "name"  "ZhangSan" ,
     "age"  "21"
}
#验证从节点是否可写
testSet:SECONDARY> db.classes.insert({class:  "2" ,numstu:  "50" })
WriteResult({  "writeError"  : {  "code"  : undefined,  "errmsg"  "not master"  } })
 
#由此可见,只有主节点才可写

以上便是复制集的相关配置,如果主节点故障,从节点会自动选举出新的主节点,这里就不再演示

数据分片

分片缘由

分片(sharding)是MongoDB用来将大型集合分割到不同服务器(集群)上所采用的方法。当单台服务器CPU,Memory,IO等无法满足需求,就需要将数据分片存放,减缓服务器压力。

分片架构

wKioL1WjvPuQ0HVeAAG3WbZrFqw217.jpg

实验拓扑

wKioL1WjwLeTs5aJAACNKqEdgL8258.jpg

配置过程

因为以上做过实验我们首先来清理一下数据

1
2
3
4
5
[root@node1 ~] # service mongod stop
Stopping mongod:                                           [  OK  ]
[root@node1 ~] # rm -rf /mongodb/data/*
 
#各节点都执行以上操作,若第一次做可忽略

Config Server配置

1
2
3
4
5
#安装所需包
[root@node2 mongodb] # ls
mongodb-org-server-2.6.10-1.x86_64.rpm  mongodb-org-tools-2.6.10-1.x86_64.rpm
mongodb-org-shell-2.6.10-1.x86_64.rpm
[root@node2 mongodb] # yum install *.rpm -y

修改配置文件

1
2
3
4
5
6
7
8
9
10
11
[root@node2 ~] # vim /etc//mongod.conf 
 
logpath= /var/log/mongodb/mongod .log
logappend= true
fork= true
dbpath= /mongodb/data  
configsvr= true                                #开启config server                  
pidfilepath= /var/run/mongodb/mongod .pid
#bind_ip=127.0.0.1                          
httpinterface= true                         
rest= true

创建数据目录

1
2
3
4
[root@node2 ~] # mkdir /mongodb/data -pv
mkdir : created directory ` /mongodb '
mkdir : created directory ` /mongodb/data '
[root@node2 ~] # chown -R mongod.mongod /mongodb

启动服务

1
2
3
4
5
6
[root@node2 ~] # service mongod start
Starting mongod:                                           [  OK  ]
[root@node2 ~] # ss -tnl | grep 27019
LISTEN     0      128                       *:27019                    *:*     
 
#监听端口已发生改变,不再是27017

Mongos配置

1
2
#安装所需包,Mongos节点只装此包即可,无需装第一次实验中的mongod的相关包
[root@node1 ~] # yum install mongodb-org-mongos-2.6.10-1.x86_64.rpm -y

启动服务

1
2
3
4
5
6
7
8
[root@node1 ~] # mongos --configdb=172.16.10.124 --fork --logpath=/var/log/mongodb/mongos.log
2015-07-13T22:22:47.404+0800 warning: running with 1 config server should be  done  only fo
r testing purposes and is not recommended  for  production
about to fork child process, waiting  until  server is ready  for  connections.
forked process: 3583
child process started successfully, parent exiting
 
#--configdb指定config server --logpath指定日志位置 --fork后台运行

Shard配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#以为我们第一次实验安装过软件了,下面直接修改配置文件
[root@node3 ~] # vim /etc/mongod.conf 
 
logpath= /var/log/mongodb/mongod .log
logappend= true
fork= true
dbpath= /mongodb/data                      
pidfilepath= /var/run/mongodb/mongod .pid
#bind_ip=127.0.0.1                          
httpinterface= true                         
rest= true
 
[root@node3 ~] # service mongod start
Starting mongod:                                           [  OK  ]
 
#两个shard节点都执行以上操作

Mongos节点添加Shard节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@node1 ~] # mongo --host 172.16.10.123
MongoDB shell version: 2.6.10
connecting to: 172.16.10.123:27017 /test
mongos> sh.addShard( "172.16.10.125" )
"shardAdded"  "shard0000" "ok"  : 1 }
mongos> sh.addShard( "172.16.10.126" )
"shardAdded"  "shard0001" "ok"  : 1 }
mongos> sh.status()
--- Sharding Status --- 
   sharding version: {
     "_id"  : 1,
     "version"  : 4,
     "minCompatibleVersion"  : 4,
     "currentVersion"  : 5,
     "clusterId"  : ObjectId( "55a3c9ba131b83ff44e19435" )
}
   shards:
     {   "_id"  "shard0000" ,   "host"  "172.16.10.125:27017"  }
     {   "_id"  "shard0001" ,   "host"  "172.16.10.126:27017"  }
   databases:
     {   "_id"  "admin" ,   "partitioned"  false ,   "primary"  "config"  }

对所需对象启用分片功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#对数据库启用sharding功能
mongos> sh.enableSharding( "testdb" )
"ok"  : 1 }
mongos> sh.status()
--- Sharding Status --- 
   sharding version: {
     "_id"  : 1,
     "version"  : 4,
     "minCompatibleVersion"  : 4,
     "currentVersion"  : 5,
     "clusterId"  : ObjectId( "55a3c9ba131b83ff44e19435" )
}
   shards:
     {   "_id"  "shard0000" ,   "host"  "172.16.10.125:27017"  }
     {   "_id"  "shard0001" ,   "host"  "172.16.10.126:27017"  }
   databases:
     {   "_id"  "admin" ,   "partitioned"  false ,   "primary"  "config"  }
     {   "_id"  "test" ,   "partitioned"  false ,   "primary"  "shard0000"  }
     {   "_id"  "testdb" ,   "partitioned"  true ,   "primary"  "shard0000"  }
 
#指定需要分片的Collection及索引
mongos> sh.shardCollection( "testdb.students" ,{ "age" : 1})
"collectionsharded"  "testdb.students" "ok"  : 1 }
mongos> sh.status()
--- Sharding Status --- 
   sharding version: {
     "_id"  : 1,
     "version"  : 4,
     "minCompatibleVersion"  : 4,
     "currentVersion"  : 5,
     "clusterId"  : ObjectId( "55a3c9ba131b83ff44e19435" )
}
   shards:
     {   "_id"  "shard0000" ,   "host"  "172.16.10.125:27017"  }
     {   "_id"  "shard0001" ,   "host"  "172.16.10.126:27017"  }
   databases:
     {   "_id"  "admin" ,   "partitioned"  false ,   "primary"  "config"  }
     {   "_id"  "test" ,   "partitioned"  false ,   "primary"  "shard0000"  }
     {   "_id"  "testdb" ,   "partitioned"  true ,   "primary"  "shard0000"  }
         testdb.students
             shard key: {  "age"  : 1 }
             chunks:
                 shard0000   1
             "age"  : {  "$minKey"  : 1 } } -->> {  "age"  : {  "$maxKey"  : 1 } }
on : shard0000 Timestamp(1, 0)

分片功能已开启,接下来我们手动创建数据来验证是否会分片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mongos> use testdb
switched to db testdb
mongos>  for  (i=1;i<=100000;i++) db.students.insert({name: "student" +i,age:(i%120),address: "China" })
WriteResult({  "nInserted"  : 1 })
mongos> db.students. find ().count()
100000
mongos> sh.status()
--- Sharding Status --- 
   sharding version: {
     "_id"  : 1,
     "version"  : 4,
     "minCompatibleVersion"  : 4,
     "currentVersion"  : 5,
     "clusterId"  : ObjectId( "55a3c9ba131b83ff44e19435" )
}
   shards:
     {   "_id"  "shard0000" ,   "host"  "172.16.10.125:27017"  }
     {   "_id"  "shard0001" ,   "host"  "172.16.10.126:27017"  }
   databases:
     {   "_id"  "admin" ,   "partitioned"  false ,   "primary"  "config"  }
     {   "_id"  "test" ,   "partitioned"  false ,   "primary"  "shard0000"  }
     {   "_id"  "testdb" ,   "partitioned"  true ,   "primary"  "shard0000"  }
         testdb.students
             shard key: {  "age"  : 1 }
             chunks:
                 shard0001   1
                 shard0000   2
             "age"  : {  "$minKey"  : 1 } } -->> {  "age"  : 1 } on : shard0001 Timestamp(2, 0) 
             "age"  : 1 } -->> {  "age"  : 119 } on : shard0000 Timestamp(2, 2) 
             "age"  : 119 } -->> {  "age"  : {  "$maxKey"  : 1 } } on : shard0000 Timestamp(2, 3)

查看数据状态会发现数据已被分到不同shard上,至此,数据分片成功实现

The end

MongoDB复制集及数据分片就先说到这里了,通过以上简单应用可以看出,MongoDB在大数据处理方面比关系型数据库略胜一筹,但由于MongoDB目前还处在发展阶段,在实际生产环境中还有许多问题有待解决,不过相信在未来MongoDB会更加出色。以上仅为个人学习整理,如有错漏,大神勿喷~~~



本文转自 北城书生  51CTO博客,原文链接:http://blog.51cto.com/scholar/1673939


相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
7天前
|
存储 负载均衡 NoSQL
MongoDB分片技术:实现水平扩展的利器
【4月更文挑战第30天】MongoDB的分片技术是应对数据增长和复杂业务需求的解决方案,它将数据水平拆分存储在多个实例上,实现数据库的水平扩展。分片带来水平扩展性、负载均衡、高可用性和灵活的数据管理。分片工作涉及mongos路由进程、config server和shard实例。设置分片包括部署配置服务器、添加分片、启动mongos、配置分片键和开始分片。选择合适的分片键和有效管理能确保系统性能和稳定性。
|
2天前
|
监控 NoSQL MongoDB
mongoDB查看数据的插入日志
【5月更文挑战第2天】mongoDB查看数据的插入日志
25 0
|
8天前
|
分布式计算 DataWorks NoSQL
DataWorks产品使用合集之DataWorks 中同步 MongoDB 数据的步骤如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
24 4
|
8天前
|
NoSQL 数据管理 MongoDB
数据管理DMS产品使用合集之如何通过阿里云的数据管理服务(DMS)导出MongoDB数据
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
29天前
|
JSON NoSQL MongoDB
mongodb通过mongoexport命令导出数据
mongodb通过mongoexport命令导出数据
|
29天前
|
JSON NoSQL MongoDB
mongodb导出聚合查询的数据
mongodb导出聚合查询的数据
|
29天前
|
NoSQL MongoDB
使用MongoTemplate 对 mongodb数据进行分组、排序、分页、连表查询
使用MongoTemplate 对 mongodb数据进行分组、排序、分页、连表查询
|
1月前
|
存储 NoSQL 关系型数据库
MongoDB 的数据关系
MongoDB是面向文档的NoSQL数据库,以其灵活的数据模型区别于传统关系型数据库。数据以JSON-like文档形式存储,文档可嵌套并存储在集合中。其特点包括:嵌入式文档、弱类型架构(无模式)、无连接性及引用关系。MongoDB支持动态添加字段,通过嵌入或引用处理文档关联,适应各种数据结构和复杂关系,适合不同应用场景。
|
2月前
|
NoSQL MongoDB
MongoDB数据日期显示相差8小时
MongoDB数据日期显示相差8小时
25 0
|
2月前
|
NoSQL MongoDB
搭建MongoDB分片式集群
搭建MongoDB分片式集群
17 0