前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MongoDB复制集及数据分片详解(一)

MongoDB复制集及数据分片详解(一)

作者头像
小小科
发布2018-05-04 15:45:08
6680
发布2018-05-04 15:45:08
举报
文章被收录于专栏:北京马哥教育北京马哥教育

前言

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

MongoDB

简介

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

特点及功能特性

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

主要功能特性有:

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

模式自由

支持动态查询

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

支持查询

支持复制和故障恢复

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

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

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

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

可通过网络访问

优缺点

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

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

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

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

内置Sharding

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

性能优越

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

不支持事务操作

占用空间过大

没有成熟的维护工具

MongoDB复制集

复制集

MongoDB有两种复制类型:Master/Slave主从和Replica Set副本集复制,由于MongoDB的特性,主从复制架构已基本不再使用,目前比较常见的是副本集复制方式

工作特性:

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

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

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

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

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

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

arbiter: 仲裁者

复制集架构

实验拓扑

#系统环境:CentOS6.6

#各节点时间已同步

配置过程

安装所需软件

代码语言:javascript
复制
[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个包都安装

#所有节点都执行以上安装操作

编辑配置文件

代码语言:javascript
复制
[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

同步配置文件至各节点

代码语言:javascript
复制
[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

创建数据目录

代码语言:javascript
复制
[root@node1 ~]# mkdir /mongodb/data -pv
mkdir: created directory `/mongodb'
mkdir: created directory `/mongodb/data'
[root@node1 ~]# chown -R mongod.mongod /mongodb

#各节点都执行以上操作

启动服务

代码语言:javascript
复制
[root@node1 ~]# service mongod start
Starting mongod:                                           [  OK  ]
[root@node1 mongodb]# ss -tnl | grep 27017
LISTEN     0      128                       *:27017                    *:*   

#各节点启动服务,启动过程中需要初始化数据,故启动较慢

连接数据库做初始化

代码语言:javascript
复制
[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
}

创建数据,验证是否同步

#主节点

代码语言:javascript
复制
testSet:PRIMARY> use testdb
switched to db testdb
testSet:PRIMARY> db.students.insert({name: "ZhangSan",age: "21"})
WriteResult({ "nInserted" : 1 })

#从节点

代码语言:javascript
复制
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"
}

#验证从节点是否可写

代码语言:javascript
复制
testSet:SECONDARY> db.classes.insert({class: "2",numstu: "50"})
WriteResult({ "writeError" : { "code" : undefined, "errmsg" : "not master" } })

#由此可见,只有主节点才可写

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 马哥Linux运维 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档