前面几篇文章的分析复制集解决了数据库的备份与自动故障转移,但是围绕数据库的业务中当前还有两个方面的问题变得越来越重要。一是海量数据如何存储?二是如何高效的读写海量数据?尽管复制集也可以实现读写分析,如在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. (转)oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”

    Oracle删除用户的提示无法删除当前已连接用户两种解决方法如下: 1.先锁定用户.然后查询进程号,最后删除对应的进程.在删除对应的用户 SQLalter user XXX account lock; ...

  2. 压缩文本、字节或者文件的压缩辅助类-GZipHelper

    下面为大家介绍一.NET下辅助公共类GZipHelper,该工具类主要作用是对文本.字符.文件等进行压缩与解压.该类主要使用命名空间:System.IO.Compression下的GZipStream ...

  3. Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

    转载请包含网址:http://blog.csdn.net/pathuang68/article/details/7351317 一.Surface Surface就是“表面”的意思.在SDK的文档中, ...

  4. node服务器

    markdown support HTTP服务器 一.服务器基本方法 "use strict"; // 1.加载http模块 const http = require('http' ...

  5. MVC 之 WebAPI 系列二

    今天,我想在此记录下 WebApi 跨域调用 1. 什么叫跨域: 跨域问题简单理解就是JavaScript同源策略的限制,其根本原因是因为浏览器对于这种请求,所给予的权限是较低的,通常只允许调用本域中 ...

  6. 史上最强防火墙iptables

    #1.清空所有的防火墙规则 iptables -F iptables -X iptables -Z iptables -t NAT -F iptables -t NAT -X iptables -t ...

  7. iOS开发时,在Xcode中添加多个Targets进行版本控制

    在iOS开发中,很可能有以下场景:需要开发多个版本,或因需区分收费版,免费版,或因为网络环境需要区分测试版,发布版,或因渠道不同需要区分企业版,AppStore版等等.解决办法无非就是CheckOut ...

  8. Socket通信基本原理

    Http通信: http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据. Socket通信: Socket通信则是在双方建立起连接后就 ...

  9. BZOJ1261: [SCOI2006]zh_tree

    Description 张老师根据自己工作的需要,设计了一种特殊的二叉搜索树.他把这种二叉树起名为zh_tree,对于具有n个结点的zh_tree,其中序遍历恰好为(1,2,3,-,n),其中数字1, ...

  10. android混淆那些事

    写给Android开发者的混淆使用手册 综述 毫无疑问,混淆是打包过程中最重要的流程之一,在没有特殊原因的情况下,所有 app 都应该开启混淆. 首先,这里说的的混淆其实是包括了代码压缩.代码混淆以及 ...