一、架构简介

目标
单机搭建mongodb分布式集群(副本集 + 分片集群),演示mongodb分布式集群的安装部署、简单操作。

说明
在同一个vm启动由两个分片组成的分布式集群,每个分片都是一个PSS(Primary-Secondary-Secondary)模式的数据副本集;
Config副本集采用PSS(Primary-Secondary-Secondary)模式。

二、配置说明

  • 端口通讯
    当前集群中存在shard、config、mongos共12个进程节点,端口矩阵编排如下:
编号 实例类型
1 mongos
2 mongos
3 mongos
4 config
5 config
6 config
7 shard1
8 shard1
9 shard1
10 shard2
11 shard2
12 shard2
  • 内部鉴权
    节点间鉴权采用keyfile方式实现鉴权,mongos与分片之间、副本集节点之间共享同一套keyfile文件。 官方说明

  • 账户设置
    管理员账户:admin/Admin@01,具有集群及所有库的管理权限
    应用账号:appuser/AppUser@01,具有appdb的owner权限

关于初始化权限
keyfile方式默认会开启鉴权,而针对初始化安装的场景,Mongodb提供了localhost-exception机制
可以在首次安装时通过本机创建用户、角色,以及副本集初始操作。

三、准备工作

1. 下载安装包

官方地址:https://www.mongodb.com/download-center

  1. wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.3.tgz

2. 部署目录

解压压缩文件,将bin目录拷贝到目标路径/opt/local/mongo-cluster,参考以下命令:

  1. tar -xzvf mongodb-linux-x86_64-rhel70-3.6.3.tgz
  2. mkdir -p /opt/local/mongo-cluster
  3. cp -r mongodb-linux-x86_64-rhel70-3.6.3/bin /opt/local/mongo-cluster

3. 创建配置文件

  1. cd /opt/local/mongo-cluster
  2. mkdir conf

A. mongod 配置文件 mongo_node.conf
mongo_node.conf 作为mongod实例共享的配置文件,内容如下:

  1. storage:
  2. engine: wiredTiger
  3. directoryPerDB: true
  4. journal:
  5. enabled: true
  6. systemLog:
  7. destination: file
  8. logAppend: true
  9. operationProfiling:
  10. slowOpThresholdMs: 10000
  11. replication:
  12. oplogSizeMB: 10240
  13. processManagement:
  14. fork: true
  15. net:
  16. http:
  17. enabled: false
  18. security:
  19. authorization: "enabled"

选项说明可参考这里

B. mongos 配置文件 mongos.conf

  1. systemLog:
  2. destination: file
  3. logAppend: true
  4. processManagement:
  5. fork: true
  6. net:
  7. http:
  8. enabled: false

4. 创建keyfile文件

  1. cd /opt/local/mongo-cluster
  2. mkdir keyfile
  3. openssl rand -base64 756 > mongo.key
  4. chmod 400 mongo.key
  5. mv mongo.key keyfile

mongo.key 采用随机算法生成,用作节点内部通讯的密钥文件

5. 创建节点目录

  1. WORK_DIR=/opt/local/mongo-cluster
  2. mkdir -p $WORK_DIR/nodes/config/n1/data
  3. mkdir -p $WORK_DIR/nodes/config/n2/data
  4. mkdir -p $WORK_DIR/nodes/config/n3/data
  5. mkdir -p $WORK_DIR/nodes/shard1/n1/data
  6. mkdir -p $WORK_DIR/nodes/shard1/n2/data
  7. mkdir -p $WORK_DIR/nodes/shard1/n3/data
  8. mkdir -p $WORK_DIR/nodes/shard2/n1/data
  9. mkdir -p $WORK_DIR/nodes/shard2/n2/data
  10. mkdir -p $WORK_DIR/nodes/shard2/n3/data
  11. mkdir -p $WORK_DIR/nodes/mongos/n1
  12. mkdir -p $WORK_DIR/nodes/mongos/n2
  13. mkdir -p $WORK_DIR/nodes/mongos/n3

以config 节点1 为例,nodes/config/n1/data是数据目录,而pid文件、日志文件都存放于n1目录
以mongos 节点1 为例,nodes/mongos/n1 存放了pid文件和日志文件

四、搭建集群

1. Config副本集

按以下脚本启动3个Config实例

  1. WORK_DIR=/opt/local/mongo-cluster
  2. KEYFILE=$WORK_DIR/keyfile/mongo.key
  3. CONFFILE=$WORK_DIR/conf/mongo_node.conf
  4. MONGOD=$WORK_DIR/bin/mongod
  5. $MONGOD --port 26001 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n1/data --pidfilepath $WORK_DIR/nodes/config/n1/db.pid --logpath $WORK_DIR/nodes/config/n1/db.log --config $CONFFILE
  6. $MONGOD --port 26002 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n2/data --pidfilepath $WORK_DIR/nodes/config/n2/db.pid --logpath $WORK_DIR/nodes/config/n2/db.log --config $CONFFILE
  7. $MONGOD --port 26003 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n3/data --pidfilepath $WORK_DIR/nodes/config/n3/db.pid --logpath $WORK_DIR/nodes/config/n3/db.log --config $CONFFILE

待成功启动后,输出日志如下:

  1. about to fork child process, waiting until server is ready for connections.
  2. forked process: 4976
  3. child process started successfully, parent exiting

此时通过ps 命令也可以看到3个启动的进程实例。

连接其中一个Config进程,执行副本集初始化

  1. ./bin/mongo --port 26001 --host 127.0.0.1
  2. > MongoDB server version: 3.4.7
  3. > cfg={
  4. _id:"configReplSet",
  5. configsvr: true,
  6. members:[
  7. {_id:0, host:'127.0.0.1:26001'},
  8. {_id:1, host:'127.0.0.1:26002'},
  9. {_id:2, host:'127.0.0.1:26003'}
  10. ]};
  11. rs.initiate(cfg);

其中configsvr:true指明这是一个用于分片集群的Config副本集。
关于副本集配置可参考这里

2. 创建分片

按以下脚本启动Shard1的3个实例

  1. WORK_DIR=/opt/local/mongo-cluster
  2. KEYFILE=$WORK_DIR/keyfile/mongo.key
  3. CONFFILE=$WORK_DIR/conf/mongo_node.conf
  4. MONGOD=$WORK_DIR/bin/mongod
  5. echo "start shard1 replicaset"
  6. $MONGOD --port 27001 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n1/data --pidfilepath $WORK_DIR/nodes/shard1/n1/db.pid --logpath $WORK_DIR/nodes/shard1/n1/db.log --config $CONFFILE
  7. $MONGOD --port 27002 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n2/data --pidfilepath $WORK_DIR/nodes/shard1/n2/db.pid --logpath $WORK_DIR/nodes/shard1/n2/db.log --config $CONFFILE
  8. $MONGOD --port 27003 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n3/data --pidfilepath $WORK_DIR/nodes/shard1/n3/db.pid --logpath $WORK_DIR/nodes/shard1/n3/db.log --config $CONFFILE

待成功启动后,输出日志如下:

  1. about to fork child process, waiting until server is ready for connections.
  2. forked process: 5976
  3. child process started successfully, parent exiting

此时通过ps 命令也可以看到3个启动的Shard进程实例。

连接其中一个Shard进程,执行副本集初始化

  1. ./bin/mongo --port 27001 --host 127.0.0.1
  2. > MongoDB server version: 3.4.7
  3. > cfg={
  4. _id:"shard1",
  5. members:[
  6. {_id:0, host:'127.0.0.1:27001'},
  7. {_id:1, host:'127.0.0.1:27002'},
  8. {_id:2, host:'127.0.0.1:27003'}
  9. ]};
  10. rs.initiate(cfg);

参考以上步骤,启动Shard2的3个实例进程,并初始化副本集。

3. 启动mongos路由

执行以下脚本启动3个mongos进程

  1. WORK_DIR=/opt/local/mongo-cluster
  2. KEYFILE=$WORK_DIR/keyfile/mongo.key
  3. CONFFILE=$WORK_DIR/conf/mongos.conf
  4. MONGOS=$WORK_DIR/bin/mongos
  5. echo "start mongos instances"
  6. $MONGOS --port=25001 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n1/db.pid --logpath $WORK_DIR/nodes/mongos/n1/db.log --config $CONFFILE
  7. $MONGOS --port 25002 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n2/db.pid --logpath $WORK_DIR/nodes/mongos/n2/db.log --config $CONFFILE
  8. $MONGOS --port 25003 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n3/db.pid --logpath $WORK_DIR/nodes/mongos/n3/db.log --config $CONFFILE

待成功启动后,通过ps命令看到mongos进程:

  1. dbuser 7903 1 0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port=25001 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n1/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n1/db.log --config /opt/local/mongo-cluster/conf/mongos.conf
  2. dbuser 7928 1 0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port 25002 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n2/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n2/db.log --config /opt/local/mongo-cluster/conf/mongos.conf
  3. dbuser 7954 1 0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port 25003 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n3/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n3/db.log --config /opt/local/mongo-cluster/conf/mongos.conf

接入其中一个mongos实例,执行添加分片操作:

  1. ./bin/mongo --port 25001 --host 127.0.0.1
  2. mongos> MongoDB server version: 3.4.7
  3. mongos> sh.addShard("shard1/127.0.0.1:27001")
  4. { "shardAdded" : "shard1", "ok" : 1 }
  5. mongos> sh.addShard("shard2/127.0.0.1:27004")
  6. { "shardAdded" : "shard2", "ok" : 1 }

至此,分布式集群架构启动完毕,但进一步操作需要先添加用户。

4. 初始化用户

接入其中一个mongos实例,添加管理员用户

  1. use admin
  2. db.createUser({
  3. user:'admin',pwd:'Admin@01',
  4. roles:[
  5. {role:'clusterAdmin',db:'admin'},
  6. {role:'userAdminAnyDatabase',db:'admin'},
  7. {role:'dbAdminAnyDatabase',db:'admin'},
  8. {role:'readWriteAnyDatabase',db:'admin'}
  9. ]})

当前admin用户具有集群管理权限、所有数据库的操作权限。
需要注意的是,在第一次创建用户之后,localexception不再有效,接下来的所有操作要求先通过鉴权。

  1. use admin
  2. db.auth('admin','Admin@01')

检查集群状态

  1. mongos> sh.status()
  2. --- Sharding Status ---
  3. sharding version: {
  4. "_id" : 1,
  5. "minCompatibleVersion" : 5,
  6. "currentVersion" : 6,
  7. "clusterId" : ObjectId("5aa39c3e915210dc501a1dc8")
  8. }
  9. shards:
  10. { "_id" : "shard1", "host" : "shard1/127.0.0.1:27001,127.0.0.1:27002,127.0.0.1:27003", "state" : 1 }
  11. { "_id" : "shard2", "host" : "shard2/127.0.0.1:27004,127.0.0.1:27005,127.0.0.1:27006", "state" : 1 }
  12. active mongoses:
  13. "3.4.7" : 3
  14. autosplit:
  15. Currently enabled: yes

集群用户
分片集群中的访问都会通过mongos入口,而鉴权数据是存储在config副本集中的,即config实例中system.users数据库存储了集群用户及角色权限配置。mongos与shard实例则通过内部鉴权(keyfile机制)完成,因此shard实例上可以通过添加本地用户以方便操作管理。在一个副本集上,只需要在Primary节点上添加用户及权限,相关数据会自动同步到Secondary节点。
关于集群鉴权
在本案例中,我们为两个分片副本集都添加了本地admin用户。

通过mongostat工具可以显示集群所有角色:

  1. host insert query update delete getmore command dirty used flushes mapped vsize res faults qrw arw net_in net_out conn set repl time
  2. 127.0.0.1:27001 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.49G 44.0M n/a 0|0 0|0 429b 56.1k 25 shard1 PRI Mar 10 19:05:13.928
  3. 127.0.0.1:27002 *0 *0 *0 *0 0 7|0 0.1% 0.1% 0 1.43G 43.0M n/a 0|0 0|0 605b 55.9k 15 shard1 SEC Mar 10 19:05:13.942
  4. 127.0.0.1:27003 *0 *0 *0 *0 0 7|0 0.1% 0.1% 0 1.43G 43.0M n/a 0|0 0|0 605b 55.9k 15 shard1 SEC Mar 10 19:05:13.946
  5. 127.0.0.1:27004 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.48G 43.0M n/a 0|0 0|0 546b 55.8k 18 shard2 PRI Mar 10 19:05:13.939
  6. 127.0.0.1:27005 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.43G 42.0M n/a 0|0 0|0 540b 54.9k 15 shard2 SEC Mar 10 19:05:13.944
  7. 127.0.0.1:27006 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.46G 44.0M n/a 0|0 0|0 540b 54.9k 17 shard2 SEC Mar 10 19:05:13.936

五、数据操作

在案例中,创建appuser用户、为数据库实例appdb启动分片。

  1. use appdb
  2. db.createUser({user:'appuser',pwd:'AppUser@01',roles:[{role:'dbOwner',db:'appdb'}]})
  3. sh.enableSharding("appdb")

创建集合book,为其执行分片初始化。

  1. use appdb
  2. db.createCollection("book")
  3. db.device.ensureIndex({createTime:1})
  4. sh.shardCollection("appdb.book", {bookId:"hashed"}, false, { numInitialChunks: 4} )

继续往device集合写入1000W条记录,观察chunks的分布情况

  1. use appdb
  2. var cnt = 0;
  3. for(var i=0; i<1000; i++){
  4. var dl = [];
  5. for(var j=0; j<100; j++){
  6. dl.push({
  7. "bookId" : "BBK-" + i + "-" + j,
  8. "type" : "Revision",
  9. "version" : "IricSoneVB0001",
  10. "title" : "Jackson's Life",
  11. "subCount" : 10,
  12. "location" : "China CN Shenzhen Futian District",
  13. "author" : {
  14. "name" : 50,
  15. "email" : "RichardFoo@yahoo.com",
  16. "gender" : "female"
  17. },
  18. "createTime" : new Date()
  19. });
  20. }
  21. cnt += dl.length;
  22. db.book.insertMany(dl);
  23. print("insert ", cnt);
  24. }

执行db.book.getShardDistribution(),输出如下:

  1. Shard shard1 at shard1/127.0.0.1:27001,127.0.0.1:27002,127.0.0.1:27003
  2. data : 13.41MiB docs : 49905 chunks : 2
  3. estimated data per chunk : 6.7MiB
  4. estimated docs per chunk : 24952
  5. Shard shard2 at shard2/127.0.0.1:27004,127.0.0.1:27005,127.0.0.1:27006
  6. data : 13.46MiB docs : 50095 chunks : 2
  7. estimated data per chunk : 6.73MiB
  8. estimated docs per chunk : 25047
  9. Totals
  10. data : 26.87MiB docs : 100000 chunks : 4
  11. Shard shard1 contains 49.9% data, 49.9% docs in cluster, avg obj size on shard : 281B
  12. Shard shard2 contains 50.09% data, 50.09% docs in cluster, avg obj size on shard : 281B

总结

    • Mongodb集群架构由Mongos、Config副本集和多个分片组成;
      安装过程中先初始化Config副本集、分片副本集,最后通过Mongos添加分片
    • Config副本集存储了集群访问的用户及角色权限,为了方便管理,可以给分片副本集添加本地用户
    • Mongodb提供了LocalException机制,首次安装数据库时可以在本机直接添加用户
      • from: https://www.cnblogs.com/littleatp/p/8563273.html

mongodb分布式集群搭建手记的更多相关文章

  1. mongo分布式集群搭建手记

    一.架构简介 目标 单机搭建mongodb分布式集群(副本集 + 分片集群),演示mongodb分布式集群的安装部署.简单操作. 说明 在同一个vm启动由两个分片组成的分布式集群,每个分片都是一个PS ...

  2. MongoDB分布式集群搭建

    最近在做一个关于车险的项目,由于数据量较大,实验室的Boss决定采用HBase+ES/MongoDB这两种方案,并做性能对比,本人负责MongoDB方案.为了满足海量数据的存储要求,需要搭建一个分布式 ...

  3. MongoDB分布式集群搭建(分片加副本集)

    # 环境准备 服务器 # 环境搭建 文件配置和目录添加 新建目录的操作要在三台机器中进行,为配置服务器新建数据目录和日志目录 mkdir -p $MONGODB_HOME/config/data mk ...

  4. Hadoop上路-01_Hadoop2.3.0的分布式集群搭建

    一.配置虚拟机软件 下载地址:https://www.virtualbox.org/wiki/downloads 1.虚拟机软件设定 1)进入全集设定 2)常规设定 2.Linux安装配置 1)名称类 ...

  5. hadoop伪分布式集群搭建与安装(ubuntu系统)

    1:Vmware虚拟软件里面安装好Ubuntu操作系统之后使用ifconfig命令查看一下ip; 2:使用Xsheel软件远程链接自己的虚拟机,方便操作.输入自己ubuntu操作系统的账号密码之后就链 ...

  6. Hadoop分布式集群搭建

    layout: "post" title: "Hadoop分布式集群搭建" date: "2017-08-17 10:23" catalog ...

  7. hbase分布式集群搭建

    hbase和hadoop一样也分为单机版.伪分布式版和完全分布式集群版本,这篇文件介绍如何搭建完全分布式集群环境搭建. hbase依赖于hadoop环境,搭建habase之前首先需要搭建好hadoop ...

  8. 分布式实时日志系统(四) 环境搭建之centos 6.4下hbase 1.0.1 分布式集群搭建

    一.hbase简介 HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java.它是Apache软件基金会的Hadoop项目的一部分,运行 ...

  9. kafka系列二:多节点分布式集群搭建

    上一篇分享了单节点伪分布式集群搭建方法,本篇来分享一下多节点分布式集群搭建方法.多节点分布式集群结构如下图所示: 为了方便查阅,本篇将和上一篇一样从零开始一步一步进行集群搭建. 一.安装Jdk 具体安 ...

随机推荐

  1. ResourceBundle.getBundle方法demo

    这个参考链接 http://blog.csdn.net/tgyman/article/details/56012706

  2. ubuntu下Sprak(IDE)wordcount例子

    一.进入IDE界面 cd ~/Downloads/idea/bin idea.sh 二.建立scala项目 Step 1:导入Spark-hadoop对应的包,次选择“File”–> “Proj ...

  3. 使用 jquery jroll2 开发仿qq聊天列表侧滑功能

    由于开发需求,需要做一个类似qq的聊天界面,侧滑弹出单条item右侧菜单,菜单可点击,效果如下图(包括点击事件+长按事件): 1.项目主体dom和css 页面结构比较简单,顶部header做了fixe ...

  4. NLP文本相似度(TF-IDF)

    本篇博文是数据挖掘部分的首篇,思路主要是先聊聊相似度的理论部分,下一篇是代码实战.       我们在比较事物时,往往会用到“不同”,“一样”,“相似”等词语,这些词语背后都涉及到一个动作——双方的比 ...

  5. BZOJ.4516.[SDOI2016]生成魔咒(后缀数组 RMQ)

    题目链接 后缀自动机做法见这(超好写啊). 后缀数组是可以做的: 本质不同的字符串的个数为 \(子串个数-\sum_{ht[i]}\),即 \(\frac{n(n+1)}{2}-\sum_{ht[i] ...

  6. BZOJ3712[PA2014]Fiolki 建图+倍增lca

    居然是一道图论题 毫无思路 我们对于每一次的融合操作 $(a,b)$ 建一个新点$c$ 并向$a,b$连边 再将$b$瓶当前的位置赋成$c$ 这样子我们就可以建成一个森林 现在枚举每一种反应$M_i$ ...

  7. Codeforces Round #396 (Div. 2) B. Mahmoud and a Triangle 贪心

    B. Mahmoud and a Triangle 题目连接: http://codeforces.com/contest/766/problem/B Description Mahmoud has ...

  8. 使用 IntraWeb (2) - Hello IntraWeb

    IntraWeb 比我相像中的更贴近 VCL, 传统的非可视组件在这里大都可用(其内部很多复合属性是 TStringList 类型的), 它的诸多可视控件也是从 TControl 继承下来的. 这或许 ...

  9. Failed to connect socket to '/var/run/libvirt/libvirt-sock'的问题解决

    1.增加libvirtd用户组 groupadd libvirtd 2.设置用户到组 sudo usermod -a -G libvirtd $USER 3.设置启动libvirtd服务的用户组 vi ...

  10. linux无锁化编程--__sync_fetch_and_add系列原子操作函数

    linux支持的哪些操作是具有原子特性的?知道这些东西是理解和设计无锁化编程算法的基础. 下面的东西整理自网络.先感谢大家的分享! __sync_fetch_and_add系列的命令,发现这个系列命令 ...