MongoDB的轮回重生(缩减规模)

我是。
即使对mongodb做了充分的准备,有时候也可能无法发展。
这种情况下就必须进行缩减规模。

這次是關於對未能成長的mongodb進行供奉,以小而微的形式進行輪迴轉生的故事。

条件与迁移前迁移后

    • 移行中はサービス停止を伴う

 

    • mongodbクラスタのシャードを削除するのではなく、新しく準備する

 

    • mongodumpで静止点バックアップを取得してmongorestoreでDB単位のリストアを実行する

 

    各mongodbクラスタに作られているデータベース及びコレクションはバッティングしないこと(潰してしまうので)

就是这样

    • mongodb cluster *2

 

    • cluster内のロール

conf * 3
shard * 2

replica set *2(member *3)

一共有18台,每台是9乘以2的计算结果。

假设每个应用服务器都在运行mongos,并通过mongos访问MongoDB集群。

要是

    • mongodb cluster *1

 

    • cluster内のロール

shard * 1
replica set *1
conf + replica set member *3

三台计算机

假设每个应用服务器都启动了mongos,并通过mongos访问了mongodb集群。

转型后蒙古的建设 de

安装MongoDB

如果使用Amazon Linux 2015.09,目前将安装mongodb 3.0.9-1。
兄弟,我们要用WiredTiger。

$ sudo yum install mongodb -y

MongoDB配置(元数据)的定义。

    /etc/mongoc.conf
# mongodb config

systemLog:
  destination: file
  path: /var/log/mongodb/mongod_config_27019.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod_config_27019.pid
net:
  port: 27019
storage:
  dbPath: "/var/lib/mongodb/mongoc"
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      journalCompressor: none # default snappy
    collectionConfig:
      blockCompressor: none # default snappy
sharding:
  clusterRole: "configsvr"
    /etc/init.d/mongoc

准备启动MongoDB配置的脚本。复制并修改使用yum安装的MongoDB init脚本。

    mongocの起動
$ sudo service mongoc start

MongoDB分片(副本集)的用途可概括为:

祈愿它能够再次茁壮成长,我将在replSetName中指定Origin00。

    /etc/mongod.conf
# mongodb mongod

systemLog:
  destination: file
  path: /var/log/mongodb/mongod_27017.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod_27017.pid
net:
  port: 27017
storage:
  dbPath: "/var/lib/mongodb/mongod"
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      journalCompressor: none # default snappy
    collectionConfig:
      blockCompressor: none # default snappy
replication:
  replSetName: "mongodb_replicaset00"
sharding:
  clusterRole: "shardsvr"
    /etc/init.d/mongod

我将创建一个启动mongod的脚本。
我将复制并修改通过yum安装的mongodb的init脚本。

    mongodの起動
$ sudo service mongod start

以上即为新环境下,MongoDB配置/服务已成功启动。

创建副本集

将三个分散的蒙古之心合为一个整体。

    Primaryにするmongodbノードで操作
$ mongo --port=27017
mongod> config = {   "_id": "mongodb_replicaset00",   "members": [     { "_id": 0, "host": '172.16.11.21:27017'},     { "_id": 1, "host": '172.16.11.22:27017'},     { "_id": 2, "host": '172.16.11.23:27017'}     ] }
mongod> rs.initiate(config);
PRIMARY

备份使用复制集成员的设置

由于存在三个副本集成员,我们将其中一台设置为隐藏状态。

    backup用replica set member

这次我们将”_id”:”1″的成员设为隐藏成员。

mongodb_replicaset00:PRIMARY> cfg = rs.config()
{
        "_id" : "mongodb_replicaset00",
        "version" : 2,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "172.16.11.21:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "172.16.11.22:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "172.16.11.23:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatTimeoutSecs" : 10,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                }
        }
}  
mongodb_replicaset00:PRIMARY> cfg.members[2].priority = 0
0
mongodb_replicaset00:PRIMARY> cfg.members[2].hidden = true
true
mongodb_replicaset00:PRIMARY> rs.reconfig(cfg)
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1455458942, 1),
                "electionId" : ObjectId("56c07ea680f80b802b651ba2")
        }
}
mongodb_replicaset00:PRIMARY>rs.config()
mongodb_replicaset00:PRIMARY> rs.config()
{
        "_id" : "mongodb_replicaset00",
        "version" : 2,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "172.16.11.21:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "172.16.11.22:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "172.16.11.23:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : true,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatTimeoutSecs" : 10,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                }
        }
}          

应用程序服务器(mongos)的配置

创建用于新集群的mongos定义

将连接定义创建到新的mongo集群。
将新的mongo集群的mongo配置节点的IP注册到DNS上。
(根据官方文档,建议将mongod节点的名称通过DNS或hosts进行解析。)

    /etc/mongos.conf
  # mongos(mongodb router)

systemLog:
  destination: file
  path: /var/log/mongodb/mongos.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongos.pid
net:
  port: 37017
sharding:
  configDB: mongodb-conf0.mongo.internal:27019,mongodb-conf1.mongo.internal:27019,mongodb-conf2.mongo.internal:27019
    /etc/init.d/mongos-new

我将复制并修改mongos启动脚本。

启动mongos

    command
$ sudo service mongos-new start

碎片的设定 de

在已完成配置的新mongos服务器上进行操作

增加碎片

$ mongo --port=37017
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("56c081bccabb5eff10c1c995")
}
  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("mongodb_replicaset00/172.16.11.21:27017");
{ "shardAdded" : "mongodb_replicaset00", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("56c081bccabb5eff10c1c995")
}
  shards:
        {  "_id" : "mongodb_replicaset00",  "host" : "mongodb_replicaset00/172.16.11.21:27017,172.16.11.22:27017,172.16.11.23:27017" }
  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" }

创建测试用数据库和集合

创建一个新的 MongoDB 数据库,并创建名为 “newshard_test” 的集合。

    mongosでの作業
mongos> use newmongodb
mongos> db.createCollection("newshard_test");
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1455458157, 1),
                "electionId" : ObjectId("56c07ea680f80b802b651ba2")
        }
}
    replica set member(primary)での確認

通过mongos创建的数据库和集合可以从PRIMARY服务器上确认。

$ mongo --port=37017
mongodb_replicaset00:PRIMARY> show dbs
config  0.000GB
local   0.000GB
newmongodb    0.000GB
mongodb_replicaset00:PRIMARY> use newmongodb
switched to db newmongodb
mongodb_replicaset00:PRIMARY> show collections;
newshard_test

插入测试文件

    newmongodb.newshard_testにnewshard_testというドキュメントを挿入する
mongos> db.createCollection("newshard_test");
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1455458157, 1),
                "electionId" : ObjectId("56c07ea680f80b802b651ba2")
        }
}

现在新创建的MongoDB集群已经准备就绪。

将数据从MongoDB迁移

    サービス停止

为了防止使用輪廻転生するモンゴ服务时进行DB写入操作,我们会进行维护。

从原来的环境中进行mongodump

    Balancerの停止とmongodump

这次,我们将按照前提条件通过mongos来进行mongodump。
在dump之前,请先停止Balancer。

    – Balancerの停止

我会对所有目标迁移的MongoDB集群执行停止Balancer的命令。

$ mongo --port=27017
mongos> sh.status();
mongos> sh.stopBalancer();
mongos> sh.disableBalancing(true);
mongos> sh.status();
※Balancerが停止していること
$ mongo --port=27117
mongos> sh.status();
mongos> sh.stopBalancer();
mongos> sh.disableBalancing(true);
mongos> sh.status();
※Balancerが停止していること

    mongodump

我们将通过mongos执行具有与mongodb集群相同数量的mongodump操作。

$ mongodump --port=27017 --out=mongodbcluster_shard_dump
$ mongodump --port=27117 --out=mongocluster2_shard_dump

将数据恢复到目标环境中使用mongorestore

执行db的mongorestore命令。

    full restoreはエラーになる

配置数据库无法进行恢复,会显示错误。

$ mongorestore --port=37017 --dir=mongodbcluster_shard_dump/
2016-02-14T23:50:39.692+0900    building a list of dbs and collections to restore from mongodbcluster_shard_dump/ dir
2016-02-14T23:50:39.693+0900    Failed: cannot do a full restore on a sharded system - remove the 'config' directory from the dump directory first
    db単位でmongorestoreする
$ mongorestore --port=37017 --db=mongodb --dir=mongodbcluster_shard_dump/mongodb/
2016-02-14T23:51:25.823+0900    building a list of collections to restore from mongodbcluster_shard_dump/mongodb/ dir
2016-02-14T23:51:25.860+0900    reading metadata file from mongodbcluster_shard_dump/mongodb/mongocollection.metadata.json
2016-02-14T23:51:25.862+0900    restoring mongodb.mongocollection from file mongodbcluster_shard_dump/mongodb/mongocollection.bson
2016-02-14T23:51:27.035+0900    restoring indexes for collection mongodb.mongocollection from metadata
2016-02-14T23:51:27.054+0900    finished restoring mongodb.mongocollection (33 documents)
2016-02-14T23:51:27.054+0900    done

确认在转移后

我会检查迁移的集合中的文档数量。
由于迁移前和迁移后的数量相同,因此成功完成了迁移。

    移行前のコレクション内ドキュメント件数
$ mongo --port=27017
MongoDB shell version: 3.0.9
connecting to: 127.0.0.1:27017/test
mongos> use mongodb;
switched to db mongodb
mongos> db.mongocollection.find().count();
33
    移行後のコレクション内ドキュメントの件数
$ mongo --port=37017
MongoDB shell version: 3.0.9
connecting to: 127.0.0.1:37017/test
mongos> use mongodb;
switched to db mongodb
mongos> db.mongocollection.find().count();
33
    shardの状態を確認

由于迁移前的分片密钥丢失了,但是这次我们将它缩小为一个分片,所以不需要恢复。

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("56c081bccabb5eff10c1c995")
}
  shards:
        {  "_id" : "mongodb_replicaset00",  "host" : "mongodb_replicaset00/172.16.11.21:27017,172.16.11.22:27017" }
  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" }
        {  "_id" : "newmongodb",  "partitioned" : false,  "primary" : "mongodb_replicaset00" }
        {  "_id" : "mongodb",  "partitioned" : false,  "primary" : "mongodb_replicaset00" }

mongos>

将应用程序(mongos)切换到新环境。

    • アプリケーションのmongosエンドポイントを新環境にアクセスするように変更します。

 

    移行前環境のmongodbクラスタにアクセスするmongosを停止します。

以上已完成转移和切换。

放棄先前的環境

如果在切换之后没有问题的话,将销毁之前的mongodb集群。

低语,结束声、祈祷。

结束了。

番茄酱

破片的缩放

只需要对Shard进行缩减而不需要重新制作的时候,可以在线操作。

使用removeShard。
需要执行两次removeShard。

流失 -> 狀態會從drop開始進行變化。

    シャードのdraining
mongos> sh.status();
移行前のシャード状態を確認する
mongos> use admin
mongos> db.runCommand( { removeShard: "shard01" } );
{
        "msg" : "draining ongoing",
        "state" : "ongoing",
        "remaining" : {
                "chunks" : NumberLong(0),
                "dbs" : NumberLong(2)
        },
        "note" : "you need to drop or movePrimary these databases",
        "dbsToMove" : [
                "mongocollection",
                "test"
        ],
        "ok" : 1
}
    シャードの確認とPrimaryシャードの変更

如果集合所属的主要分片是被删除的分片,那么在第二次执行removeShard时将会产生以下错误消息。

    削除対象のシャードにPrimaryコレクションが存在するとエラー
mongos> db.runCommand( { removeShard: "shard01" } );
{
        "msg" : "draining ongoing",
        "state" : "ongoing",
        "remaining" : {
                "chunks" : NumberLong(0),
                "dbs" : NumberLong(2)
        },
        "note" : "you need to drop or movePrimary these databases",
        "dbsToMove" : [
                "mongocollection",
                "test"
        ],
        "ok" : 1
}
    コレクションのPrimaryシャード変更
mongos> sh.status();
チャンクが全て残すシャードに寄ったことを確認します。
mongos> db.runCommand( { movePrimary: "mongocollection", to :"shard00" } );
{
        "primary " : "shard00:shard00/172.16.10.21:27017,172.16.10.22:27017,172.16.10.23:27017",
        "ok" : 1
}
mongos> sh.status()
コレクションのPrimaryシャードが削除対象ではないシャードになっていることを確認する
    シャードの削除

所有的区块都已移动到保留的分片上。
集合的主分片已成为保留的分片。

如果以上没问题,我会删除分片。再见~

mongos> use admin
mongos> db.runCommand( { removeShard: "shard01" } );
{
        "msg" : "removeshard completed successfully",
        "state" : "completed",
        "shard" : "shard01",
        "ok" : 1
}

結束的結束。

广告
将在 10 秒后关闭
bannerAds