MongoDB 文档数据库【初阶】

文章目录

    • 一、MongoDB 基本介绍
      • 1、简介
      • 2、应用场景
      • 3、MongoDB的特点
      • 4、MongoDB的优势
      • 5、体系架构
    • 二、MongoDB 复制集
      • 1、复制集简介
      • 2、复制集四种架构及角色
      • 3、Oplog
      • 4、复制集数据同步流程
      • 5、复制集选举
      • 6、写——Writen Concern机制
      • 7、读——复制集读选项
    • 三、MongoDB 分片集
      • 1、分片目的
      • 2、分片集群架构
      • 3、数据分布策略
      • 4、Chunk迁移与数据平衡
      • 5、mongos路由策略
    • 四、MongoDB 安装部署
      • 0、常用CRUD操作
      • 1、单节点
      • 2、副本集:一主一从一仲裁
      • 3、分片集群
        • a.第一套副本集:一主一副本一仲裁
        • 启动第一套副本集
        • b.第二套副本集:一主一副本一仲裁
        • 启动第二套副本集
        • c.第三套副本集:配置节点副本集
        • 启动第三套副本集
        • d.第一个路由节点
        • 分片测试
        • e.第二个路由节点
        • 重置分片集群

一、MongoDB 基本介绍

1、简介

MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库

它支持的数据结构非常松散,是一种类似于 JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。

MongoDB中的记录是一个文档,它是一个由字段和值对(field:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。

MongoDB的3大核心优势
灵活模式:通过json文档来实现灵活模式。
高可用性:通过复制集来保证高可用。
可扩展性:通过Sharding cluster来保证可扩展性。

2、应用场景

传统的关系型数据库(如MySQL),在数据操作的“三高”需求以及应对Web2.0的网站需求面前,显得力不从心。

三高”需求:

  • High performance - 对数据库高并发读写的需求。
  • Huge Storage - 对海量数据的高效率存储和访问的需求。
  • High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求。

而MongoDB可应对“三高”需求。具体的应用场景如:

  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
  • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
  • 视频直播,使用 MongoDB 存储用户信息、点赞互动信息等。

这些应用场景中,数据操作方面的共同特点是:

  • 数据量大。
  • 写入操作频繁(读写都很频繁)。
  • 价值较低的数据,对事务性要求不高。

3、MongoDB的特点

  • 高性能

    MongoDB提供高性能的数据持久性。特别是,
    对嵌入式数据模型的支持减少了数据库系统上的I/O活动。
    索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。
    Gridfs解决文件存储的需求。
    mmapv1、WiredTiger、mongorocks(rocksdb)、in-memory 等多引擎支持满足各种场景需求。

  • 高可用性

    MongoDB的复制工具称为副本集(replica set),它可提供自动故障转移和数据冗余。

  • 高扩展性

    MongoDB提供了水平可扩展性作为其核心功能的一部分。分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展)

  • 丰富的查询支持

    MongoDB支持丰富的查询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等。

  • 其他特点:如无模式(动态模式)、灵活的文档模型等

4、MongoDB的优势

  • 读写效率高 – Data locality
    由于文档模型把相关数据集中在一块,在普通机械盘上读数据的时候不用花太多时间去定位磁头,因此在IO性能上有先天独厚的优势;
  • 可扩展能力强 – 无关联易分库
    关系型数据库很难做分布式的原因就是多节点海量数据关联有巨大的性能问题。如果不考虑关联,数据分区分库,水平扩展就比较简单;
  • 动态模式 – 灵活应对不同数据模型
    文档模型支持可变的数据模式,不要求每个文档都具有完全相同的结构。对很多异构数据场景支持非常好;
  • 模型自然 – 最接近于对象模型
    文档模型最接近于我们熟悉的对象模型。从内存到存储,无需经过ORM的双向转换,性能上和理解上都很自然易懂。

5、体系架构

MongoDB 文档数据库【初阶】_第1张图片

SQL 术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
嵌入文档 MongoDB通过嵌入式文档来替代多表连接
primary key primary key 主键,MongoDB自动将_id字段设置为主键

二、MongoDB 复制集

1、复制集简介

MongoDB中的副本集(Replica Set)是一组维护相同数据集的mongod服务。 副本集可提供冗余和高可用性,是所有生产部署的基础。

通俗的讲就是用多台机器进行同一数据的异步同步,从而使多台机器拥有同一数据的多个副本,并且当主库宕掉时在不需要用户干预的情况下自动切换其他备份服务器做主库。而且还可以利用副本服务器做只读服务器,实现读写分离,提高负载。

副本集作用

  • 1)高可用
    防止设备(服务器、网络)故障。
    提供自动failover 功能。
  • 2)灾难恢复
    当发生故障时,可以从其他节点恢复。
  • 3)功能隔离
    用于分析、报表,数据挖掘,系统任务等。
    用于备份。
  • 4)运维升级&数据维护
    滚动升级从节点,最后升级主节点。

2、复制集四种架构及角色

MongoDB 文档数据库【初阶】_第2张图片

  • 1)主节点(Primary)

MongoDB复制集由一组mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点。

Primary节点接收所有来自客户端的写操作,并会将所有数据集的变动记录到oplog
复制集为所有来自主节点的读提供了严格的一致性校验 。

  • 2)副本节点(Secondary)

MongoDB复制集由一组mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点。
一旦主节点不可用,复制集就会将一个从节点选举成为新的主节点。

  • 3)仲裁节点(Arbiter)

仲裁节点并不包含数据集,它仅仅是在选举过程中参与投票。

如果你的副本+主节点的个数是偶数,建议加一个仲裁者,形成奇数,容易满足大多数的投票。
如果你的副本+主节点的个数是奇数,可以不加仲裁者。

  • 4)Hidden节点

Hidden节点不能被选为主(Priority为0),并且对Driver不可见。因Hidden节点不会接受Driver的请求,可使用Hidden节点做一些数据备份、离线计算的任务,不会影响复制集的服务。

  • 5)Delayed节点

Delayed节点必须是Hidden节点。因Delayed节点的数据比Primary落后一段时间,当错误或者无效的数据写入Primary时,可通过Delayed节点的数据来恢复到之前的时间点。

3、Oplog

  • 作用:Primary与Secondary之间通过oplog来同步数据。

Primary上的写操作完成后,会向特殊的local.oplog.rs特殊集合写入一条oplog,Secondary不断的从Primary取新的oplog并应用,从而实现Replication的功能。同时由于其记录了Primary上的写操作,故还能将其用作数据恢复。可以简单的将其视作MySQL中的binlog。

  • 大小:Oplog是一个capped collection【通俗意思就是它是固定大小,循环使用的】。MongoDB默认将其大小设置为可用disk空间的5%。
  • Oplog格式样例:
{
	"ts": Timestamp(1646912240, 1),  ##操作时间
	"t": NumberLong(4),              ##数据类型
	"h": NumberLong("478351560757205978"),   ##全局唯一操作符
	"v": 2,     ##oplog版本
	"op": "n",  ##操作类型:i-插入,u-更新,d-删除,c-执行命令(如create/dropDatabase),n-空操作 
	"ns": "articleadb.test",  ##操作的集合      
	"wall": ISODate("2022-03-10T11:37:20.281Z"),
	"o": {             ##操作内容   
		"_id" : ObjectId("622f15dc7284015c7a121e2f"), "x" : 14548 }
	}
}

4、复制集数据同步流程

MongoDB复制集里的Secondary会从Primary上同步数据,以保持副本集所有节点的数据保持一致,数据同步主要包含2个过程:initial sync、replication。

先通过init sync同步全量数据,再通过replication不断重放Primary上的oplog同步增量数据。

  • 同步流程:

step1、T1时间,从Primary同步所有数据库的数据(local除外),通过 istDatabases + listCollections + cloneCollection命令组合完成, 假设T2时间完成所有操作。
step2、从Primary应用[T1-T2]时间段内的所有oplog,可能部分操作已经包含在步骤1,但由于oplog的幂等性,可重复应用。
step3、根据Primary各集合的index设置,在Secondary上为相应集合创建index。(每个集合_id的index已在步骤1中完成)。

  • 同步场景分析

a、副本集初始化

初始化选出Primary后,此时Secondary上无有效数据,oplog是空的,会先进行initial sync,然后不断的应用新的oplog 。

b、新加入成员

因新成员上无有效数据,会先进行initial sync,然后不断的应用新的oplog。

c、有数据的节点加入

如果该节点最新的oplog时间戳,比所有节点最旧的oplog时间戳还要小,该节点将找不到同步源,会一直处于RECOVERING而不能服务;反之,如果能找到同步源,则直接进入replication阶段,不断的应用新的oplog。

注意:因oplog太旧而处于RECOVERING的节点目前无法自动恢复,需人工介入处理(故设置合理的oplog大小非常重要),最简单的方式是发送resync命令,让该节点重新进行initial sync

官方给出两种方式:第一种是停掉数据库,直接删除本地数据,然后启动mongo数据库,启动之后存在一个同步的过程,会非常耗时。另一种方式是停掉数据库,直接拷贝主节点上的数据,然后再启动mongo,这样就不存在数据同步的过程了,但是拷贝主节点上的数据,也有一个问题,就是数据时刻在变化,拷贝过程中难免会漏掉一些数据。

通过 db.printReplicationInfo()可以查看oplog的一些信息:

db.printReplicationInfo();
configured oplog size:   1518.617431640625MB
log length start to end: 349348secs (97.04hrs)
oplog first event time:  Thu Mar 10 2022 19:22:29 GMT+0800 (CST)
oplog last event time:   Mon Mar 14 2022 20:24:57 GMT+0800 (CST)
now:                     Mon Mar 14 2022 20:24:56 GMT+0800 (CST)
  • 异常处理

当Primary宕机时,如果有数据未同步到Secondary,当Primary重新加入时,如果新的Primary上已经发生了写操作,则旧Primary需要回滚部分操作,以保证数据集与新的Primary一致。
旧Primary将回滚的数据写到单独的rollback目录下,数据库管理员可根据需要使用mongorestore进行恢复。

5、复制集选举

复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Priamry选举操作,获得大多数成员投票支持的节点,会成为Primary,其余节点成为Secondary。

当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。

  • 复制集选举场景

    复制集的初始化。
    复制集被reconfig。
    Secondary节点检测到Primary宕机时,会触发新Primary的选举。
    当有Primary节点主动stepDown(主动降级为Secondary)时,也会触发新的Primary选举。
    复制集成员心跳检测结果发生变化,比如某个节点挂了或者新增节点。

  • 节点间心跳

    Primary的选举受节点间心跳、优先级、最新的oplog时间等多种因素影响。

    复制集成员间默认每2s会发送一次心跳信息,如果10s未收到某个节点的心跳,则认为该节点已宕机;如果宕机的节点为 Primary,Secondary(前提是可被选为Primary)会发起新的Primary选举。

    每个节点都倾向于投票给优先级最高的节点。
    优先级默认为1,取值为0-1000。
    优先级为0的节点不会主动发起Primary选举。

    当Primary发现有优先级更高Secondary,并且该Secondary的数据落后在10s内,则Primary会主动降级,让优先级更高的 Secondary有成为Primary的机会。(reconfig)

  • Optime

    拥有最新optime(最近一条oplog的时间戳)的节点才能被选为主。

  • 网络分区

    只有更大多数投票节点间保持网络连通,才有机会被选Primary;如果Primary与大多数的节点断开连接,Primary会主动降级为Secondary。当发生网络分区时,可能在短时间内出现多个 Primary【类似脑裂】。

  • Vote属性

    复制集成员最多50个,但是参与Primary选举投票的成员最多7个,其他成员的votes属性必须设置为0,即不参与投票。

6、写——Writen Concern机制

写关注机制用来指定MongoDB对写操作的回执行为。可在connection level或者写操作level指定。

  • {w:0}——关闭Writen Concern。

  • {w:1}——MongoDB在写完内存后发送确认。系统崩溃时可能会丢失最多100ms数据。

  • {w:1,j: true}——刷盘Journal之后再发送写回执。Group Commit 30ms间隔,所以单个请求可能会等最多30ms才返回。

  • {w:n}——等待数据复制到n个节点再发送回执。

  • {w:majority}——等待数据复制到大多数节点再发送回执。

MongoDB 文档数据库【初阶】_第3张图片

7、读——复制集读选项

默认情况下,复制集的所有读请求都发到Primary,Driver可通过设置Read Preference来将读请求路由到其他的节点。

  • primary:默认规则,所有读请求发到Primary。
  • primaryPreferred:Primary优先,如果Primary不可达,请求Secondary。
  • secondary:所有的读请求都发到secondary。
  • secondaryPreferred:Secondary优先,当所有Secondary不可达时,请求Primary。
  • nearest:读请求发送到最近的可达节点上(通过ping探测得出最近的节点)。

三、MongoDB 分片集

1、分片目的

分片(sharding)是一种跨多台机器分布数据的方法, MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。

具有大型数据集或高吞吐量应用程序的数据库系统可以会挑战单个服务器的容量。例如,高查询率会耗尽服务器的CPU容量。工作集大小大于系统的RAM会抢掉磁盘驱动器的I/O容量。

MongoDB支持通过分片进行水平扩展来解决系统增长。

MongoDB的3大核心优势:
• 灵活模式:通过json文档来实现灵活模式。
• 高可用性:通过复制集来保证高可用。
• 可扩展性:通过Sharding cluster来保证可扩展性

当MongoDB复制集遇到下面的业务场景时,需要考虑使用Sharding cluster:
• 存储容量需求超出单机磁盘容量。
• 活跃的数据集超出单机内存容量,导致很多请求都要从磁盘读取数 据,影响性能。
• 写IOPS超出单个MongoDB节点的写服务能力。

2、分片集群架构

Sharding Cluster由Mongos、Config server 和 Shard 3个组件构成。

  • Mongos路由:客户端请求的入口。
  • Config server配置中心:存储Sharding Cluster的所有元数据。[主要是Chunk信息]
  • Shard分片:存储应用数据记录。

MongoDB 文档数据库【初阶】_第4张图片

如何确定 shard、mongos 数量?

shard、mongos的数量归根结底是由应用需求决定。

  • 如果你使用 sharding 只是解决海量数据存储的问题,访问并不多,那么很简单,假设你单个shard能存储 M, 需要的存储总量是N。
    n u m b e r O f S h a r d s = N / M / 0.75 numberOfShards = N / M / 0.75 numberOfShards=N/M/0.75

    n u m b e r O f M o n g o s = 2 + numberOfMongos = 2+ numberOfMongos=2+

  • 如果你使用sharding是解决高并发写入(或读取)数据的问题,总的数据量其实很小。假设单个shard最大qps为M,单个mongos最大qps为Ms,需要总的qps为N。
    n u m b e r O f S h a r d s = N / M / 0.75 numberOfShards = N / M / 0.75 numberOfShards=N/M/0.75

    n u m b e r O f M o n g o s = N / M s / 0.75 numberOfMongos = N / Ms/0.75 numberOfMongos=N/Ms/0.75

3、数据分布策略

  • 策略一:范围分片

集合根据x字段来分片,x的取值范围为[minKey, maxKey],将整个取值范围划分为多个chunk,每个chunk的数据都存储在同一个Shard上,每个Shard可以存储很多个chunk,chunk存储在哪个shard的信息会存储在Config server种,mongos也会根据各个shard上的chunk的数量来自动做负载均衡。

范围分片的优点:
范围分片能很好的满足范围查询的需求,比如想查询x的值在[-30, 10]之间的所有文档,这时mongos直接能将请求路由到ChunkX,就能查询出所有符合条件的文档。

范围分片的缺点:
如果shard key有明显递增(或者递减)趋势,则新插入的文档多会分布到同一个chunk,无法扩展写的能力。

  • chunk分裂

对于一个刚配置为Sharding的collection ,最开始只有一个chunk,范围是从-∞到 +∞。随着数据的增长,其中的数据大小超过了配置的chunk size,默认是64M,则这个chunk就会分裂成两个。数据的增长会让chunk分裂得越来越多。

  • 策略二:hash分片

Hash分片是根据用户的shard key计算hash值(64bit整型),根据hash值按照范围分片的策略将文档分布到不同的chunk。

Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。

  • 分片键

必须为分片集群定义分片键。

分片键基于一个或多个字段。

分片键决定了文档在集群中的位置。

一旦集合已经分片,就不可以直接修改分片键。

分片键必须有索引。

分片键大小限制512bytes。

MongoDB不接受已进行collection级分片的collection上插入无分片键的文档(也不支持空值插入)。

  • 如何选择一个优秀的片键?

所有的插入、更新以及删除将会均匀分发到集群中的所有分片中。

所有的查询将会在集群中的所有分片中平均地分发。

所有的操作将会只面向相关的分片:更新或者删除操作将不会发送到一个没有存储被修改数据的分片上。

相似地,一个查询将不会被送到没有存储被查询数据的分片上。

  • 分片键选择建议

1)递增的shard key(范围片键)
数据文件挪动小。(优势)
因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写热点。
同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。

2)随机的shard key(Hash片键)
数据分布均匀,insert的写IO均匀分布在多个片上。(优势)
大量的随机IO,磁盘不堪重荷。

3)混合型shard key(范围+Hash)
大方向随机递增。
小范围随机分布。

4、Chunk迁移与数据平衡

  • 基本概念

Chunk:数据块。

MongoDB基于分片键范围将数据分区到数据块中。

数据的均衡通过数据块的迁移来达到,MongoDB会尝试在不同的片之间保持数据均衡。

初始1个chunk。缺省chunk 大小:64MB。chunksize设置通常100-200M。小的chunksize:数据均衡是迁移速度快,数据分布更均匀,但是数据分裂频繁,路由节点消耗更多资源。大的chunksize:数据分裂少,但是数据块移动集中消耗IO资源。

MongoDB自动拆分 & 迁移chunks。

Banlancer:后台任务。该任务不断对针对下面3种场景来判断是否需要迁移chunk,如果需要,则发送moveChunk命令到源shard上开始迁移,整个迁移过程比较复杂。同事也提供了moveChunk 命令,让用户能主动的触发数据迁移。

  • 需要chunk迁移的场景

1)场景1:
当多个shard上chunk数量分布不均时,MongoDB会自动的在shard间迁移chunk,尽可能让各个shard上chunk数量均匀分布。
2)场景2:
用户调用removeShard命令后,被移除shard上的chunk就需要被迁移到其他的shard上,等该shard上没有数据后,安全下线。
3)场景3:
MongoDB sharding支持shard tag功能,可以对shard及shard key range打标签,系统会自动将对应range的数据迁移到拥有相同tag的shard上。

  • Banlancer工作步骤

Step1:获取集合对应的chunk分布信息。
Step2:检查是否需要chunk分裂。
Step3:迁移draining shard上的chunk。
Step4:迁移tag不匹配的chunk。
Step5:负载均衡迁移。
Step6:执行迁移。

Balancer是基于各个shard持有的chunk数量来做负载均衡迁移,如果一个集合在2个shard里的chunk数量相差超过一定阈值,则会触发迁移。 (通过对比持有chunk 最多和最少的shard)。eg:当集合的chunk数量小于20时,如果2个shard 间chunk数量相差大于或等于2时,就会构建迁移任务,将某个chunk从持有chunk最多的shard迁移到持有chunk最少的 shard。

  • moveChunk命令

MongoDB 文档数据库【初阶】_第5张图片

5、mongos路由策略

在Shard Cluster里,用户可以将集合的数据以chunk为单位分散存储到多个shard 上。

当写入新文档时,mongos从config server上获取集合的路由表本地,mongos从config server上获取到路由表后,会缓存在本地内存,避免每次写入/查询都去config server上取表。而在Sharded Cluster里,mongos会自动在shard之间迁移chunk以均衡负载(用户也可以发送moveChunk命令来手动迁移),那么一旦 chunk 发生迁移后,mongos 本地缓存的路由表就会失效,从而请求被路由到错误的 shard。

MongoDB 的做法是给路由表增加版本信息,mongos在写入时,会带上自身缓存的路由表版本,当请求到达shard后,shard 发现mongos的路由表版本比自己的低,则说明路由表已经发生过更新,这时mongos会重新到config server上取最新的路由表,然后按新的路由表来写入。

四、MongoDB 安装部署

0、常用CRUD操作

# 常用命令
#选择切换数据库:
use articledb
#插入数据:
db.comment.insert({bson数据})
db.comment.insert({bson数据1},{bson数据2},{bson数据3})

#查询所有数据:
db.comment.find();
#条件查询数据:
db.comment.find({条件})
#查询符合条件的第一条记录:
db.comment.findOne({条件})
#查询符合条件的前几条记录:
db.comment.find({条件}).limit(条数)
#查询符合条件的跳过的记录:
db.comment.find({条件}).skip(条数)

#修改数据:
db.comment.update({条件},{修改后的数据})
db.comment.update({条件},{$set:{要修改部分的字段:数据})
#修改数据并自增某字段值:
db.comment.update({条件},{$inc:{自增的字段:步进值}})

#删除数据:
db.comment.remove({条件})
#集合创建:
db.createCollection("mycollection")
#集合删除:
db.mycollection.drop()

#统计查询:
db.comment.count({条件})
#模糊查询:
db.comment.find({字段名:/正则表达式/})
#条件比较运算:
db.comment.find({字段名:{$gt:}})
#包含查询:
db.comment.find({字段名:{$in:[值1,值2]}})
db.comment.find({字段名:{$nin:[值1,值2]}})
#条件连接查询:
db.comment.find({$and:[{条件1},{条件2}]})或db.comment.find({$or:[{条件1},{条件2}]})

1、单节点

# 单节点 后台启动
mongod -f /etc/mongod.conf

# 关闭服务的方法
#方法一
kill -2 Pid

#如果一旦是因为数据损坏,则需要进行如下操作
rm -f /mongodb/single/data/db/*.lock
mongod --repair --dbpath=/var/lib/mongo

#方法二:标准的关闭方法(数据不容易出错,但是比较麻烦)
#客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
##切换到admin库
use admin
#关闭服务
db.shutdownServer()
#必须是在 admin库下执行该关闭服务命令。
#如果没有开启认证,必须是从 localhost登陆的,才能执行关闭服务命令。
#非 localhost的、通过远程登录的,必须有登录且必须登录用户有对admin操作权限才可以。

2、副本集:一主一从一仲裁

#第一步 准备主节点
mkdir -p /mongodb/replica_sets/myrs_27017/log
mkdir -p /mongodb/replica_sets/myrs_27017/data/db
vim /mongodb/replica_sets/myrs_27017/mongod.conf
#第二步 准备副本节点
mkdir -p /mongodb/replica_sets/myrs_27018/log
mkdir -p /mongodb/replica_sets/myrs_27018/data/db
vim /mongodb/replica_sets/myrs_27018/mongod.conf
#第三步 准备仲裁节点
mkdir -p /mongodb/replica_sets/myrs_27019/log
mkdir -p /mongodb/replica_sets/myrs_27019/data/db
vim /mongodb/replica_sets/myrs_27019/mongod.conf
#第四步 启动节点
# 启动主节点、启动副本节点、启动仲裁节点
mongod -f /mongodb/replica_sets/myrs_27017/mongod.conf
mongod -f /mongodb/replica_sets/myrs_27018/mongod.conf
mongod -f /mongodb/replica_sets/myrs_27019/mongod.conf

# 连接主节点
mongo --host 192.168.168.101 --port 27017
# 第五步 初始化副本集和主节点
rs.initiate()

rs.conf()

rs.status()

rs.add("192.168.168.101:27018")

# 第五步 添加仲裁节点
rs.addArb("192.168.168.101:27019")
# 如果加入有问题(卡住,很长时间后报错)  先执行下面命令,参考:https://docs.mongodb.com/manual/reference/command/setDefaultRWConcern/
db.adminCommand({
  "setDefaultRWConcern" : 1,
  "defaultWriteConcern" : {
    "w" : 2
  }
})

rs.status

#从库 设置为奴隶节点,允许在从成员上运行读的操作
rs.secondaryOk()

## 副本集的关闭
#关闭副本集中的服务,建议依次关闭仲裁节点→副本节点→主节点。
#客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。

#先关闭仲裁节点
mongo --port 27018
#告知副本集说本机要下线
rs.stepDown()
#切换到admin库
use admin
#关闭服务
db.shutdownServer()

#再关闭副本节点
mongo --port 27018
#告知副本集说本机要下线
rs.stepDown()
#切换到admin库
use admin
#关闭服务
db.shutdownServer()

#最后关闭主节点
mongo --port 27017
#告知副本集说本机要下线
rs.stepDown()
#切换到admin库
use admin
#关闭服务
db.shutdownServer()
# 主节点
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/replica_sets/myrs_27017/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/replica_sets/myrs_27017/data/db"
  journal:
#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27017
replication:
  #副本集的名称
  replSetName: myrs

# 副本节点
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/replica_sets/myrs_27018/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/replica_sets/myrs_27018/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/replica_sets/myrs_27018/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27018
replication:
  #副本集的名称
  replSetName: myrs
  
# 仲裁节点  官方文档建议:不要在同时承载副本集的主成员或辅助成员的系统上运行仲裁服务器
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/replica_sets/myrs_27019/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/replica_sets/myrs_27019/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/replica_sets/myrs_27019/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27019
replication:
  #副本集的名称
  replSetName: myrs

3、分片集群

MongoDB 文档数据库【初阶】_第6张图片

a.第一套副本集:一主一副本一仲裁

mkdir -p /mongodb/sharded_cluster/myshardrs01_27018/log
mkdir -p /mongodb/sharded_cluster/myshardrs01_27018/data/db
mkdir -p /mongodb/sharded_cluster/myshardrs01_27118/log
mkdir -p /mongodb/sharded_cluster/myshardrs01_27118/data/db
mkdir -p /mongodb/sharded_cluster/myshardrs01_27218/log
mkdir -p /mongodb/sharded_cluster/myshardrs01_27218/data/db

vim /mongodb/sharded_cluster/myshardrs01_27018/mongod.conf

#myshardrs01_27018
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs01_27018/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27018
replication:
  #副本集的名称
  replSetName: myshardrs01
sharding:
  #分片角色
  clusterRole: shardsvr

vim /mongodb/sharded_cluster/myshardrs01_27118/mongod.conf

#myshardrs01_27118
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs01_27118/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs01_27118/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27118/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27118
replication:
  replSetName: myshardrs01
sharding:
  clusterRole: shardsvr

vim /mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

#myshardrs01_27218
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs01_27218/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs01_27218/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27218/log/mongod.pid"
net:
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27218
replication:
  replSetName: myshardrs01
sharding:
  clusterRole: shardsvr

启动第一套副本集

mongod -f /mongodb/sharded_cluster/myshardrs01_27018/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs01_27118/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

ps -ef |grep mongod

mongo --host 192.168.168.101 --port 27018
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27118")
rs.addArb("192.168.168.101:27218")
rs.conf()

b.第二套副本集:一主一副本一仲裁

mkdir -p /mongodb/sharded_cluster/myshardrs02_27318/log
mkdir -p /mongodb/sharded_cluster/myshardrs02_27318/data/db
mkdir -p /mongodb/sharded_cluster/myshardrs02_27418/log
mkdir -p /mongodb/sharded_cluster/myshardrs02_27418/data/db
mkdir -p /mongodb/sharded_cluster/myshardrs02_27518/log
mkdir -p /mongodb/sharded_cluster/myshardrs02_27518/data/db

vim /mongodb/sharded_cluster/myshardrs02_27318/mongod.conf

#myshardrs02_27318
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs02_27318/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs02_27318/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27318/log/mongod.pid"
net:
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27318
replication:
  replSetName: myshardrs02
sharding:
  clusterRole: shardsvr
  
vim /mongodb/sharded_cluster/myshardrs02_27418/mongod.conf

#myshardrs02_27418
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs02_27418/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs02_27418/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27418/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27418
replication:
  replSetName: myshardrs02
sharding:
  clusterRole: shardsvr

vim /mongodb/sharded_cluster/myshardrs02_27518/mongod.conf

#myshardrs02_27518
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myshardrs02_27518/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myshardrs02_27518/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27518/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27518
replication:
  replSetName: myshardrs02
sharding:
  clusterRole: shardsvr

启动第二套副本集

mongod -f /mongodb/sharded_cluster/myshardrs02_27318/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs02_27418/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs02_27518/mongod.conf

ps -ef |grep mongod

mongo --host 192.168.168.101 --port 27318
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27418")
rs.addArb("192.168.168.101:27518")
rs.conf()
rs.status()

c.第三套副本集:配置节点副本集

mkdir -p /mongodb/sharded_cluster/myconfigrs_27019/log
mkdir -p /mongodb/sharded_cluster/myconfigrs_27019/data/db
mkdir -p /mongodb/sharded_cluster/myconfigrs_27119/log
mkdir -p /mongodb/sharded_cluster/myconfigrs_27119/data/db
mkdir -p /mongodb/sharded_cluster/myconfigrs_27219/log
mkdir -p /mongodb/sharded_cluster/myconfigrs_27219/data/db

vim /mongodb/sharded_cluster/myconfigrs_27019/mongod.conf

# myconfigrs_27019
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myconfigrs_27019/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myconfigrs_27019/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myconfigrs_27019/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27019
replication:
  replSetName: myconfigrs
sharding:
  clusterRole: configsvr

vim /mongodb/sharded_cluster/myconfigrs_27119/mongod.conf

#myconfigrs_27119
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myconfigrs_27119/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myconfigrs_27119/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myconfigrs_27119/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27119
replication:
  replSetName: myconfigrs
sharding:
  clusterRole: configsvr
 
vim /mongodb/sharded_cluster/myconfigrs_27219/mongod.conf
 
# myconfigrs_27219
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/myconfigrs_27219/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
storage:
  #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  dbPath: "/mongodb/sharded_cluster/myconfigrs_27219/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
    enabled: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: "/mongodb/sharded_cluster/myconfigrs_27219/log/mongod.pid"
net:
  #服务实例绑定所有IP
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #绑定的端口
  port: 27219
replication:
  replSetName: myconfigrs
sharding:
  clusterRole: configsvr

启动第三套副本集

mongod -f /mongodb/sharded_cluster/myconfigrs_27019/mongod.conf
mongod -f /mongodb/sharded_cluster/myconfigrs_27119/mongod.conf
mongod -f /mongodb/sharded_cluster/myconfigrs_27219/mongod.conf

ps -ef |grep mongod

mongo --host 192.168.168.101 --port 27019
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27119")
rs.add("192.168.168.101:27219")
rs.conf()
rs.status()

d.第一个路由节点

mkdir -p /mongodb/sharded_cluster/mymongos_27017/log

vim /mongodb/sharded_cluster/mymongos_27017/mongos.conf

# mongos.conf
systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/mymongos_27017/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: /mongodb/sharded_cluster/mymongos_27017/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27017
sharding:
  #指定配置节点副本集
  configDB: myconfigrs/192.168.168.101:27019,192.168.168.101:27119,192.168.168.101:27219
  
mongos -f /mongodb/sharded_cluster/mymongos_27017/mongos.conf

mongo --host 192.168.168.101 --port 27017

# 添加第一套分片
sh.addShard("myshardrs01/192.168.168.101:27018,192.168.168.101:27118,192.168.168.101:27218")

sh.status()

# 添加第二套分片
sh.addShard("myshardrs02/192.168.168.101:27318,192.168.168.101:27418,192.168.168.101:27518")

sh.status()

# 如何移除分片
use admin
db.runCommand( { removeShard: "myshardrs02" } )

#开启分片功能
sh.enableSharding("articledb")

#集合分片【基于范围的分片方式与基于哈希的分片方式性能对比】
#分片规则一:哈希策略
sh.shardCollection("articledb.comment",{"nickname":"hashed"})
#分片规则二:范围策略
sh.shardCollection("articledb.author",{"age":1})

#显示集群的详细信息
db.printShardingStatus()
#查看均衡器是否工作【需要重新均衡时系统会自动启动】
sh.isBalancerRunning()
#查看当前 Balancer状态
sh.getBalancerState()

分片测试

# 测试一(哈希规则):登录mongs后,向comment循环插入1000条数据做测试
use articledb
# js的语法,因为mongo的shell是一个JavaScript的shell
for(var i=1;i<=1000;i++){db.comment.insert({_id:i+"",nickname:"BoBo"+i})}

db.comment.count()

# 登录第一个分片集
mongo --host 192.168.168.101 --port 27018
# 计算有多少个记录
use articledb
db.comment.count()

# 登录第二个分片集
mongo --host 192.168.168.101 --port 27318
# 计算有多少个记录
use articledb
db.comment.count()
#结论:可以看到, 1000条数据近似均匀的分布到了2个shard上。是根据片键的哈希值分配的。这种分配方式非常易于水平扩展:一旦数据存储需要更大空间,可以直接再增加分片即可,同时提升了性能。

#测试二(范围规则):登录mongs后,向comment循环插入1000条数据做测试
use articledb
#js的语法【下面这条命令执行时间比较长】
for(var i=1;i<=20000;i++){db.author.save({"name":"BoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBoBo"+i,"age":NumberInt(i%120)})}
db.author.count()

# 登录第一个分片集
mongo --host 192.168.168.101 --port 27018
# 计算有多少个记录
use articledb
db.author.count()

# 登录第二个分片集
mongo --host 192.168.168.101 --port 27318
# 计算有多少个记录
use articledb
db.author.count()
#如果查看状态发现没有分片,则可能是由于以下原因造成:
#1)系统繁忙,正在分片中。
#2)数据块(chunk)没有填满,默认的数据块尺寸(chunksize)是64M,填满后才会考虑向其他片的数据块填充数据,因此,为了测试,可以将其改小,这里改为1M,操作如下:
use config
db.settings.save( { _id:"chunksize", value: 1 } )
#要先改小,再设置分片。为了测试,可以先删除集合,重新建立集合的分片策略,再插入数据测试即可。
db.settings.save( { _id:"chunksize", value: 64 } )

e.第二个路由节点

mkdir -p /mongodb/sharded_cluster/mymongos_27117/log

vi /mongodb/sharded_cluster/mymongos_27117/mongos.conf

systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  path: "/mongodb/sharded_cluster/mymongos_27117/log/mongod.log"
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
  logAppend: true
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式。
  fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  pidFilePath: /mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:
  #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
  #bindIpAll: true
  #服务实例绑定的IP
  bindIp: localhost,192.168.168.101
  #bindIp
  #绑定的端口
  port: 27117
sharding:
  #指定配置节点副本集
  configDB: myconfigrs/192.168.168.101:27019,192.168.168.101:27119,192.168.168.101:27219

mongos -f /mongodb/sharded_cluster/mymongos_27117/mongos.conf

mongo --host 192.168.168.101 --port 27117
#第二个路由无需配置,因为分片配置都保存到了配置服务器

重置分片集群

如果在搭建分片的时候有操作失败或配置有问题,需要重新来过的,可以进行如下操作:

#第一步:查询出所有的测试服务节点的进程
ps -ef |grep mongo

kill -2 进程编号

#第二步:清除所有节点【十一个节点】的数据
rm -rf /mongodb/sharded_cluster/myshardrs01_27018/data/db/*
rm -rf /mongodb/sharded_cluster/myshardrs01_27118/data/db/*
rm -rf /mongodb/sharded_cluster/myshardrs01_27218/data/db/*
rm -rf /mongodb/sharded_cluster/myshardrs02_27318/data/db/*
rm -rf /mongodb/sharded_cluster/myshardrs02_27418/data/db/*
rm -rf /mongodb/sharded_cluster/myshardrs02_27518/data/db/*
rm -rf /mongodb/sharded_cluster/myconfigrs_27019/data/db/*
rm -rf /mongodb/sharded_cluster/myconfigrs_27119/data/db/*
rm -rf /mongodb/sharded_cluster/myconfigrs_27219/data/db/*
# rm -rf /mongodb/sharded_cluster/mymongos_27017/data/db/*.*
# rm -rf /mongodb/sharded_cluster/mymongos_27117/data/db/*.*

#第三步:查看或修改有问题的配置
#第四步:依次启动所有节点,不包括路由节点
mongod -f /mongodb/sharded_cluster/myshardrs01_27018/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs01_27118/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

#启动第一套副本集
mongo --host 192.168.168.101 --port 27018
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27118")
rs.addArb("192.168.168.101:27218")
rs.conf()

mongod -f /mongodb/sharded_cluster/myshardrs02_27318/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs02_27418/mongod.conf
mongod -f /mongodb/sharded_cluster/myshardrs02_27518/mongod.conf

#启动第二套副本集
mongo --host 192.168.168.101 --port 27318
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27418")
rs.addArb("192.168.168.101:27518")
rs.conf()
rs.status()

mongod -f /mongodb/sharded_cluster/myconfigrs_27019/mongod.conf
mongod -f /mongodb/sharded_cluster/myconfigrs_27119/mongod.conf
mongod -f /mongodb/sharded_cluster/myconfigrs_27219/mongod.conf

#启动第三套副本集
mongo --host 192.168.168.101 --port 27019
rs.initiate()
rs.conf()
rs.add("192.168.168.101:27119")
rs.add("192.168.168.101:27219")
rs.conf()
rs.status()

#第五步:对两个数据分片副本集和一个配置副本集进行初始化和相关配置
#第六步:检查路由mongos的配置,并启动mongos
mongos -f /mongodb/sharded_cluster/mymongos_27017/mongos.conf

#启动第一个路由
mongo --host 192.168.168.101 --port 27017
# 添加第一套分片
sh.addShard("myshardrs01/192.168.168.101:27018,192.168.168.101:27118,192.168.168.101:27218")
sh.status()
# 添加第二套分片
sh.addShard("myshardrs02/192.168.168.101:27318,192.168.168.101:27418,192.168.168.101:27518")
sh.status()

#启动第二个路由【自动同步分片】
mongos -f /mongodb/sharded_cluster/mymongos_27117/mongos.conf
#第七步:mongo登录mongos,在其上进行相关操作。

你可能感兴趣的:(数据库,数据库,mongodb,nosql)