中原玛瑙 發表於 2024-4-23 09:22:00

使用Docker搭建MongoDB 5.0版本副本集集群

<h4 id="1mongodb集群">1、mongodb集群</h4>
<p>首先我们需要了解mongodb的集群模式,mongodb安装分为单机安装和集群安装。集群安装分为:主从复制(Master-Slaver)集群、副本集(Replica Set)集群和分片集群(Sharded Cluster)。MongoDB的主从复制(Master-Slave Replication)已不再是官方推荐的特性,并且在未来的版本中可能会被移除。MongoDB官方推荐使用副本集(Replica Set)作为高可用性的解决方案。</p>
<h5 id="11主从复制存在的问题">1.1主从复制存在的问题</h5>
<ul>
<li>单点故障:Master节点故障时,没有自动故障转移机制。</li>
<li>数据量有限:Slave节点数据通常不可写,限制了数据总量的增长。</li>
<li>延迟和同步问题:Slave节点可能会落后于Master,导致数据延迟。</li>
<li>资源利用率低:需要额外资源来运行Slave节点。</li>
</ul>
<h5 id="12-副本集的优点">1.2 副本集的优点</h5>
<ul>
<li>自动故障转移。</li>
<li>读写分离,能提供更好的读扩展能力。</li>
<li>副本集成员可配置为arbiter(仲裁),提供投票决定谁是主节点。</li>
</ul>
<h5 id="13-分片集群">1.3 分片集群</h5>
<ul>
<li>用于跨多个服务器分布数据的方法,用于支持非常大的数据集和高吞吐量的操作</li>
</ul>
<h4 id="2副本集节点选择">2、副本集节点选择</h4>
<p>一个副本集最多有50个节点并且最多支持7个投票节点,其余节点必须是没有投票权的节点。副本集通过设置priority决定优先级,默认优先级为1,priority值是0到100之间的数字,数字越大优先级越高,priority=0,则此节点永远不能成为主节点primay。</p>
<p><strong>副本集的最小推荐配置是三个节点:</strong></p>
<ul>
<li>一个主节点和两个从节点</li>
<li>一个主节点、一个从节点和仲裁节点</li>
</ul>
<p>如果可能,尽可能在副本集中使用奇数个数据成员,而不要使用仲裁者。所以推荐使用的最低配置为:一个主节点和两个从节点。副本集在部署时如果当节点数目为偶数个时,需要部署一个仲裁节点,否则偶数个节点,当主节点挂了后,其他节点会变为只读。不会去选举其他主节点。</p>
<p><strong>关于仲裁者说明:</strong></p>
<p>仲裁者可随意部署在网络通的任何地方,不会占用什么系统资源,它只提供投票选举的功能,不存储数据。</p>
<h4 id="3拉取mongodb镜像">3、拉取mongodb镜像</h4>
<pre><code class="language-sh">docker pull mongo:5.0
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091411614-317289642.png"></p>
<h4 id="4创建mongodb文件夹">4、创建mongodb文件夹</h4>
<p>首先在宿主机里面创建mongodb的存储数据文件夹</p>
<pre><code class="language-sh">mkdir mongo01 &amp;&amp; cd mongo01
</code></pre>
<p>进入mongo01创建conf、data、logs、tmp文件夹</p>
<pre><code class="language-sh">mkdir conf data logs tmp
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091442932-1143378605.png"></p>
<p>进入conf文件夹编写mongod.conf文件</p>
<pre><code class="language-properties"># 数据库文件存储位置
dbpath = /data/db
# log文件存储位置
logpath = /data/log/mongod.log
# 使用追加的方式写日志
logappend = true
# 是否以守护进程方式运行
# fork = true
# 全部ip可以访问
bind_ip = 0.0.0.0
# 端口号
port = 27017
# 是否启用认证
auth = true
# 设置oplog的大小(MB)
oplogSize=2048
#指定秘钥文件
keyFile = /data/key/mongo.key
#指定副本集名称
replSet = rs
</code></pre>
<p>MongoDB 的 <code>mongod.conf</code> 文件从版本 3.2 开始支持 YAML 格式。可以使用更加简洁和结构化的语法来配置 MongoDB</p>
<pre><code class="language-yaml"># mongod.conf
# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: /data/db
journal:
    enabled: true
#engine:
wiredTiger:
    engineConfig:
      cacheSizeGB: 1
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /tmp/mongod.log
# network interfaces
net:
port: 27017
#bindIp: 127.0.0.1
bindIp: 0.0.0.0
# how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo
#开启认证
security:
keyFile: /data/key/mongo.key
authorization: enabled

#operationProfiling:

#replication:配副本集名
replication:
replSetName: rs

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:

</code></pre>
<p>后面使用YAML格式进行配置说明。由于搭建副本集服务器,开启认证的同时,必须指定keyFile参数,节点之间的通讯基于该keyFile进行的。否则会启动失败。我们通过<code>docker logs 容器ID</code>查看docker日志可以发现启动的时候会报错:</p>
<p><code>BadValue: security.keyFile is required when authorization is enabled with replica sets</code></p>
<p>所以开始之前我们先把开启认证给注释掉,集群搭建成功后在开启认证。配置如下:</p>
<pre><code class="language-yaml">
#开启认证
#security:
#keyFile: /data/key/mongo.key
#authorization: enabled

</code></pre>
<p>然后把配置好的mongo01文件夹拷贝两份</p>
<pre><code class="language-sh">cp -r mongo01 mongo02
cp -r mongo01 mongo03
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091522963-1633027710.png"></p>
<h4 id="5启动mongodb容器实例">5、启动mongodb容器实例</h4>
<p>Linux路径:</p>
<pre><code class="language-sh">docker run -d --name mongo01 -p 27017:27017 --privileged=true -v ~/config/mongodb/mongo01/data:/data/db -v ~/config/mongodb/mongo01/conf:/data/configdb -v ~/config/mongodb/mongo01/logs:/data/log/-v ~/config/mongodb/mongo01/tmp:/tmpmongo:5.0   -f /data/configdb/mongod.conf
</code></pre>
<pre><code class="language-sh">docker run -d --name mongo02 -p 27018:27017 --privileged=true -v ~/config/mongodb/mongo02/data:/data/db -v ~/config/mongodb/mongo02/conf:/data/configdb -v ~/config/mongodb/mongo02/logs:/data/log/-v ~/config/mongodb/mongo02/tmp:/tmpmongo:5.0   -f /data/configdb/mongod.conf
</code></pre>
<pre><code class="language-sh">docker run -d --name mongo03 -p 27019:27017 --privileged=true -v ~/config/mongodb/mongo03/data:/data/db -v ~/config/mongodb/mongo03/conf:/data/configdb -v ~/config/mongodb/mongo03/logs:/data/log/-v ~/config/mongodb/mongo03/tmp:/tmpmongo:5.0   -f /data/configdb/mongod.conf
</code></pre>
<p>如果为Windows系统把容器卷路径改为磁盘地址即可:</p>
<pre><code class="language-sh">docker run -d --name mongo01 -p 27017:27017 --privileged=true -v D:/mongo/mongo01/data:/data/db -v D:/mongo/mongo01/conf:/data/configdb -v D:/mongo/mongo01/logs:/data/log/-v D:/mongo/mongo01/tmp:/tmpmongo:5.0   -f /data/configdb/mongod.conf
</code></pre>
<p>启动成功后通过 <code>docker ps</code> 查看容器是否运行成功。</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091544592-1772297077.jpg"></p>
<h4 id="6配置集群">6、配置集群</h4>
<p>随便进入一个容器节点进行集群配置。</p>
<pre><code class="language-sh">docker exec -it mongo01 bash
</code></pre>
<p>进入容器后,登录mongodb命令行</p>
<pre><code class="language-sh">mongo
</code></pre>
<p>执行配置副本集命令配置集群:</p>
<pre><code class="language-sh">rs.initiate({_id: "rs",members: [{ _id: 0, host: "192.168.1.9:27017" },{ _id: 1, host: "192.168.1.9:27018" },{ _id: 2, host: "192.168.1.9:27019" }]})
</code></pre>
<p>_id: "rs" 副本集名要和配置文件中的一致。如果配置仲裁节点需要在改节点里面加上 arbiterOnly: true属性 如:</p>
<pre><code class="language-sh">{ _id: 2, host: "192.168.1.9:27019", arbiterOnly: true}
</code></pre>
<p>也可以指定其<code>priority</code>( 优先级)。如果不指定,默认优先级为1。如指定第一个节点优先级为90:</p>
<pre><code class="language-sh">{"_id":0,"host":"192.168.1.9:27017",priority:90}
</code></pre>
<p>执行上面rs.initiate(config)命令后,集群就搭建成功了。系统会选择一个节点当主节点。</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091620087-1270380237.png"></p>
<p>配置成功后,目前不需要账号密码就能够登录。下面我们需要开启安全认证以保证数据库的安全。</p>
<h4 id="7集群后开启安全认证">7、集群后开启安全认证</h4>
<h5 id="71-创建root权限用户">7.1 创建root权限用户</h5>
<p>由于我们的副本集已经搭建成功了。我们可以看到有一个PRIMAY节点和两个SECONDARY节点,进入主节点容器创建用户信息。</p>
<p>切到admin库</p>
<pre><code class="language-sh">use admin
</code></pre>
<p>创建用户,用户名root,密码1234qwer,权限root,所属库admin</p>
<pre><code class="language-sh">db.createUser({user:"root",pwd:"1234qwer",roles:[{role:'root',db:'admin'}]})
</code></pre>
<p>执行上面命令后用户就创建成功了,我们先退出容器。</p>
<h5 id="72-创建密钥文件">7.2 创建密钥文件</h5>
<p>使用openssl生成key文件,由于上面已经提到了想要在副本集中开启认证,必须指定keyFile参数,所有节点使用相同的key。所以我们需要使用openssl生成一个mongo.key文件,并把文件拷贝到容器内部。</p>
<p>首先确保Linux系统安装了openssl,查看是否安装命令:</p>
<pre><code class="language-sh">openssl version
</code></pre>
<p>如果没有输出软件包信息,执行下面命令安装openssl</p>
<pre><code class="language-sh">yum install openssl
</code></pre>
<p>安装成功后执行命令生成mongo.key文件。</p>
<pre><code class="language-sh">openssl rand -base64 753 &gt; mongo.key
</code></pre>
<p>执行成功后,会生成一个mongo.key文件。我们使用docker cp命令把文件拷贝到容器中。</p>
<pre><code class="language-sh">docker cp ./mongo.key mongo01:/data/key/mongo.key
</code></pre>
<p>拷贝成功后,进入容器内部给文件授权。</p>
<pre><code class="language-sh">docker exec -it mongo01 bash
</code></pre>
<p>进入/data/key命令给文件授权。</p>
<pre><code class="language-sh">chown 999 mongo.key #设置文件归属权
chmod 400 mongo.key #设置文件为只读
</code></pre>
<p><strong>上面的授权命令必须要执行,不然容器会启动失败。一定要注意!!!</strong></p>
<h5 id="73-开启认证">7.3 开启认证</h5>
<p>上面的步骤操作成功后,接下来我们就可以把配置文件中注释掉的开启认证参数给打开了。</p>
<pre><code class="language-yaml">#开启认证
security:
keyFile: /data/key/mongo.key
authorization: enabled
</code></pre>
<p>keyFile指定的路径为拷贝到docker容器内部文件存放的路径。</p>
<h5 id="74-重启容器">7.4 重启容器</h5>
<p>把mongo.key文件也按照相同的方式拷贝到另外两个节点容器内。以上操作都成功后,就可以重新启动容器了。首先退出容器关闭所有容器副本集节点</p>
<pre><code class="language-sh">docker stop mongo01
docker stop mongo02
docker stop mongo03
</code></pre>
<p>在启动容器</p>
<pre><code class="language-sh">docker start mongo01 mongo02 mongo03
</code></pre>
<p>查看容器是否启动成功</p>
<pre><code class="language-sh">docker ps
</code></pre>
<h4 id="8副本集相关命令">8、副本集相关命令</h4>
<p>初始化副本集</p>
<pre><code class="language-sql">rs.initiate(config)
</code></pre>
<p>查看状态</p>
<pre><code class="language-sql">rs.status()
</code></pre>
<p>查看配置信息</p>
<pre><code class="language-sql">rs.conf()
</code></pre>
<p>查看是否为主节点</p>
<pre><code class="language-sql">rs.isMaster()
</code></pre>
<p>添加从节点</p>
<pre><code class="language-sql">rs.add("192.168.1.9:27020" )
</code></pre>
<p>添加仲裁节点</p>
<pre><code class="language-sql">rs.addArb("ip:27017")
</code></pre>
<p>删除节点</p>
<pre><code class="language-sql">rs.remove("192.168.1.9:27020")
</code></pre>
<p>降级节点,主节点降级为从节点,并重新选举新的主节点</p>
<pre><code class="language-sql">rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)
</code></pre>
<p>查看备份节点的复制信息</p>
<pre><code class="language-sql">db.printSlaveReplicationInfo()
</code></pre>
<p>开启从节点为只读权限</p>
<pre><code class="language-sql">rs.secondaryOk()
</code></pre>
<p>如果是4.0以下的版本,则是</p>
<pre><code class="language-sql">rs.slaveOk()
</code></pre>
<p>每次宕机重连之后都需要执行方法,不然在从节点数据库中无法读取数据。</p>
<p>测试服务宕机</p>
<pre><code class="language-sql">use admin;

db.shutdownServer();
</code></pre>
<h4 id="9可视化工具连接">9、可视化工具连接</h4>
<p>我们可以使用mongodb可视化工具连接副本集,这里使用Studio 3T进行连接。</p>
<p>选择新建连接:</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091800943-218027652.png"></p>
<p>配置连接信息</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091810567-679087087.png"></p>
<p>指定连接类型、节点地址、副本集名称。输入账号密码:</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091821393-1787009558.png"></p>
<p>点击连接</p>
<p><img src="https://img2024.cnblogs.com/blog/2661519/202404/2661519-20240423091838445-1728277008.png"></p><br><br>
来源:https://www.cnblogs.com/sowler/p/18152081
頁: [1]
查看完整版本: 使用Docker搭建MongoDB 5.0版本副本集集群