澳门网络娱乐游戏平台-澳门电子游戏娱乐网址-官方直营

【转】MongoDB 分片的原理、搭建、应用

用A库来还原B库

 

 

一、概念:

  1. 对正值利用的B库实行还原,还原时改革数据库名称,还原出错,提醒数据库正在使用。删除B库,如故提示正在利用,认为像活死人

    大盛娱乐就上01311澳门 1

      分片(sharding)是指将数据库拆分,将其疏散在差别的机器上的历程。将数据分散到不相同的机械上,无需成效强大的服务器就能够积存更加多的数码和管理越来越大的负载。着力思谋就算将集结切成小块,那个块分散到若干片里,种种片只担负总的数量据的少年老成局地,最终经过三个均衡器来对少年老成一分片实行均衡(数据迁移)。通过一个名称叫mongos的路由进程展开操作,mongos知道多少和片的对应关系(通过配备服务器)。抢先50%利用情状都以竭泽而渔磁盘空间的主题材料,对于写入有极大希望会变差(+++里面的印证+++),查询则尽量制止跨分片查询。使用分片的机缘:

 

1,机器的磁盘不够用了。使用分片解决磁盘空间的问题。
2,单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
3,想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。

 

二、安顿安装: 前提是安装了mongodb(本文用3.0测试)

  1. 重启SQL SE奥迪Q3VECRUISER,因B库已去除,在A库上点击还原按键,但在对话中将目的库名改为B,奇迹来了,B库还原成功,A库却恒久踏入苏醒状态

在搭建分片此前,先领会下分片中逐生机勃勃剧中人物的功用。

大盛娱乐就上01311澳门 2

① 配置服务器。是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最先开始建立,启用日志功能。像启动普通的mongod一样启动配置服务器,指定configsvr选项。不需要太多的空间和资源,配置服务器的1KB空间相当于真是数据的200MB。保存的只是数据的分布表。当服务不可用,则变成只读,无法分块、迁移数据。
② 路由服务器。即mongos,起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息,开启mongos进程需要知道配置服务器的地址,指定configdb选项。
③ 分片服务器。是一个独立普通的mongod进程,保存数据信息。可以是一个副本集也可以是单独的一台服务器。

 

配置情形:3台机子

  1. 实践RESTORE DATABASE A库名 WITH RECOVE君越Y,数据库能够扩充了翻看数据了,但只怕 会有特地 的气象,最佳依旧重启sql server

A:配置(3)、路由1、分片1;

 

B:分片2,路由2;

C:分片3

      在安排在此以前先驾驭片键的含义,八个好的片键对分片至关心珍视要。片键必须是一个索引,数据依附那几个片键进行拆分分散。通过sh.shardCollection加会自动创建索引。叁个自增的片键对写入和数目均匀布满就不是很好,因为自增的片键总会在叁个分片上写入,后续到达某些阀值恐怕会写到别的分片。可是遵照片键查询会超级高效。随机片键对数码的均匀分布效果很好。注意尽量防止在三个分片上举办询问。在有着分片上查询,mongos会对结果开展归拢列排在一条线序。

开头下边这个劳动,因为在后台运维,所以用配备文件运维,配备文件表明。

1)安排服务器的启航。(A上开启3个,Port:二零零三0、21000、2二零零三卡塔尔(英语:State of Qatar) 

配备服务器是二个平常的mongod进度,所以只须求新开八个实例就可以。布置服务器必需开启1个或则3个,开启2个则会报错

BadValue need either 1 or 3 configdbs

因为要松手后台用用配置文件运行,须要改正配置文件:

/etc/mongod_20000.conf

#数据目录
dbpath=/usr/local/config/
#日志文件
logpath=/var/log/mongodb/mongodb_config.log
#日志追加
logappend=true
#端口
port = 20000
#最大连接数
maxConns = 50
pidfilepath = /var/run/mongo_20000.pid
#日志,redo log
journal = true
#刷写提交机制
journalCommitInterval = 200
#守护进程模式
fork = true
#刷写数据到日志的频率
syncdelay = 60
#storageEngine = wiredTiger
#操作日志,单位M
oplogSize = 1000
#命名空间的文件大小,默认16M,最大2G。
nssize = 16
noauth = true
unixSocketPrefix = /tmp
configsvr = true

/etc/mongod_21000.conf

数据目录
dbpath=/usr/local/config1/
#日志文件
logpath=/var/log/mongodb/mongodb_config1.log
#日志追加
logappend=true
#端口
port = 21000
#最大连接数
maxConns = 50
pidfilepath = /var/run/mongo_21000.pid
#日志,redo log
journal = true
#刷写提交机制
journalCommitInterval = 200
#守护进程模式
fork = true
#刷写数据到日志的频率
syncdelay = 60
#storageEngine = wiredTiger
#操作日志,单位M
oplogSize = 1000
#命名空间的文件大小,默认16M,最大2G。
nssize = 16
noauth = true
unixSocketPrefix = /tmp
configsvr = true

翻开配置服务器:

root@mongo1:~# mongod -f /etc/mongod_20000.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 8545
child process started successfully, parent exiting

root@mongo1:~# mongod -f /etc/mongod_21000.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 8595
child process started successfully, parent exiting

同理再起一个22002端口的安排服务器。

大盛娱乐就上01311澳门 3大盛娱乐就上01311澳门 4

#数据目录
dbpath=/usr/local/config2/
#日志文件
logpath=/var/log/mongodb/mongodb_config2.log
#日志追加
logappend=true
#端口
port = 22000
#最大连接数
maxConns = 50
pidfilepath = /var/run/mongo_22000.pid
#日志,redo log
journal = true
#刷写提交机制
journalCommitInterval = 200
#守护进程模式
fork = true
#刷写数据到日志的频率
syncdelay = 60
#storageEngine = wiredTiger
#操作日志,单位M
oplogSize = 1000
#命名空间的文件大小,默认16M,最大2G。
nssize = 16

noauth = true
unixSocketPrefix = /tmp

configsvr = true

View Code

2)路由服务器的启航。(A、B上各开启1个,Port:30000卡塔尔(英语:State of Qatar)

路由服务器不保留数据,把日记记录一下就能够。

# mongos

#日志文件
logpath=/var/log/mongodb/mongodb_route.log
#日志追加
logappend=true
#端口
port = 30000
#最大连接数
maxConns = 100
#绑定地址
#bind_ip=192.168.200.*,...,

pidfilepath = /var/run/mongo_30000.pid

configdb=192.168.200.A:20000,192.168.200.A:21000,192.168.200.A:22000  #必须是1个或则3个配置 。

#configdb=127.0.0.1:20000  #报错

#守护进程模式 fork = true

中间最要害的参数是configdb,不可能在其前面带的布署服务器的地点写成localhost或则127.0.0.1,需求设置成别的分片也能访谈的地址,即192.168.200.A:20020/21000/22002。不然在addshard的时候会报错:

{
"ok" : 0,
"errmsg" : "can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs  host: 172.16.5.104:20000 isLocalHost:0"
}

开启mongos:

root@mongo1:~# mongos -f /etc/mongod_30000.conf 
2015-07-10T14:42:58.741+0800 W SHARDING running with 1 config server should be done only for testing purposes and is not recommended for production
about to fork child process, waiting until server is ready for connections.
forked process: 8965
child process started successfully, parent exiting

3)分片服务器的开发银行:

就是二个日常的mongod进程:

root@mongo1:~# mongod -f /etc/mongod_40000.conf 
note: noprealloc may hurt performance in many applications
about to fork child process, waiting until server is ready for connections.
forked process: 9020
child process started successfully, parent exiting

A服务器下边包车型客车服务开启达成

root@mongo1:~# ps -ef | grep mongo
root      9020     1  0 14:47 ?        00:00:06 mongod -f /etc/mongod_40000.conf
root      9990     1  0 15:14 ?        00:00:02 mongod -f /etc/mongod_20000.conf
root     10004     1  0 15:14 ?        00:00:01 mongod -f /etc/mongod_21000.conf
root     10076     1  0 15:20 ?        00:00:00 mongod -f /etc/mongod_22000.conf
root     10096     1  0 15:20 ?        00:00:00 mongos -f /etc/mongod_30000.conf

安分守己地方的艺术再到B上开启分片服务和路由服务(配置文件少年老成律卡塔尔国,以至在C上开启分片服务。到此分片的构造服务器、路由服务器、分片服务器皆已安顿产生。

三、配置分片:下边的操作都是在mongodb的通令行里施行

1)增多分片大盛娱乐就上01311澳门,:sh.addShard("IP:Port") 

登陆路由服务器mongos 操作:

root@mongo1:~# mongo --port=30000
MongoDB shell version: 3.0.4
connecting to: 127.0.0.1:30000/test
mongos> 

增加分片:

mongos> sh.status()    #查看集群的信息
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "minCompatibleVersion" : 5,
    "currentVersion" : 6,
    "clusterId" : ObjectId("559f72470f93270ba60b26c6")
}
  shards:
  balancer:
    Currently enabled:  yes
    Currently running:  no
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours: 
        No recent migrations
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }

mongos> sh.addShard("192.168.200.A:40000") #添加分片
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard("192.168.200.B:40000") #添加分片
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> sh.addShard("192.168.200.C:40000") #添加分片
{ "shardAdded" : "shard0002", "ok" : 1 }

mongos> sh.status()    #查看集群信息
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "minCompatibleVersion" : 5,
    "currentVersion" : 6,
    "clusterId" : ObjectId("559f72470f93270ba60b26c6")
}
  shards:  #分片信息
    {  "_id" : "shard0000",  "host" : "192.168.200.A:40000" }
    {  "_id" : "shard0001",  "host" : "192.168.200.B:40000" }
    {  "_id" : "shard0002",  "host" : "192.168.200.C:40000" }
  balancer:
    Currently enabled:  yes
    Currently running:  no
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours: 
        No recent migrations
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }

2)开启分片成效:sh.enableSharding("库名"卡塔尔国、sh.shardCollection("库名.会集名",{"key":1})

mongos> sh.enableSharding("dba")  #首先对数据库启用分片
{ "ok" : 1 }
mongos> sh.status()               #查看分片信息
--- Sharding Status ---...
...
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
    {  "_id" : "dba",  "partitioned" : true,  "primary" : "shard0000" }

mongos> sh.shardCollection("dba.account",{"name":1})    #再对集合进行分片,name字段是片键。片键的选择:利于分块、分散写请求、查询数据。
{ "collectionsharded" : "dba.account", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---...
  shards:
    {  "_id" : "shard0000",  "host" : "192.168.200.51:40000" }
    {  "_id" : "shard0001",  "host" : "192.168.200.52:40000" }
    {  "_id" : "shard0002",  "host" : "192.168.200.53:40000" }
...
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
    {  "_id" : "dba",  "partitioned" : true,  "primary" : "shard0000" }  #库
        dba.account
            shard key: { "name" : 1 }                                    #集合
            chunks:
                shard0000    1
            { "name" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0) 

地点加粗部分代表分片新闻已经陈设完结。借使现身:

too many chunks to print, use verbose if you want to force print

想要见到详细的消息则须求实施:

mongos> sh.status({"verbose":1})
或则
mongos> db.printShardingStatus("vvvv")
或则
mongos> printShardingStatus(db.getSisterDB("config"),1)

四、测试 :对dba库的account集结实行测验,随机写入,查看是不是分散到3个分片中。

认清是或不是为shard:db.runCommand({isdbgrid:1}卡塔尔(قطر‎

mongos> db.runCommand({isdbgrid:1})
{ "isdbgrid" : 1, "hostname" : "mongo3c", "ok" : 1 }

经过二个python脚本实行猖獗写入:分别向A、B 2个mongos各写入10万条记下。

大盛娱乐就上01311澳门 5大盛娱乐就上01311澳门 6

#!/usr/bin/env python
#-*- coding:utf-8 -*-
#随即写MongoDB Shard 测试

import pymongo
import time
from random import Random
def random_str(randomlength=8):
    str = ''
    chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
    length = len(chars) - 1
    random = Random()
    for i in range(randomlength):
        str+=chars[random.randint(0, length)]
        return str

def inc_data(conn):
    db = conn.dba
#    db = conn.test
    collection = db.account
    for i in range(100000):
        str = ''
        chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
        length = len(chars) - 1
        random = Random()
        for i in range(15):
            str+=chars[random.randint(0, length)]
            string = str
        collection.insert({"name" : string, "age" : 123+i, "address" : "hangzhou"+string})

if __name__ =='__main__':
    conn = pymongo.MongoClient(host='192.168.200.A/B',port=30000)

    StartTime = time.time()
    print "===============$inc==============="
    print "StartTime : %s" %StartTime
    inc_data(conn)
    EndTime = time.time()
    print "EndTime : %s" %EndTime
    CostTime = round(EndTime-StartTime)
    print "CostTime : %s" %CostTime

View Code

查看是不是分片:db.collection.stats()

mongos> db.account.stats() #查看集合的分布情况
...
...
    "shards" : {
        "shard0000" : {
            "ns" : "dba.account",
            "count" : 89710,
            "size" : 10047520,
...
...
        "shard0001" : {
            "ns" : "dba.account",
            "count" : 19273,
            "size" : 2158576,
...
...
        "shard0002" : {
            "ns" : "dba.account",
            "count" : 91017,
            "size" : 10193904,
...
...

上面加粗部分为汇集的主导音讯,能够看出分片成功,种种分片都有数据(count卡塔尔(قطر‎。到此MongoDB分片集群搭建设成功。

++++++++++++++++++++++++++++++++++++++++++++++++

感兴趣的同学能够看上边那一个比较有趣的场馆:

#在写之前分片的基本信息:
mongos> sh.status()
--- Sharding Status --- 
...
...
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
    {  "_id" : "dba",  "partitioned" : true,  "primary" : "shard0000" }
        dba.account
            shard key: { "name" : 1 }
            chunks:
                shard0000    1
            { "name" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0)   #可以看到这里片键的写入,都是写在shard0000里面的。

#在写期间的分片基本信息:
mongos> sh.status()
--- Sharding Status --- 
...
...
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
    {  "_id" : "dba",  "partitioned" : true,  "primary" : "shard0000" }
        dba.account
            shard key: { "name" : 1 }
            chunks:          #数据块分布
                shard0000    1
                shard0001    1
                shard0002    1
            { "name" : { "$minKey" : 1 } } -->> { "name" : "5yyfY8mmR5HyhGJ" } on : shard0001 Timestamp(2, 0) 
            { "name" : "5yyfY8mmR5HyhGJ" } -->> { "name" : "woQAv99Pq1FVoMX" } on : shard0002 Timestamp(3, 0) 
            { "name" : "woQAv99Pq1FVoMX" } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(3, 1)   #可以看到片键写入的基本分布

#在写完成后的基本信息:
mongos> sh.status()
--- Sharding Status --- 
...
...
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
    {  "_id" : "dba",  "partitioned" : true,  "primary" : "shard0000" }
        dba.account
            shard key: { "name" : 1 }
            chunks:          #数据块分布
                shard0000    2
                shard0001    1
                shard0002    2
            { "name" : { "$minKey" : 1 } } -->> { "name" : "5yyfY8mmR5HyhGJ" } on : shard0001 Timestamp(2, 0) 
            { "name" : "5yyfY8mmR5HyhGJ" } -->> { "name" : "UavMbMlfszZOFrz" } on : shard0000 Timestamp(4, 0) 
            { "name" : "UavMbMlfszZOFrz" } -->> { "name" : "t9LyVSNXDmf6esP" } on : shard0002 Timestamp(4, 1) 
            { "name" : "t9LyVSNXDmf6esP" } -->> { "name" : "woQAv99Pq1FVoMX" } on : shard0002 Timestamp(3, 4) 
            { "name" : "woQAv99Pq1FVoMX" } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(3, 1)  #最后片键写入的分布

上面加粗的新闻比较上看出,本来在每一个分片上都唯有二个块,最后在shard0000、shard0002上有2个块,被拆分了。shard0001不改变。那是因为mongos在接到写央求的时候,会检讨当前块的拆分阀值点。达到该阀值的时候,会向分片发起三个拆分的央求。例子中shard0000和shard0002里的块被拆分了。分片内的数额开展了搬迁(有早晚的损耗),最终经过三个均衡器来对数码举行改动分配。所以在写入途中假使看见叁个分片中集中的多寡变小也是正常的。

balancer:  #均衡器
    Currently enabled:  yes
    Currently running:  yes   #正在转移
        Balancer lock taken at Fri Jul 10 2015 22:57:27 GMT+0800 (CST) by mongo2:30000:1436540125:1804289383:Balancer:846930886

均衡器:均衡器担任数据迁移,周期性的检讨分片是不是存在不均匀,假若不设有则会开首块的迁徙,config.locks集结里的state表示均衡器是不是找正在运作,0表示非活动状态,2表示正在均衡。均衡迁移数据的经过会增加系统的负载:指标分片必需查询源分片的有着文书档案,将文书档案插入指标分片中,再覆灭源分片的多寡。能够关闭均衡器(不提议):关闭会招致各分片数据布满不均匀,磁盘空间得不到平价的应用。 

mongos> sh.setBalancerState(false)  #关闭自动均衡器,手动均衡,打开:sh.setBalancerState(true)
mongos> db.settings.find()          #查看均衡器状态
{ "_id" : "balancer", "stopped" : true }

可认为均衡器设置贰个平均时间窗口:activeWindow

mongos> db.settings.update({"_id":"balancer"},{"$set":{"activeWindow":{"start":"08:00","stop":"02:00"}}},true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find({"_id":"balancer"})
{ "_id" : "balancer", "stopped" : false, "activeWindow" : { "start" : "08:00", "stop" : "02:00" } }

上面表明:均衡只会在上午8点到下午2点开展平衡操作。均衡器是以块的多寡作为迁移目标,而非数据大小,块的分寸暗中同意是64M,能够改善:(config.settings)

mongos> db.settings.find()
{ "_id" : "chunksize", "value" : 64 }
mongos> db.settings.save({"_id":"chunksize","value":32})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find()
{ "_id" : "chunksize", "value" : 32 }

上边把块的暗许大小改成了32M,除了通过均衡器自动员搬迁移外,还是能手动员搬迁移数据sh.moveChunk("db.collection",{块地点},"新剧名称"卡塔尔国

mongos> db.chunks.find({"_id" : "abc.account-name_"wPeFnJEvendSTbH""}).pretty() #先到config.chunks上任意找一个块
{
    "_id" : "abc.account-name_"wPeFnJEvendSTbH"",
    "lastmod" : Timestamp(3, 1),
    "lastmodEpoch" : ObjectId("55a52ff1fdd9a605a0371327"),
    "ns" : "abc.account",
    "min" : {
        "name" : "wPeFnJEvendSTbH"              #被移动的块
    },
    "max" : {
        "name" : { "$maxKey" : 1 }
    },
    "shard" : "shard0000"                       #原先所在的分片
}
mongos> sh.moveChunk("abc.account",{"name" : "wPeFnJEvendSTbH"},"mablevi")  #把abc.account集合中包含name(片键)为""的快迁移到mablevi分片中
{ "millis" : 6800, "ok" : 1 }
mongos> db.chunks.find({"_id" : "abc.account-name_"wPeFnJEvendSTbH""}).pretty()  
{
    "_id" : "abc.account-name_"wPeFnJEvendSTbH"",
    "lastmod" : Timestamp(5, 0),
    "lastmodEpoch" : ObjectId("55a52ff1fdd9a605a0371327"),
    "ns" : "abc.account",
    "min" : {
        "name" : "wPeFnJEvendSTbH"
    },
    "max" : {
        "name" : { "$maxKey" : 1 }
    },
    "shard" : "mablevi"                        #已被迁移到新片
}

上面是手动移动多少的操作,数据被活动。 借使块超过了64M限定【原因是片键没选好(日期、状态值等卡塔尔(قطر‎,导致三个块Infiniti叠合】,则无从张开自动均衡,不可能分块。有2个点子:1是加大块的大小(setting),2是拆分sh.splitAt()(推荐)。

之所以假若碰见分片写入比单点写入慢正是因为分片路由劳动(mongos)要求珍爱元数据、数据迁移、路由开采等

++++++++++++++++++++++++++++++++++++++++++++++++

五、高可用:Sharding+Replset

上边的分片都是单点的,若是一个分片坏了,则数据会抛弃,利用以前减少的别本集,能不能够把别本集参预到分片中?下边就来评释下。

1)加上别本集分片服务器(mmm别本集名称):这里测量试验就只对三个分片加别本集,要兑现完全的高可用就须要对具有分片加副本集,幸免单点故障

本文由澳门网络娱乐游戏平台发布于数据库,转载请注明出处:【转】MongoDB 分片的原理、搭建、应用

相关阅读