概念
副本集(Replicat Set)模式
1.主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心
2.副本集中的副本节点,在主节点挂掉后,通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器
3.Mongodb 提供了各种开发语言访问 Mongodb replica sets 的驱动程序,所以,访问地址的高可用在客户端访问代码中实现
4.Mongodb Replicat sets 同步测试
5.Mongodb Replicat sets 故障切换测试
6.Mongodb Replicat sets 读写分离配置
读写分离,将读压力分散到副本集的副本节点上,可以减轻主节点的读写压力
(1)设置读写分离,需要先在副本节点SECONDARY ,设置 setSlaveOk。
(2)在程序中设置副本节点负责读操作,
分片
分片的目的
高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。
为了解决这些问题,有两个基本的方法: 垂直扩展和水平扩展。
- 垂直扩展:增加更多的CPU和存储资源来扩展容量。
- 水平扩展:将数据集分布在多个服务器上。水平扩展即分片。
分片的设计思想
分片为应对高吞吐量与大数据量提供了方法。使用分片减少了每个分片需要处理的请求数,因此,通过水平扩展,集群可以提高自己的存储容量和吞吐量。举例来说,当插入一条数据时,应用只需要访问存储这条数据的分片.
使用分片减少了每个分片存储的数据。
例如,如果数据库1tb的数据集,并有4个分片,然后每个分片可能仅持有256 GB的数据。如果有40个分片,那么每个切分可能只有25GB的数据。
分片机制提供了如下三种优势
1.mongos 对集群进行抽象,让集群“不可见”
mongodb中没有failover机制,官方建议是将mongos和应用服务器部署在一起,多个应用服务器就要部署多个mongos实例。mongos作为统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。
mongos的高可用可以用有几种方法可以使这三个mongos接口都利用起来,减少单个接口的压力。常用的有LVS和HAProxy。于是尝试用HAProxy做负载均衡。
mongodb 可以以单复制集的方式运行,client 直连 mongod 读取数据。
单复制集的方式下,数据的水平扩展的责任推给了业务层解决(分实例,分库分表),mongodb 原生提供集群方案,该方案的简要架构如下:
ConfigServer
mongodb 元数据全部存放在configServer中,configServer 是由一组(至少三个)MongoDb实例组成的集群。
ConfigServer 的唯一功能是提供元数据的增删改查。和大多数元数据管理系统(etcd,zookeeper)类似,也是保证一致性与分区容错性。本身不具备中心化的调度功能。
ConfigServer与复制集
ConfigServer 的分区容错性§和数据一致性©是复制集本身的性质。
mongodb 的读写一致性由 WriteConcern 和 ReadConcern 两个参数保证。
Mongos
数据自动分片
对于一个读写操作,mongos 需要知道应该将其路由到哪个复制集上,mongos通过将片键空间划分为若干个区间,计算出一个操作的片键的所属区间对应的复制集来实现路由。
Collection1 被划分为4个chunk,其中
chunk1 包含(-INF,1) , chunk3 包含[20, 99) 的数据,放在shard1上。
chunk2 包含 [1,20), chunk4 包含[99, INF) 的数据,放在shard2上。
chunk 的信息存放在configServer 的mongod实例的 config.chunks 表中,格式如下:
{
“id" : "mydb.foo-a"cat”",
“lastmod” : Timestamp(1000, 3),
“lastmodEpoch” : ObjectId(“5078407bd58b175c5c225fdc”),
“ns” : “mydb.foo”,
“min” : { “animal” : “cat” },
“max” : { “animal” : “dog” },
“shard” : “shard0004”
}
值得注意的是:chunk是一个逻辑上的组织结构,并不涉及到底层的文件组织方式。
2.保证集群总是可读写
MongoDB通过多种途径来确保集群的可用性和可靠性。将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每分数据都有相应的备份,这样就可以确保有服务器换掉时,其他的从库可以立即接替坏掉的部分继续工作。
3.使集群易于扩展
当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。
分片集群架构
分片集群的构造
(1)mongos :数据路由,和客户端打交道的模块。mongos本身没有任何数据,他也不知道该怎么处理这数据,去找config server
(2)config server:所有存、取数据的方式,所有shard节点的信息,分片功能的一些配置信息。可以理解为真实数据的元数据。
(3)shard:真正的数据存储位置,以chunk为单位存数据。
Mongos的路由功能
当数据写入时,MongoDB Cluster根据分片键设计写入数据。
当外部语句发起数据查询时,MongoDB根据数据分布自动路由至指定节点返回数据。
部署
分片及副本集规划
三台服务器:hsdatalab1,hsdatalab2,hsdatalab3
hsdatalab1 | hsdatalab2 | hsdatalab3 |
---|---|---|
mongos | mongos | mongos |
config server | config server | config server |
sh1 | sh1 | sh1 |
sh2 | sh2 | sh2 |
sh3 | sh3 | sh3 |
副本集 | 端口 |
---|---|
mongos | 27017 |
config server | 27019 |
sh1 | 25001 |
sh2 | 25002 |
sh3 | 25003 |
创建文件夹
mkdir -p /opt/data/mongo/logs
mkdir -p /opt/data/mongo/db/
mkdir -p /opt/data/mongo/db/sh1db
mkdir -p /opt/data/mongo/db/sh2db
mkdir -p /opt/data/mongo/db/sh3db
配置文件
mongos的配置rout.conf
systemLog:
path: "/opt/data/mongo/logs/route.log"
destination: "file"
quiet: true
logAppend: true
processManagement:
fork: true
net:
port: 27017
sharding:
configDB: "hsdatalab1:27019,hsdatalab2:27019,hsdatalab3:27019"
chunkSize: 256
config server 的配置config.conf:
storage:
dbPath: "/opt/data/mongo/db/config"
directoryPerDB: true
journal:
enabled: true
engine: "wiredTiger"
systemLog:
path: "/opt/data/mongo/logs/config.log"
destination: "file"
processManagement:
fork: true
net:
port: 27019
sharding:
clusterRole: "configsvr"
sh1 的配置sh1.conf
storage:
dbPath: "/opt/data/mongo/db/sh1db"
directoryPerDB: true
journal:
enabled: true
engine: "wiredTiger"
wiredTiger:
engineConfig:
cacheSizeGB: 4
collectionConfig:
blockCompressor: "snappy"
systemLog:
path: "/opt/data/mongo/logs/sh1.log"
destination: "file"
processManagement:
fork: true
net:
port: 25001
replication:
replSetName: "sh1"
sharding:
clusterRole: "shardsvr"
sh2的配置sh2.conf
storage:
dbPath: "/opt/data/mongo/db/sh2db"
directoryPerDB: true
journal:
enabled: true
engine: "wiredTiger"
wiredTiger:
engineConfig:
cacheSizeGB: 4
collectionConfig:
blockCompressor: "snappy"
systemLog:
path: "/opt/data/mongo/logs/sh2.log"
destination: "file"
processManagement:
fork: true
net:
port: 25002
replication:
replSetName: "sh2"
sharding:
clusterRole: "shardsvr"
sh3的配置sh3.conf
storage:
dbPath: "/opt/data/mongo/db/sh3db"
directoryPerDB: true
journal:
enabled: true
engine: "wiredTiger"
wiredTiger:
engineConfig:
cacheSizeGB: 4
collectionConfig:
blockCompressor: "snappy"
systemLog:
path: "/opt/data/mongo/logs/sh3.log"
destination: "file"
processManagement:
fork: true
net:
port: 25003
replication:
replSetName: "sh3"
sharding:
clusterRole: "shardsvr"
启动服务
mongos服务
./bin/mongos -f conf/route.conf
config server服务
./bin/mongos -f conf/config.conf
分片 服务
./bin/mongos -f conf/sh1.conf
./bin/mongos -f conf/sh2.conf
./bin/mongos -f conf/sh3.conf
配置复制集
配置shard
在hsdatalab1上,执行命令,登录mongo
./bin/mongo -port 25001
在mongo命令行输入窗口中输入如下内容
> var config = {
"_id" : "sh1",
"members" : [
{
"_id" : 0,
"host" : "hsdatalab1:25001"
},
{
"_id" : 1,
"host" : "hsdatalab2:25001"
},
{
"_id" : 2,
"host" : "hsdatalab3:25001"
}
]
}
> rs.initiate(config)
在hsdatalab2上,执行命令,登录mongo
./bin/mongo -port 25002
在mongo命令行输入窗口中输入如下内容
> var config = {
"_id" : "sh2",
"members" : [
{
"_id" : 0,
"host" : "hsdatalab1:25002"
},
{
"_id" : 1,
"host" : "hsdatalab2:25002"
},
{
"_id" : 2,
"host" : "hsdatalab3:25002"
}
]
}
> rs.initiate(config)
在hsdatalab3上,执行命令,登录mongo
./bin/mongo -port 25002
在mongo命令行输入窗口中输入如下内容
> var config = {
"_id" : "sh3",
"members" : [
{
"_id" : 0,
"host" : "hsdatalab1:25003"
},
{
"_id" : 1,
"host" : "hsdatalab2:25003"
},
{
"_id" : 2,
"host" : "hsdatalab3:25003"
}
]
}
> rs.initiate(config)
添加副本集分片到集群
登录任意一台服务器上执行:mongo
执行如下命令
sh.addShard( "sh1/hsdatalab1:25001" )
sh.addShard( "sh2/hsdatalab2:25002" )
sh.addShard( "sh3/hsdatalab3:25003" )