MongoDB伪分布式部署(mac M2)

news/2024/10/4 9:11:20/

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_allmongod --replSet rs0 --dbpath /Users/bytedance/mongodb12/data --port 27032 --bind_ip_allmongod --replSet rs0 --dbpath /Users/bytedance/mongodb13/data --port 27033 --bind_ip_all
    
  • 如果想通过配置文件部署,服务1的配置文件如下

    # 数据存储相关配置
    storage:dbPath: /Users/bytedance/mongodb2/datajournal:enabled: true# 网络相关配置
    net:port: 27030bindIp: 0.0.0.0  # 允许从所有IP地址访问# 副本集相关配置
    replication:replSetName: "rs0"# 日志相关配置
    systemLog:destination: filelogAppend: truelogRotate: renamepath: /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 时指定的idname: '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_allmongod --configsvr --replSet rs0 --dbpath /Users/xxx/mongodb2/data/configdb --port 27020 --bind_ip_allmongod --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/configdbjournal:enabled: true
    # 网络相关配置
    net:port: 27010bindIp: 0.0.0.0  # 允许从所有IP地址访问
    # 复制集相关配置
    replication:replSetName: "rs0"
    # 设置role:分片集群中的配置服务器
    sharding:clusterRole: "configsvr"
    # 日志相关配置
    systemLog:destination: filelogAppend: truelogRotate: renamepath: /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_allmongod --shardsvr --replSet shard1 --dbpath  /Users/bytedance/mongodb2/data/shard --port 27023 --bind_ip_allmongod --shardsvr --replSet shard1 --dbpath  /Users/bytedance/mongodb3/data/shard --port 27024 --bind_ip_all
    
  • 访问其中某个分片服务器,初始化分片信息

    mongosh --port 27022rs.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_allmongod --shardsvr --replSet shard2 --dbpath  /Users/bytedance/mongodb2/data/shard2 --port 27026 --bind_ip_allmongod --shardsvr --replSet shard2 --dbpath  /Users/bytedance/mongodb3/data/shard2 --port 27027 --bind_ip_all
    
  • 访问其中某个分片服务器,初始化分片信息

    mongosh --port 27025rs.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.0port: 27017sharding:configDB: rs0/localhost:27019,localhost:27020,localhost:27021
    
  • 以前台方式启动mongos

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

    mongosh --port 27017sh.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.ppmy.cn/news/1534328.html

相关文章

Netgear-WN604 downloadFile.php 信息泄露复现(CVE-2024-6646)

0x01 产品描述&#xff1a; NETGEAR WN604是一款功能强大的双频AC1200无线路由器,非常适合中大型家庭和企业使用。它支持最新的802.11ac无线标准,能提供高达1200Mbps的无线传输速度。路由器具备千兆有线网口和3个100Mbps有线网口,可满足有线和无线设备的接入需求。此外,它还内置…

element-ui 通过按钮式触发日期选择器

element ui 写在前面1. 自定义的日期时间组件CustomDatePicker.vue2. 页面效果总结写在最后 写在前面 需求&#xff1a;elementui中日期时间选择器&#xff0c;目前只能通过点击input输入框触发日期选择器&#xff0c;我希望能通过其他方式触发日期选择器同时把input输入框去掉…

git如何将多个提交合并为一个提交

目录 第一种&#xff1a;使用git rebase命令 第二种&#xff1a;使用git reset命令 重新提交 第一种&#xff1a;使用git rebase命令 使用以下命令的其中一种启动交互式 rebase git rebase -i 你想要合并提交的父提交的哈希值git rebase -i <commit-hash>^ &#…

实战4、爬取淘宝商品数据-selenium模拟

1、登录 在页面中找到登录按键&#xff0c;使用selenium模拟点击 button_login wd.find_element(By.XPATH,"//li[idJ_SiteNavMytaobao]/div[classsite-nav-menu-hd]/a[target_top]")button_login.click()找到用户名密码所在位置模拟输入 # 模拟输入账密button_us…

正向代理与反向代理:原理、区别以及应用(Nginx 和 Tomcat)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 实现原理正向代理工作流程&#xff1a; 反向代理工作流程&#xff1a; 区别 2. 使用案例Nginx作为正向代理Nginx作为反向代理Tomcat作为反向代理 3. 适用场景…

C#绘制动态曲线

前言 用于实时显示数据动态曲线&#xff0c;比如&#xff1a;SOC。 //用于绘制动态曲线&#xff0c;可置于定时函数中&#xff0c;定时更新数据曲线 void DrawSocGraph() {double f (double)MainForm.readData[12]; //display datachart1.Series[0].Points.Add(f);if (ch…

影视cms泛目录用什么程序?苹果cms二次开发泛目录插件

影视CMS泛目录一般使用的程序有很多种&#xff0c;&#xff08;maccmscn&#xff09;以下是其中几种常见的程序&#xff1a; WordPress&#xff1a;WordPress是一个非常流行的开源内容管理系统&#xff0c;可以通过安装一些插件来实现影视CMS泛目录功能。其中&#xff0c;一款常…

高性能防静电主轴4033 AC-ESD 在线路板切割中的非凡表现

随着电子产品的日益小型化/集成化&#xff0c;线路板的制造也面临着更高的挑战。线路板分板作为电子制造流程中的关键环节&#xff0c;其效率和精度直接影响到最终产品的质量和市场竞争力。因此专用的高性能防静电主轴SycoTec 4033 AC-ESD凭借其卓越的性能&#xff0c;成为众多…