MongoDB伪分布式部署(mac M2)

news2024/11/24 15:02:42

1. 序言

  • 本博客是上一博客的进阶版:mac M2安装单机版 MongoDB 7.x,上一博客可以看做是单机、单节点部署MongoDB
  • 本博客将介绍单机、多服务部署MongoDB,实际就是伪分布式部署

2. 副本集(Replica Set)方式部署

2.1 什么是副本集?

  • 多节点部署、主从部署等其实都是为了 MongoDB 的高可用,支持数据多副本、读写分离等
  • 较新版本的MongoDB Master/slave 被废弃,通过副本集提供高可用和数据冗余
    "msg":"Master/slave replication is no longer supported"
    
  • 一个副本集由多个节点组成,其中一个节点是主节点(Primary),其余是从节点(Secondary)
  • 主节点处理所有的写操作,从节点复制主节点的数据并可以处理读操作(如果启用了读偏好)
  • 副本集的特点:
    • 高可用性: 如果主节点发生故障,从节点会自动选举一个新的主节点。
    • 数据冗余:数据在多个节点上复制,提供数据冗余。
    • 读扩展:可以配置从节点处理读操作,以减轻主节点的负载。

2.2 副本集部署

2.2.1 启动3个MongoDB服务

  • 在本机以前台进程的方式启动3个 MongoDB 服务,且指定副本集为 rs0

    mongod --replSet rs0 --dbpath /Users/bytedance/mongodb11/data --port 27031 --bind_ip_all
    
    mongod --replSet rs0 --dbpath /Users/bytedance/mongodb12/data --port 27032 --bind_ip_all
    
    mongod --replSet rs0 --dbpath /Users/bytedance/mongodb13/data --port 27033 --bind_ip_all
    
  • 如果想通过配置文件部署,服务1的配置文件如下

    # 数据存储相关配置
    storage:
      dbPath: /Users/bytedance/mongodb2/data
      journal:
        enabled: true
    
    # 网络相关配置
    net:
      port: 27030
      bindIp: 0.0.0.0  # 允许从所有IP地址访问
    
    # 副本集相关配置
    replication:
      replSetName: "rs0"
    
    # 日志相关配置
    systemLog:
      destination: file
      logAppend: true
      logRotate: rename
      path: /Users/xxx/mongodb11/log/mongo.log
    
    # 进程管理相关配置
    processManagement:
      fork: true  # 以守护进程方式运行(后台运行)
    
    # 安全相关配置
    security:
      authorization: disabled  # 关闭用户认证
    

2.2.2 初始化副本集

  • 通过mongosh登录访问其中一个服务:

    mongosh --port 27032
    
  • 执行如下命令初始化副本集合:

    rs.initiate({
      _id: "rs0",
      members: [
        { _id: 0, host: "localhost:27031" },
        { _id: 1, host: "localhost:27032" },
        { _id: 2, host: "localhost:27033" }
      ]
    })
    
  • 执行rs.status() 验证副本集状态

    rs0 [direct: primary] test> rs.status()
    {
      set: 'rs0',
      ... # 其他信息省略
      members: [
        {
          _id: 0, # initiate 时指定的id
          name: 'localhost:27031',
          health: 1,
          state: 2,
          stateStr: 'SECONDARY', # 从节点
          ... # 其他信息省略
        },
        {
          _id: 1,
          name: 'localhost:27032',
          health: 1,
          state: 1,
          stateStr: 'PRIMARY', # 主节点
          ... # 其他信息省略
        },
        {
          _id: 2,
          name: 'localhost:27033',
          health: 1,
          state: 2,
          stateStr: 'SECONDARY', # 从节点
          ... # 其他信息省略
        }
      ],
      ok: 1,
      ... # 其他信息省略
    }
    
  • 还可以通过 rs.isMaster() 查看当前访问的服务是不是primary节点

    rs0 [direct: primary] test> rs.isMaster()
    {
      ... # 其他信息省略
      hosts: [ 'localhost:27031', 'localhost:27032', 'localhost:27033' ],
      setName: 'rs0',
      setVersion: 1,
      ismaster: true, # 当前访问的是primary节点(服务)
      secondary: false,
      primary: 'localhost:27032',
      me: 'localhost:27032',
      .. # 其他信息省略
      readOnly: false,
      ... # 其他信息省略
      isWritablePrimary: true # 只能通过primary节点写入
    }
    

2.3 副本集中数据的读写

  • 从上面的信息就可以看出, 副本集的可以支持设置读写偏好、支持读写分离

  • 例如,isWritablePrimary: true 只能在primary节点写入,若在非primary节点插入数据将报错

    Uncaught:
    MongoBulkWriteError[NotWritablePrimary]: not primary
    
  • 在primary节点插入数据

    db.test_data.insertMany([
      { name: "Bob", age: 25, sex: "male", city: "Los Angeles" },
      { name: "Carol", age: 28, sex: "female", city: "Chicago" },
      { name: "Dave", age: 35, sex: "male", city: "San Francisco" }
    ])
    
  • 在任意节点查询数据

    db.test_data.find({'name':"Bob"})
    

3. 部署分片(Sharding)集群

3.1 什么是分片?

  • 在数据存储系统中,除了支持副本集(多副本存储全量数据),还支持分片(Sharding),MongoDB也不例外
  • 分片是 MongoDB 提供的一种水平扩展机制,用于将数据分布在多个服务器上
  • 分片具备以下特性:
    • 水平扩展:通过将数据分布在多个分片上,解决单个服务器的存储和性能限制。
    • 负载均衡:数据和请求可以在多个分片之间均匀分布。
    • 高可用性:结合副本集使用,每个分片可以是一个副本集,从而提供高可用性。

3.2 副本集 vs 分片

  • 相对副本集,分片会按照某种规则将数据拆分成多个split,每个split存储到相应的分片
  • 以销售数据为例,形象化比喻:
    • 副本集就是一个机房有多台机器,每台机器都将存储中国市场的销售数据
    • 分片就是存在多个机房,每个机房存储只存储所在区域的销售数据。例如,华北机房只存储华北地区的销售数据,西南机房只存储西南地区的销售数据
    • 同时,为了提供高可用和数据冗余,分片存储时,每个机房需要有多台机器,支持多副本储存该区域的销售数据
    • 也就是说,一个分片就是一个副本集,分片内部通过副本集实现高可用和数据冗余机制

3.3 部署分片集群(副本集与分片的结合使用)

  • 分片集群由配置服务器(Config Servers)、分片服务器(Shards)、和路由服务器(mongos)组成
    • 配置服务器作为副本集:配置服务器存储集群的元数据,为了确保配置服务器的高可用性,配置服务器也通常设置为一个副本集
    • 每个分片作为一个副本集:在分片集群中,每个分片通常是一个副本集。这意味着每个分片不仅能存储数据的一部分,还能提供高可用性和数据冗余。
    • 路由服务器(mongos):mongos不存储数据,而是作为路由器将客户端请求路由到适当的分片,可以部署多个mongos实例以提供高可用性和负载均衡

3.3.1 部署配置服务器

  • 使用如下命令,在本地启动三个配置服务器,注意提前创建好data目录

    • --configsvr:表示这是一个配置服务器

    • --replSet rs0:设置副本集,配置服务器的本质是一个副本集

      
      mongod --configsvr --replSet rs0 --dbpath /Users/xxx/mongodb1/data/configdb --port 27019 --bind_ip_all
      
      mongod --configsvr --replSet rs0 --dbpath /Users/xxx/mongodb2/data/configdb --port 27020 --bind_ip_all
      
      mongod --configsvr --replSet rs0 --dbpath /Users/xxx/mongodb3/data/configdb --port 27021 --bind_ip_all
      
  • 访问某个配置服务,初始化副本集

    mongosh --port 27019 # 访问配置服务
    
    rs.initiate({
      _id: "rs0",
      configsvr: true,
      members: [
        { _id: 0, host: "localhost:27019" },
        { _id: 1, host: "localhost:27020" },
        { _id: 2, host: "localhost:27021" }
      ]
    })
    
  • PS: 若以后台服务方式启动,上述启动方式对应的配置文件如下

    storage:
      dbPath:  /Users/xxx/mongodb1/data/configdb
      journal:
        enabled: true
    # 网络相关配置
    net:
      port: 27010
      bindIp: 0.0.0.0  # 允许从所有IP地址访问
    # 复制集相关配置
    replication:
      replSetName: "rs0"
    # 设置role:分片集群中的配置服务器
    sharding:
      clusterRole: "configsvr"
    # 日志相关配置
    systemLog:
      destination: file
      logAppend: true
      logRotate: rename
      path: /Users/xxx/mongodb1/log/configd/mongo.log
    # 进程管理相关配置
    processManagement:
      fork: true  # 以守护进程方式运行(后台运行)
    # 安全相关配置
    security:
      authorization: disabled  # 关闭用户认证
    

3.3.2 部署分片服务器

shard1
  • 使用如下命令,在本地启动三个分片服务器,注意提前创建好data目录

    mongod --shardsvr --replSet shard1 --dbpath /Users/bytedance/mongodb1/data/shard --port 27022 --bind_ip_all
    
    mongod --shardsvr --replSet shard1 --dbpath  /Users/bytedance/mongodb2/data/shard --port 27023 --bind_ip_all
    
    mongod --shardsvr --replSet shard1 --dbpath  /Users/bytedance/mongodb3/data/shard --port 27024 --bind_ip_all
    
  • 访问其中某个分片服务器,初始化分片信息

    mongosh --port 27022
    
    rs.initiate({
      _id: "shard1",
      members: [
        { _id: 0, host: "localhost:27022" },
        { _id: 1, host: "localhost:27023" },
        { _id: 2, host: "localhost:27024" }
      ]
    })
    
shard2
  • 使用如下命令,在本地启动三个分片服务器,注意提前创建好data目录

    mongod --shardsvr --replSet shard2 --dbpath /Users/bytedance/mongodb1/data/shard2 --port 27025 --bind_ip_all
    
    mongod --shardsvr --replSet shard2 --dbpath  /Users/bytedance/mongodb2/data/shard2 --port 27026 --bind_ip_all
    
    mongod --shardsvr --replSet shard2 --dbpath  /Users/bytedance/mongodb3/data/shard2 --port 27027 --bind_ip_all
    
  • 访问其中某个分片服务器,初始化分片信息

    mongosh --port 27025
    
    rs.initiate({
     _id: "shard2",
     members: [
       { _id: 0, host: "localhost:27025" },
       { _id: 1, host: "localhost:27026" },
       { _id: 2, host: "localhost:27027" }
     ]
    })
    

3.3.4 部署mongos

  • 先创建好mongos所需的相关目录

    mkdir /Users/xxx/mongos
    cd /Users/xxx/mongos
    mkdir data log etc
    
  • 在etc目录下创建mongos的配置文件,mongos-config.yaml

    net:
      bindIp: 0.0.0.0
      port: 27017
    
    sharding:
      configDB: rs0/localhost:27019,localhost:27020,localhost:27021
    
  • 以前台方式启动mongos

    mongos --config /Users/xxx/mongos/etc/mongos-config.yaml
    
  • 访问mongos,添加分片(之前部署好的分片服务器)

    mongosh --port 27017
    
    sh.addShard("shard1/localhost:27022,localhost:27023,localhost:27024")
    sh.addShard("shard2/localhost:27025,localhost:27026,localhost:27027")
    
  • 通过 sh.status() 查看shard信息

    # 关键信息
    shards
    [
      {
        _id: 'shard1',
        host: 'shard1/localhost:27022,localhost:27023,localhost:27024',
        state: 1,
        topologyTime: Timestamp({ t: 1727872634, i: 3 })
      },
      {
        _id: 'shard2',
        host: 'shard2/localhost:27025,localhost:27026,localhost:27027',
        state: 1,
        topologyTime: Timestamp({ t: 1727939236, i: 4 })
      }
    ]
    

3.5 启用分片

3.5.1 启用数据库分片和集合分片

  • 启用数据库分片和集合分片

    use admin # 一定要先切换到admin,
    sh.enableSharding("test")
    
    use test
    sh.shardCollection("test.test_data", {user_id: 1}) # user_id作为分片的key
    
  • 验证是否成功开启集合分片

    use test
    db.test_data.getShardDistribution()
    
  • 若有如下输出,说明开启成功

3.5.2 插入数据并查看

  • 插入100条数据

    # 数据示例 -- user_id: id000001; name: name1
    for (let i = 1; i <= 2000; i++) {
     let user_id = `id${String(i).padStart(6, '0')}`;  
     let name = `name${i}`;  
     db.test_data.insertOne({ user_id: user_id, name: name });
    }
    
  • 执行sh.status()查看分片信息,但数据只分布到了shard2,要么是集群部署存在问题,要么跟公司的 “chatGPT” 回答一样

    • 分片键选择不当:如果分片键的值分布不均匀,可能会导致数据集中在一个分片上。例如,如果您的分片键是一个递增的字段(如时间戳或自增 ID),那么所有新插入的数据都会集中在同一个分片上
    • 数据量不足:在数据量较小的情况下,MongoDB 可能不会立即将数据分布到多个分片上。MongoDB 需要一定的数据量来决定何时进行分片 (笔者倾向于该原因)
       ... # 其他信息省略,可以看到 'test.test_data' 集合成功开启了分片
       collections: {
          'test.test_data': {
            shardKey: { user_id: 1 },
            unique: false,
            balancing: true,
            chunkMetadata: [ { shard: 'shard2', nChunks: 1 } ],
            chunks: [
              { min: { user_id: MinKey() }, max: { user_id: MaxKey() }, 'on shard': 'shard2', 'last modified': Timestamp({ t: 1, i: 0 }) }
            ],
            tags: []
          }
        }
    
  • PS: 公司的 “chatGPT” 还给出了其他的查看分片信息的方法,但无任何输出

    use config
    db.chunks.find({ ns: "testDB.test_data" }).sort({ min: 1 }).pretty()
    

3.5.3 在shard2的各服务器查询数据

  • 由于上面的集合只分布在shard2,现在连接shard2的任意服务器,执行如下查询命令

    use test
    db.test_data.find({'name':"name1"})
    
  • 均能从shard2的每个服务器查到数据,这也说明了,shard2分片自身就是一个副本集


4. 后记

  • 网上查了很多MongoDB多副本部署,大部分的版本都比较低,还有 master/slave 之类的配置
    • MongoDB主从复制(master–>slave)环境搭建
    • mongodb的主从同步配置:实战详细版(建议收藏)
  • 笔者依靠公司的chartGPT完成部署后,发现这篇文章是最靠谱的:MongoDB数据库之主从复制配置实战
  • 其他一些感悟
    • AI真强大: 此次部署完全依靠公司的chartGPT,不懂就问、出问题也问,最后磕磕绊绊完成了部署
    • 磨刀不误砍柴工: 部署分片集群时,一开始没有为认真了解分片集群的架构,不知道副本集是存储元数据的,导致部署失败

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

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

相关文章

DNS与ICMP

一、DNS 在TCP/IP协议中&#xff0c;要用IP地址和端口号来连接服务器&#xff0c;但是直接输入数字用户体验感不好&#xff0c;所以就发明了主机号&#xff08;字符串&#xff09;&#xff0c;用host文件作主机名与IP的映射关系储存。 随着数量的增多&#xff0c;手动管理太麻…

【机器学习】集成学习——提升模型准确度的秘密武器

【机器学习】集成学习——提升模型准确度的秘密武器 1. 引言 集成学习&#xff08;Ensemble Learning&#xff09;是一种通过结合多个弱模型来提升整体预测准确性的技术。通过将多个模型的预测结果进行组合&#xff0c;集成学习在复杂任务中展现了极强的泛化能力。本文将探讨…

基于微信的乐室预约小程序+ssm(lw+演示+源码+运行)

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

深入探讨指令调优的局限性

深入探讨指令调优的局限性 摘要 指令调优&#xff08;Instruction Tuning, IT&#xff09;是通过使用指令-响应对训练大型语言模型&#xff08;LLMs&#xff09;的过程&#xff0c;已成为将基础预训练LLMs转化为开放领域对话代理的主要方法。尽管IT取得了显著的成功和广泛的应…

HUAWEI New4.9G 与 2.6G 无法正常切换问题处理案例

HUAWEI New4.9G 与 2.6G 无法正常切换问题处理案例 在某地市的 XX 音乐节保障准备期间&#xff0c;为确保活动期间的网络质量&#xff0c;现场新开了 4.9G HUAWEI 室外基站。在网络优化和测试中&#xff0c;发现UE无法实现从 2.6G 到 4.9G 的正常切换。虽然现场具备 4.9G信号覆…

算法与数据结构--二分查找

原理 简单说就是每次二分取中间值&#xff0c;然后将中间值与我们要找的值比较&#xff0c;如果比它大就移动左边界到其右侧&#xff0c;如果比它小就移动右边界到其左侧。直到中间值等于该值或者经过移动直至右边界在左边界左侧为止。 二.具体实现 public int searchInsert(…

数据结构 ——— 单链表oj题:反转链表

目录 题目要求 手搓一个简易链表 代码实现 题目要求 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 手搓一个简易链表 代码演示&#xff1a; struct ListNode* n1 (struct ListNode*)malloc(sizeof(struct ListNode)); assert(n1);…

【重学 MySQL】五十三、MySQL数据类型概述和字符集设置

【重学 MySQL】五十三、MySQL数据类型概述和字符集设置 MySQL数据类型概述MySQL字符集设置注意事项 MySQL数据类型概述 MySQL是一个流行的关系型数据库管理系统&#xff0c;它支持多种数据类型&#xff0c;以满足不同数据处理和存储的需求。理解并正确使用这些数据类型对于提高…

已解决:org.springframework.web.HttpMediaTypeNotAcceptableException

文章目录 写在前面问题描述报错原因分析&#xff1a; 解决思路解决办法1. 确保客户端请求的 Accept 头正确2. 修改 Controller 方法的 produces 参数3. 配置合适的消息转换器4. 检查 Spring 配置中的媒体类型5. 其他解决方案 总结 写在前面 在开发过程中&#xff0c;Spring 框…

实验1 集成开发环境的使用及程序设计入门

1、求两点之间的距离 【问题描述】从键盘输入平面上已知两点的坐标A(x1,y1)、B(x2,y2)&#xff0c;计算两点之间的距离。结果保留4位小数。 【输入形式】两个点的坐标 【输出形式】两点之间的距离 【样例输入】 0 0 3 4 【样例输出】 5.0000 #define _CRT_SECURE_NO_WARNI…

(C语言贪吃蛇)12.Linux线程概念引入及编程实现

目录 前言 Linux线程概念 解决方法 注意事项⚠️ 解决问题&#x1f525; 总结 前言 我们上节提出了两个死循环不能同时运行&#xff0c;导致我们无法控制贪吃蛇的运动方向&#xff0c;本节我们便来解决这个问题。 Linux线程概念 线程是一个进程内部的控制序列&#xff0c…

鸿蒙应用开发前置学习-TypeScript

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

杭州电子科技大学《2019年+2023年861自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《杭州电子科技大学861自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2019年真题 2023年真题 Part1&#xff1a;2019年2023年完整版真题 2019年真题 2…

【Linux私房菜(九)之进程间通信】

文章目录 进程间通信介绍进程间通信的概念进程间通信的目的进程间通信的本质进程间通信的分类 管道什么是管道匿名管道匿名管道的原理pipe函数匿名管道使用步骤管道读写规则管道的特点管道的四种特殊情况管道的大小 命名管道命名管道的原理使用命令创建命名管道创建一个命名管道…

会声会影导出视频mp4格式哪个最高清,会声会影输出格式哪个清晰

调高分辨率后&#xff0c;mp4视频还是不清晰。哪怕全部使用4K级素材&#xff0c;仍然剪不出理想中的高画质作品。不是你的操作有问题&#xff0c;而是剪辑软件没选对。Corel公司拥有全球顶尖的图像处理技术&#xff0c;该公司研发的会声会影视频剪辑软件&#xff0c;在过去的20…

详解CSS中的伪元素

4.3 伪元素 可以把样式应用到文档树中根本不存在的元素上。 ::first-line 文本中的第一行 ::first-letter 文本中的第一个字母 ::after 元素之后添加 ::before 元素之前 代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8&q…

netty之Netty传输Java对象

前言 Netty在实际应用级开发中&#xff0c;有时候某些特定场景下会需要使用Java对象类型进行传输&#xff0c;但是如果使用Java本身序列化进行传输&#xff0c;那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接…

无线物联网通信与智能家居

无线物联网通信技术与智能家居之间存在着密不可分的关系。无线物联网通信技术作为智能家居系统的核心支撑&#xff0c;为智能家居设备之间的互联互通提供了可能&#xff0c;从而实现了家居生活的智能化、便捷化和舒适化。 一、无线物联网通信技术在智能家居中的应用 1、传感器…

LabVIEW程序员从幼稚到成熟的标志是什么?

LabVIEW程序员从“幼稚”到“成熟”的转变标志主要体现在以下几个方面&#xff1a; 1. 系统性思维与架构设计 初学者通常会注重功能实现&#xff0c;常常直接编写功能模块&#xff0c;而忽略系统整体的架构设计。成熟的LabVIEW程序员则具备系统性思维&#xff0c;在开始编写代…

Ericsson EPSFB 通话掉话现象优化案例

Ericsson EPSFB 通话掉话现象优化案例 在移动通信网络中&#xff0c;用户体验的稳定性和通话质量至关重要。随着通信语言通话技术的发展&#xff0c;部分用户在通话时会遇到掉话现象&#xff0c;尤其是在采用EPSFB&#xff08;EvolvedPacket>System Fallback&#xff09;技术…