设为首页 收藏本站
查看: 1479|回复: 0

[经验分享] MongoDB复制集及数据分片详解

[复制链接]

尚未签到

发表于 2018-10-26 10:21:55 | 显示全部楼层 |阅读模式
  前言
  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: 仲裁者
  复制集架构
DSC0000.jpg

  实验拓扑
DSC0001.jpg

#系统环境:CentOS6.6  
#各节点时间已同步
  配置过程
  安装所需软件
[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个包都安装
  

  
#所有节点都执行以上安装操作
  编辑配置文件
[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
  同步配置文件至各节点
[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
  创建数据目录
[root@node1 ~]# mkdir /mongodb/data -pv  
mkdir: created directory `/mongodb'
  
mkdir: created directory `/mongodb/data'
  
[root@node1 ~]# chown -R mongod.mongod /mongodb
  

  
#各节点都执行以上操作
  启动服务
[root@node1 ~]# service mongod start  
Starting mongod:                                           [  OK  ]
  
[root@node1 mongodb]# ss -tnl | grep 27017
  
LISTEN     0      128                       *:27017                    *:*
  

  
#各节点启动服务,启动过程中需要初始化数据,故启动较慢
  连接数据库做初始化
[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>
  

  
#已成为主节点
  添加节点
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
  
}
  创建数据,验证是否同步
#主节点  
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等无法满足需求,就需要将数据分片存放,减缓服务器压力。
  分片架构
DSC0002.jpg

  实验拓扑
DSC0003.jpg

  配置过程
  因为以上做过实验我们首先来清理一下数据
[root@node1 ~]# service mongod stop  
Stopping mongod:                                           [  OK  ]
  
[root@node1 ~]# rm -rf /mongodb/data/*
  

  
#各节点都执行以上操作,若第一次做可忽略
  Config Server配置
#安装所需包  
[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
  修改配置文件
[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
  创建数据目录
[root@node2 ~]# mkdir /mongodb/data -pv  
mkdir: created directory `/mongodb'
  
mkdir: created directory `/mongodb/data'
  
[root@node2 ~]# chown -R mongod.mongod /mongodb
  启动服务
[root@node2 ~]# service mongod start  
Starting mongod:                                           [  OK  ]
  
[root@node2 ~]# ss -tnl | grep 27019
  
LISTEN     0      128                       *:27019                    *:*
  

  
#监听端口已发生改变,不再是27017
  Mongos配置
#安装所需包,Mongos节点只装此包即可,无需装第一次实验中的mongod的相关包  
[root@node1 ~]# yum install mongodb-org-mongos-2.6.10-1.x86_64.rpm -y
  启动服务
[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配置
#以为我们第一次实验安装过软件了,下面直接修改配置文件  
[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节点
[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" }
  对所需对象启用分片功能
#对数据库启用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:
  shard00001
  { "age" : { "$minKey" : 1 } } -->> { "age" : { "$maxKey" : 1 } }
  
on : shard0000 Timestamp(1, 0)
  分片功能已开启,接下来我们手动创建数据来验证是否会分片
mongos> use testdb  
switched to db testdb
  
mongos> for (i=1;i 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:
  shard00011
  shard00002
  { "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会更加出色。以上仅为个人学习整理,如有错漏,大神勿喷~~~



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-626655-1-1.html 上篇帖子: Ubuntu 14.04---Nginx+uWsgi+Django+Python+MongoDB 下篇帖子: Mongodb日志管理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表