MongoDB单机集群方案及详解

news2024/11/15 5:01:39

目录

  • 帮助文档
  • MongoDB在企业级网站中的定位
  • 单机MongoDB部署
  • 集群(副本集)
  • 集群(副本集+仲裁)
  • 集群(分片)
  • mongo运行原理
  • mongo管理小工具推荐

帮助文档

MongoDB官方更新速度过快,语法不断更新,shell命令也不断更新,建议直接看官方版。

  • 国内帮助文档:https://docs.mongoing.com/the-mongodb-manual-cn
  • 官方文档(海外):https://www.mongodb.com/developer/
  • docker官方提供的MongoDB安装文档:https://hub.docker.com/_/mongo(mongo更新过快,某些命令可能不是最新)

本文主要从docker角度出发安装MongoDB

MongoDB在企业级网站中的定位

在这里插入图片描述
如图MongoDB是在关系型与非关系数据库之间,目前企业级网站面临3V(海量Volume,多样variety,实时velocity),3高(高并发,高可扩,高性能),通过数据冗余,在一条数据中存储父子的表数据来解决不能联查的问题。
举个例子:

  • 当每秒写入的数据超过了数据库所能写入的上限时,我们改怎么办?

将数据暂存在MongoDB中,再通过定时任务,写入数据库中。虽然MongoDB存在丢失数据风险的,但如果服务器稳定遍不会出现这种问题

  • redis缓存不能满足统计分析等场景时,我们改怎么办?

将数据通过冗余的方式写入MongoDB中,通过MongoDB丰富的查询方式解决这个问题。

单机MongoDB部署

最基础的使用MongoDB,无法使用事务功能

//下载镜像
docker pull mongo
//创建容器并持久化数据
docker run --name 容器名称 -p 对外端口:27017 --restart=always -v /app/docker/mongo/db:/data/db -v /etc/localtime:/etc/localtime -d mongo   --bind_ip_all
//进入docker 容器
docker exec -it 容器名称 bash
//进入docker 容器并登录MongoDB
docker exec -it 容器名称 mongosh
//登录进MongoDB后需要重置Mongo
rs.initiate()
//至此MongoDB可以正常使用了

集群(副本集)

进阶版使用MongoDB
注:原复制集因主节点挂掉,不能继续写入数据被淘汰,更新为副本集
一个主库;两个从库组成,主库宕机时,这两个从库都可以被选为主库。但数据通过主库写入时,副本库会将数据抓取到副本集中进行存储。主库负责写入数据,副本节点负责读取数据。我们写代码时不需要区分主节点与副本节点,可以连接所有ip,MongoDB会自己分辨
在这里插入图片描述
通过心跳检测,如果主节点挂掉,优先发现主节点挂掉的副本节点会成为主节点,但主节点再恢复后不能再成为主节点,只能成为副本节点。但这里会出现一个问题,副本节点并不一定是计算能力最强的节点。而且主节点只能有一个
在这里插入图片描述

docker pull mongo

mkdir -p /app/docker/mongo1/db   #创建挂载的db目录
mkdir -p /app/docker/mongo2/db   #创建挂载的db目录
mkdir -p /app/docker/mongo3/db   #创建挂载的db目录
#第一台:
docker run --name mongo-server1 -p 30001:27017 --restart=always -v /app/docker/mongo1/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all
#第二台:
docker run --name mongo-server2 -p 30002:27018 --restart=always -v /app/docker/mongo2/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all
#第三台:
docker run --name mongo-server3 -p 30003:27019 --restart=always -v /app/docker/mongo3/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all

 

#进入容器 进入主的容器
docker exec -it mongo-server1 bash 
#连接客户端
docker exec -it 容器名称 mongosh
//这里localhost是因为我都是在同一个服务器上装的,都换成各自的ip就好
//初始化
rs.initiate()
//注册副本集
rs.add("localhost:30002") 
#如果想要在从节点查询(默认是客户端直连是不可查询的)
如果想要在端口30002 从服务上执行查询,则连接上之后需要执行 db.getMongo().setSlaveOk(); 

集群(副本集+仲裁)

仲裁节点不存储数据,仲裁会帮助选举出主节点,但如果仲裁集群挂掉,主节点也挂掉了,那就完蛋了。因为副本集群只能读取不能写入。而且主节点只能有一个
在这里插入图片描述

docker pull mongo

mkdir -p /app/docker/mongo1/db   #创建挂载的db目录
mkdir -p /app/docker/mongo2/db   #创建挂载的db目录
mkdir -p /app/docker/mongo3/db   #创建挂载的db目录
#第一台:
docker run --name mongo-server1 -p 30001:27017 --restart=always -v /app/docker/mongo1/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all
#第二台:
docker run --name mongo-server2 -p 30002:27018 --restart=always -v /app/docker/mongo2/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all
#第三台:
docker run --name mongo-server3 -p 30003:27019 --restart=always -v /app/docker/mongo3/db:/data/db -v /etc/localtime:/etc/localtime -d mongo  --replSet "rs0"  --bind_ip_all

 

#进入容器 进入主的容器
docker exec -it mongo-server1 bash 
#连接客户端
docker exec -it 容器名称 mongosh
//这里localhost是因为我都是在同一个服务器上装的,都换成各自的ip就好
//初始化
rs.initiate()
//注册副本集
rs.add("localhost:30002")
//注册仲裁
rs.addArb("localhost:30003")
#如果想要在从节点查询(默认是客户端直连是不可查询的)
如果想要在端口30002 从服务上执行查询,则连接上之后需要执行 db.getMongo().setSlaveOk(); 

集群(分片)

架构师必备,搞不懂分片完全有情可原,相当的复杂。大家创建分片时切记画好图再创建,不然会弄乱。
在这里插入图片描述
分片的意思就是将一个集合中的数据,拆成不同的分片集群来存储数据。接下来忘记副本集的概念,分片和副本集架构关系并不大

在这里插入图片描述

  • App Server 就是某一个分片集群,其中包含很多分片(Shard)和一个主节点 。实际生产环境中的一个分片服务可以由好几台服务组成reclica set,防止单点故障。(详见下图)
  • Shard 为数据存储分片,用来将分割后的数据储存起来。可以是集群,实现高负载,高可用。每一片都可以是复制集(replica set)
  • Router 路由进程 也叫mongos,用来外部访问。从整体看来,无论有多少个app server,访问时只连接Router即可,Router只需要一个。应用程序接入 mongos 再查询到具体分片
  • Config Service 路由表,每一台都具有全部 chunk 的路由信息,用来存储分割的信息,比如XXX存到哪里去,XXX要从哪里读取。也可以搭建集群。
    任何集群里面都可以有仲裁
    在这里插入图片描述

当然问题也会存在,比如某个分片挂掉,就会影响该分片内数据的读取,但只需要重启就好。如果 App Server,Config Service 任何一个整体挂掉,就不可用了,但都可以集群分布在不同机器上,问题不大。

192.168.1.201:

~~~shell
docker run --name shardsvr00 -p 10031:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_all

docker run --name shardsvr10 -p 10041:27018 -d -v /home/mongodb/data/sh/shardsvr10:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all


~~~

192.168.1.202:

~~~shell
docker run --name shardsvr01 -p 10032:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_all
docker run --name shardsvr11 -p 10042:27018 -d -v /home/mongodb/data/sh/shardsvr11:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all
~~~

192.168.3.203:

~~~shell
docker run --name shardsvr02 -p 10033:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_all
docker run --name shardsvr12 -p 10043:27018 -d -v /home/mongodb/data/sh/shardsvr12:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all
~~~

### 2.5初始化副本集

192.168.1.201执行

docker exec -it shardsvr00 bash
mongo --host 192.168.1.201 --port 10031

~~~shell
rs.initiate(
   {
      _id: "rs_shardsvr0",
      members: [
         { _id: 0, host : "192.168.1.201:10031" },
         { _id: 1, host : "192.168.1.202:10032" },
         { _id: 2, host : "192.168.1.203:10033" }
      ]
   }
);
~~~

docker exec -it shardsvr10 bash
mongo --host 192.168.1.201 --port 10041

~~~shell
rs.initiate(
   {
      _id: "rs_shardsvr0",
      members: [
         { _id: 0, host : "192.168.1.201:10041" },
         { _id: 1, host : "192.168.1.202:10042" },
         { _id: 2, host : "192.168.1.203:10043" }
      ]
   }
);
~~~

### 2.6.创建mongos,连接mongos到分片集群

192.168.1.201:

docker run --name mongos0 -d -p 10011:27017 --entrypoint "mongos" mongo --configdb rs_configsvr/192.168.1.201:10021,192.168.1.202:10022,192.168.1.203:10023 --bind_ip_all

192.168.3.202:

docker run --name mongos1 -d -p 10012:27017 --entrypoint "mongos" mongo --configdb rs_configsvr/192.168.1.201:10021,192.168.1.202:10022,192.168.1.203:10023 --bind_ip_all

### 2.7添加分片到集群

192.168.3.201:

docker exec -it mongos0 bash
mongo --host 192.168.1.201 --port 10011

sh.addShard("rs_shardsvr0/192.168.1.201:10031,192.168.1.202:10032,192.168.1.203:10033")
sh.addShard("rs_shardsvr1/192.168.1.201:10041,192.168.1.202:10042,192.168.1.203:10043")

## 数据库 启用 分片

sh.enableSharding("test")

## 分片集合

对 test.order 的 _id 字段进行哈希分片:

sh.shardCollection("test.order", {"_id": "hashed" })

mongo运行原理

在这里插入图片描述

  • 当数据data需要写入时,会先存入私有内存空间Journal内存中,随后通过定时任务journal log 每100ms刷一次存入journal log对于的硬盘中 。同时也会通过异步的方式将数据每60s一次,写入硬盘中,完成存储
  • 当数据需要读取时,不会直接读取硬盘中的数据,而是读取journal log 中的数据,并返回。
  • 当然journal log 功能是可以通过配置关闭的,定时存储时间也可以自定义设置(一般都不会动)。但是 这样的模式当MongoDB挂掉时,丢失的数据不仅仅是100ms内的数据,而是取决于数据存入journal log 内存后,定时任务有没有办法在100ms内将数据写入硬盘。如果100ms内能解决,那么只会丢最近100ms内的数据。如果不能解决,那么丢失的就会因为延迟的问题,丢失超过100ms的数据。

mongo管理小工具推荐

docker run -it --rm \
    --name mongo-express \
    -p 8081:8081 \
    -e ME_CONFIG_OPTIONS_EDITORTHEME="ambiance" \
    -e ME_CONFIG_MONGODB_SERVER="192.168.1.201" \
	-e ME_CONFIG_MONGODB_PORT="10011"          \
    -e ME_CONFIG_BASICAUTH_USERNAME="admin" \
    -e ME_CONFIG_BASICAUTH_PASSWORD="admin" \
    mongo-express

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云南民族文化旅游网页设计制作 简单静态HTML网页作品 我的家乡网页作业成品 学生旅游网站模板

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法,如盒子的嵌套、浮动、margin、border、background等属性的使用,外部大盒子设定居中,内部左中右布局,下方横向浮动排列,大学学习的前端知识点和布局方式都有…

m基于光纤光栅传感网接入GPON的光纤通信系统matlab性能仿真,包括解码,解封装,分接,码率恢复,解帧,拆包,译码

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 接入处理系统模块化设计: 传感器接收到的信息转换为二进制信息(这个我们可以直接模拟出随机的二进制序列来表示传感器的数据,首先设置一组数据&#…

maven学习: 使用Maven构建Web项目

5.1 Maven中Web项目的结构 ​ 在java的世界中,Web应用占有很大的地位,而它的标准打包方式是WAR。WAR与JAR类似,但它包含了更多内容,如JSP文件、Servlet、web.xml配置文件、静态web资源(如html,css&#xf…

Python Gui之tkinter

GUI是什么 目录 1。GUI编程的核心步骤和第一个GUI程序 2.tkinter主窗口​​​​​​​ 3.GUI的整体描述 常用组件汇总 4.简单的组件 1.Label标签 2.Options选项详解 3.Button 4.Entry单行文本框 5.Text多行文本框 1。GUI编程的核心步骤和第一个GUI程序 from tkinte…

biaffine model:Named Entity Recognition as Dependency Parsing

论文名称:Named Entity Recognition as Dependency Parsing 论文地址:https://www.aclweb.org/anthology/2020.acl-main.577/ 前提说明 本文主要参考了以下资料 nlp_paper_study_information_extraction/code_pytorch.md at main km1994/nlp_paper_s…

ASEMI肖特基二极管SBT40100VFCT规格,SBT40100VFCT封装

编辑-Z ASEMI肖特基二极管SBT40100VFCT参数: 型号:SBT40100VFCT 最大重复峰值反向电压(VRRM):100V 最大平均正向整流输出电流(IF):40A 峰值正向浪涌电流(IFSM&#…

使用kubeadm搭建高可用集群-k8s相关组件及1.16版本的安装部署

本文是向大家分享k8s相关组件及1.16版本的安装部署,它能够让大家初步了解k8s核心组件的原理及k8s的相关优势,有兴趣的同学可以部署安装下。 什么是kubernetes kubernetes是Google 开源的容器集群管理系统,是大规模容器应用编排系统&#xff…

ubuntu下jupyter notebook设置远程访问

1. 安装anaconda 推荐安装anaconda,安装后就会包含jupyter notebook 使用命令conda list或者pip list查看jupyter notebook包,这里不多介绍 2. 生成默认配置文件 在ubuntu环境下,安装jupyter notebook后,用户主目录中会有一个…

DRU-Net--一种用于医学图像分割的高效深度卷积神经网络

Title:DRU-NET: AN EFFICIENT DEEP CONVOLUTIONAL NEURAL NETWORK FOR MEDICAL IMAGE SEGMENTATION 摘要 本文的网络结构是受ResNet和DenseNet两个网络的启发而提出的。与ResNet相比本文的方法增加了额外的跳跃连接,但使用的模型参数要比DenseNet少的多。 基于先…

【创建型设计模式-单例模式】一文搞懂单例模式的使用场景及代码实现的7种方式(全)

1.什么是单例模式 在了解单例模式前,我们先来看一下它的定义: 确保一个类只有一个实例,而且自行实例化并且自行向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法, 单例模式是一种对象的创建型…

北京东物流,南顺丰速运

配图来自Canva可画 众所周知,“双11”是一年一度的物流高峰期,但2022年“双11”当日快递业务量并未达到预期水平,全年增速创下新低。据了解,“双11”当日业务量为5.52亿件,同比下滑了20.69%,而11月1日至11…

什么是CISAW认证?有什么价值?

随着信息技术的快速发展和信息化应用的不断深入,信息技术、产品及网络已经融入社会经济生活的方方面面,但同时信息安全问题也越来越突出。面对严峻的信息安全形势,我国将信息安全上升至国家战略,相继出台了一系列政策法规。那大家…

IDEA好用插件推荐

一、MavenHelper 当Maven Helper 插件安装成功后,打开项目中的pom文件,下面就会多出一个试图Dependency Analyzer 切换到此试图即可进行相应操作: Conflicts(查看冲突)All Dependencies as List(列表形式…

数据仓库规范

模型设计 模型设计概述 为什么需要模型设计? Linux 的创始人 Torvalds 有 一段关于“什么才是优秀程序员”的话:“烂程序员关心的是代码,好程序员关心的是数据结构和它们之间的关系”,其阐述了数据模型的重要性。有了适合业务和基础数据存…

python 中__init__ 作用

__init__的作用: (1)声明包 (2)预加载模块内容 (1)声明包 python项目结构中,普通目录下无__init__文件;而包下是有__init__文件的。 python 项目结构是按目录来组织的…

R语言结课及Matlab开始

R语言结课 我们R语言的学习这节课下课就结束了,接下来进行Matlab的学习。下面我会说一下R的结课任务及如何考试,以及我自己整理的Matlab安装教程。 R的结课作业:周二上课时提到的两个回归模型课程总结(老师说作业总结主要是作业…

如何运用java代码操作Redis

目录 1、java如何连接Redis? 1.1.启动Redis服务 1.2.导入相关Redis依赖 1.3.java代码进行连接 2、java连接Redis 2.1.String 2.1.1.设值 2.1.2.拿值 2.1.3.删除 2.1.4.修改 2.1.5.给键值对设置过期时间 2.1.6.获取键值对剩余的存活时间 2.2.哈希(Hash&a…

jacoco单测报告怎么同步到sonarqube

sonarqube支持多种代码覆盖率的报告展示,最常用的当属jacoco报告,那么jacoco的报告怎么同步到我们的sonarqube中呢? 我们先看看jacoco的offline模式(单元测试)报告生成的流程 根据上图我们需要生成单测报告&#xff0…

Apollo 应用与源码分析:CyberRT-工具与命令

概念 cyberRT包括一个可视化工具cyber_visualizer和两个命令行工具cyber_monitor和cyber_recorder。 注意:使用这些工具需要apollo docker环境 并且Cyber RT 中提供了一些命令工具,可以方便快捷的解决上述问题,本部分内容就主要介绍这些命…

Clion学习

看看Cmake是个什么? 他是个构建管理工具 一个比较OK的图 cmake_minimum_required(VERSION 3.15)#指定了最小的Cmake版本 project(jcdd)#指定了项目名称 set(CMAKE_CXX_STANDARD 14) add_executable(jcdd main.cpp)#输出可执行文件的名称安装第三方库&#xff…