前面几篇文章的分析复制集解决了数据库的备份与自动故障转移,但是围绕数据库的业务中当前还有两个方面的问题变得越来越重要。一是海量数据如何存储?二是如何高效的读写海量数据?尽管复制集也可以实现读写分析,如在primary节点上写,在secondary节点上读,但在这种方式下客户端读出来的数据有可能不是最新的,因为primary节点到secondary节点间的数据同步会带来一定延迟,而且这种方式也不能处理大量数据。mongoDB从设计之初就考虑了上面所提到的两个问题,引入了分片机制,实现了海量数据的分布式存储与高效的读写分离。复制集中的每个成员是一个mongod实例,但在分片部署上,每一个片可能就是一个复制集。

上面谈到了分片的优点,但分片的使用,会使数据库系统变得复杂。什么时候使用分片也是需要考虑的问题。mongoDB使用内存映射文件的方式来读写数据库,对内存的管理由操作系统来负责,随着运行时间的推移,数据库的索引和数据文件会变得越来越大,对于单节点的机器来说,迟早会突破内存的限制,当磁盘上的数据文件和索引远大于内存的大小时,这个时候操作系统会频繁的进行内存交换,导致整个数据库系统的读写性能下降。因此对于大数据的处理,要时刻监控mongoDB的磁盘I/O性能、可用内存的大小,在数据库内存使用率达到一定程度时就要考虑分片了。通过分片使整个数据库分布在各个片上,每个片拥有数据库的一部分数据,从而降低内存使用率,提高读写性能。

分片部署架构

下面看看一个具体的分片部署架构是什么,为了后续的研究,先部署一个分片集群。

分片集群主要由mongos路由进程、复制集组成的片shards、一组配置服务器Configure构成,下面对这些模块一一解释。

分片集群中的一个片shard实际上就是一个复制集,当然一个片也可以是单个mongod实例,只是在分片集群的生产环境中,每个片只是保存整个数据库数据的一部分,如果这部分数据丢失了,那么整个数据库就不完整了,因此应该保证每个片上的数据稳定性和完整性,通过第7章对复制集的分析,复制集能够达到这样的要求。因此通过将片配置为复制集的形式,使片shard在默认情况下读写都在复制集的primary节点上,每个片同时具有自动故障转移、冗余备份的功能,总之复制集所具有的的特性在片上都能得到体现。

mongos路由进程是一个轻量级且非持久性的进程。轻量级表示它不会保存任何数据库中的数据,它只是将整个分片集群看成一个整体,使分片集群对整个客户端程序来说是透明的,当客户端发起读写操作时,由mongos路由进程将该操作路由到具体的片上进行;为了实现对读写请求的路由,mongos进程必须知道整个分片集群上所有数据库的分片情况即元信息,这些信息是从配置服务器上同步过来的,每次进程启动时都会从configure服务器上读元信息,mongos并非持久化保存这些信息。

配置服务器configure在整个分片集群中想到重要,上面说到mongos会从配置服务器同步元信息,因此配置服务器要能实现这些元信息的持久化。配置服务器上的数据如果丢失,那么整个分片集群就无法使用,因此在生产环境中通常利用三台配置服务器来实现冗余备份,这三台服务器是独立的,并不是复制集架构。

下面按照上图描述来配置一个这样的分片集群。

(1)配置复制集rs0并启动,参考前面关于复制集中介绍的6个步骤。

先创建好rs0中各节点的数据文件存放路径、日志文件路径以及配置文件,其中配置文件的内容如下:

rs0中primary节点的配置文件为rs0_0.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_0

logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_0.log

journal = true

port = 40000

replSet = rs0

rs0中secondary节点的配置文件为rs0_1.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_1

logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_1.log

journal = true

port = 40001

replSet = rs0

rs0中arbiter节点的配置文件为rs0_2.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_2

logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_2.log

journal = true

port = 40002

replSet = rs0

按照7.1节介绍的步骤启动复制集rs0。

(2)配置复制集rs1并启动,步骤与上面相同,这里给出rs2中各节点对应的配置文件内容。

rs1中primary节点的配置文件为rs1_0.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs1\data\rs1_0

logpath = E:\mongodb-win32-i386-2.4.3\db_rs1\logs\rs1_0.log

journal = true

port = 40003

replSet = rs1

rs1中primary节点的配置文件为rs1_1.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs1\data\rs1_1

logpath = E:\mongodb-win32-i386-2.4.3\db_rs1\logs\rs1_1.log

journal = true

port = 40004

replSet = rs1

rs1中primary节点的配置文件为rs1_2.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs1\data\rs1_2

logpath = E:\mongodb-win32-i386-2.4.3\db_rs1\logs\rs1_2.log

journal = true

port = 40005

replSet = rs1

按照7.1节介绍的步骤启动复制集rs0

通过rs.status()检查并确认上述复制集已启动且配置正确。

(3)配置configure服务器

configure服务器也是一个mongod进程,它与普通的mongod实例没有本质区别,只是它上面的数据库以及集合是特意给分片集群用的,其内容会在后面详细介绍。三个独立的配置服务器对应的启动配置文件内容如下:

configure服务器1的配置文件cfgserver_0.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_configs\data\db_config0

logpath = E:\mongodb-win32-i386-2.4.3\db_configs\logs\db_config0.log

journal = true

port = 40006

configsvr = true

configure服务器2的配置文件cfgserver_1.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_configs\data\db_config1

logpath = E:\mongodb-win32-i386-2.4.3\db_configs\logs\db_config1.log

journal = true

port = 40007

configsvr = true

configure服务器3的配置文件cfgserver_2.conf:

dbpath = E:\mongodb-win32-i386-2.4.3\db_configs\data\db_config2

logpath = E:\mongodb-win32-i386-2.4.3\db_configs\logs\db_config2.log

journal = true

port = 40008

configsvr = true

配置服务器上的mongod实例启动时的配置选项与普通的mongod实例差不多,这里只是多了一个configsvr=true的选择,说明这个mongod实例是一个configure类型的mongod实例。

启动上面三个配置服务器:

>mongod --config E:\mongodb-win32-i386-2.4.3\configs_cfgservers\cfgserver_0.conf

>mongod --config E:\mongodb-win32-i386-2.4.3\configs_cfgservers\cfgserver_1.conf

>mongod --config E:\mongodb-win32-i386-2.4.3\configs_cfgservers\cfgserver_2.conf

(4)配置mongos路由服务器

其配置文件cfg_mongos.conf内容为:

logpath = E:\mongodb-win32-i386-2.4.3\mongos\logs\mongos.log

port = 40009

configdb = Guo:40006,GuO:40007,GuO:40008

启动路由服务器:

>mongos --config E:\mongodb-win32-i386-2.4.3\mongos\cfg_mongos.conf

实例对应的进程为mongos,路由服务器只是一个轻量级和非持久化操作的进程,因此上面的配置文件里面没有像其它mongod实例那样有一个存放数据文件的路径选项dbpath。

(5)添加各分片到集群

上面已经完成了两个片(复制集)、三个配置服务器、一个路由服务器且它已经知道从哪些配置服务器上同步元数据(configdb = Guo:40006,GuO:40007,GuO:40008),接下来要做的是将各个片添加到集群中。

打开一个mongo客户端连接到mongos服务器:

>mongo --port 40009

添加两个分片

mongos> sh.addShard("rs0/GUO:40000,GUO:40001")

{ "shardAdded" : "rs0", "ok" : 1 }

mongos> sh.addShard("rs1/GUO:40003,GUO:40004")

{ "shardAdded" : "rs1", "ok" : 1 }

这里添加分片的命令是sh.addShard(),参数是复制集名以及复制集中不包含arbiter类型的所有节点。

(6)最后通过命令sh.status()检查上面的配置是否正确,正常的话输出信息类似下面:

mongos> sh.status()

--- Sharding Status ---

sharding version: {

"_id" : 1,

"version" : 3,

"minCompatibleVersion" : 3,

"currentVersion" : 4,

"clusterId" : ObjectId("521b11e0a663075416070c04")

}

shards:

{  "_id" : "rs0",  "host" : "rs0/Guo:40000,Guo:40001" }

{  "_id" : "rs1",  "host" : "rs1/Guo:40003,Guo:40004" }

databases:

{  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }

上面输出的信息中clusterId字段表示此分片集群的唯一标示;shards为分片集群中包含的所有片,其中_id为此片的名称,host为片中的主机的host信息;databases为集群中的所有数据库,其中_id为数据库名称,partitioned表示此数据库是否支持分片;primary表示当数据库支持分片,此数据库上所有未分片的集合所在的片。

此时在整个分片集群中还没有创建任何其它数据库,通过路由进程mongos连接集群,执行命令show dbs可以看到集群中只有系统默认创建的一个config数据库,且这个数据库只存在于三个配置服务器上,config数据库中的集合包含了整个集群的配置信息,执行命令show collections,可以看到有如下集合:

mongos> show collections

changelog:保存被分片的集合的任何元数据的改变,例如chunks的迁移、分割等。

Chunks:保存集群中分片集合的所有块的信息,包含块的数据范围与块所在的片。

Databases:保存集群中的所有数据库,包含分片与未分片的。

Lockpings:保存跟踪集群中的激活组件。

locks:均衡器balancer执行时会生产锁,在此集合中插入一条记录。

mongos:保存了集群中所有路由mongos的信息。

Settings:保存分片集群的配置信息,如每个chunk的大小(64MB)、均衡器的状态。

Shards:保存了集群中的所有片的信息。

system.indexes:保存config数据库中的所有索引信息。

Version:保存当前所有元信息的版本。

由上所述得知,配置服务器中的config数据库的信息对于整个集群来说是至关重要的,这也是生产环境中最少需要3个配置服务器做冗余备份的原因;同时上面对config数据库的所有操作,都是通过客户端连接mongos后再进行的,尽管config数据库也是在单个mongod实例上,我们可以直接通过客户端连接到这个实例,然后做操作,但是这样会出现配置服务器上的信息不一致的风险,因此我们队集群的所有操作应该是通过客户端连接mongos来执行。

最好探讨一下实际部署的问题,通过上图和前面的分析可知,一个生产环境的最少需要9个mongod实例进程,一个mongos进程实例,理论上说最少需要10台机器才能组成。但是这些进程中有些并不需要很多软硬件资源,它们可以与其它进程共存部署在同一个机器上,如复制集中arbiter进程、mongos进程可以部署到应用程序所在的服务器,综合考虑后可以得到下面一个典型的部署:

图8.2

上图部署的总体原则是使每一个片(复制集)中的primary节点、secondary节点、arbiter节点分开以及三台配置服务器分开,当图中的四台机器任何一台宕机后,集群都能够正常运行。

mongoDB研究笔记:分片集群部署的更多相关文章

  1. MongoDB DBA 实践8-----Linux系统Mongodb分片集群部署

    在Linux系统中,主要是使用命令行进行mongodb的分片集群部署 一.先决条件 mongodb安装成功,明确路径, MongoDB的几个路径: /var/lib/mongodb /var/log/ ...

  2. MongoDB之分片集群(Sharding)

    MongoDB之分片集群(Sharding) 一.基本概念 分片(sharding)是一个通过多台机器分配数据的方法.MongoDB使用分片支持大数据集和高吞吐量的操作.大数据集和高吞吐量的数据库系统 ...

  3. 【MongoDB】在windows平台下mongodb的分片集群(五)

    本篇接着上面的四篇继续讲述在window平台下mongodb的分片集群搭建. 在分片集群中也照样能够创建索引,创建索引的方式与在单独数据库中创建索引的方式一样.因此这不再多说.本篇主要聚焦在分片键的选 ...

  4. MongoDB DBA 实践6-----MongoDB的分片集群部署

    一.分片 MongoDB使用分片技术来支持大数据集和高吞吐量操作. 1.分片目的 对于单台数据库服务器,庞大的数据量及高吞吐量的应用程序对它而言无疑是个巨大的挑战.频繁的CRUD操作能够耗尽服务器的C ...

  5. MongoDB分片集群部署方案

    前言 副本集部署是对数据的冗余和增加读请求的处理能力,却不能提高写请求的处理能力:关键问题是随着数据增加,单机硬件配置会成为性能的瓶颈.而分片集群可以很好的解决这一问题,通过水平扩展来提升性能.分片部 ...

  6. MongoDB在windows平台分片集群部署

    本文转载自:https://www.cnblogs.com/hx764208769/p/4260177.html 前言-为什么我要使用mongodb 最近我公司要开发一个日志系统,这个日志系统包括很多 ...

  7. MongoDB部署实战(一)MongoDB在windows平台分片集群部署

    前言-为什么我要使用mongodb 最近我公司要开发一个日志系统,这个日志系统包括很多类型,错误的,操作的,...用MongoDB存储日志,大量的日志产生,大量读写吞吐量很大的时候,单个Server很 ...

  8. MongoDB之分片集群与复制集

    分片集群 1.1.概念 分片集群是将数据存储在多台机器上的操作,主要由查询路由mongos.分片.配置服务器组成. ●查询路由根据配置服务器上的元数据将请求分发到相应的分片上,本身不存储集群的元数据, ...

  9. monodb分片集群部署

    本文档基于MongoDB版本3.6.2 下载地址: 建议使用最新版本 https://www.mongodb.com/download-center#community 安装文件 集群ip及端口设计方 ...

随机推荐

  1. php数据结构与算法

    php面试题之二--数据结构和算法(高级部分) 二.数据结构和算法 1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator ...

  2. Pro Android 4 第六章 构建用户界面以及使用控件(一)

         目前为止,我们已经介绍了android的基础内容,但是还没开始接触用户界面(UI).本章我们将开始探讨用户界面和控件.我们先讨论一下android中UI设计的一般原理,然后我们在介绍一下an ...

  3. 面试 | 商汤科技面试经历之Promise红绿灯的实现

    说在前面 说实话,刚开始在听到这个面试题的实话,我是诧异的,红绿灯?这不是单片机.FPGA.F28335.PLC的实验吗?! 而且还要用Promise去写,当时我确实没思路,只好硬着头皮去写,下来再r ...

  4. 从零学习Fluter(六):Flutter仿boss直聘v1.0重构

    今天继续学习flutter,觉得这个优秀的东西,许多方面还需要完善,作为一个后来者,要多向别人学习.俗话说,“学无先后,达者为师”.今天呢,我又重新把flutter_boss这个项目代码 从头到脚看了 ...

  5. 从Scratch到Python——python turtle 一种比pygame更加简洁的实现

    从Scratch到Python--python turtle 一种比pygame更加简洁的实现 现在很多学校都开设了Scratch课程,学生可以利用Scratch创作丰富的作品,然而Scratch之后 ...

  6. 我的django2

    1.做双系统(不现实启动项就再做一遍) 2.更新源 3.下载软件 看ubuntu篇,一直到mysql安装完. 4. 第一部分 搭建本地虚拟环境 第二部分 编辑 @部署??: 服务器端安装pip3,dj ...

  7. Vue(八)发送跨域请求

    使用vue-resource发送跨域请求 axios不支持跨域 1 安装vue-resource并引入 cnpm install vue-resource -S 2 基本用法 使用this.$http ...

  8. javascript篇-typeof,instanceof,constructor,toString判断数据类型的用法和区别

    javascript基本数据类型有:string,number,Boolean,undefined,null 引用类型(复杂类型):object, ES6中新增了一种数据类型:Symbol 以上数据类 ...

  9. Ford VCM II Ford VCM2 Diagnostic Tool with Ford IDS v108 Installed On Laptop Ready to Use

    HOW to VCM2 Ford VCM II with Ford IDS v108 Work Well? VCM2 Ford VCM2 Ford diagnostic tool hot sale i ...

  10. 用ArrayAdapter来创建Spinner(自定义布局、默认布局、动态内容、静态内容)

             android:dropDownWidth 下拉列表宽度 android:dropDownHorizontalOffset 下拉列表距离左边的距离 android:dropDownV ...