专栏首页运维经验分享搭建高可用mongodb集群(四)—— 分片 原

搭建高可用mongodb集群(四)—— 分片 原

搭建高可用mongodb集群(四)—— 分片

Posted on 29 三月, 2014 by lanceyan | 104 Replies

按照上一节中《搭建高可用mongodb集群(三)—— 深入副本集》搭建后还有两个问题没有解决:

  • 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大?
  • 数据压力大到机器支撑不了的时候能否做到自动扩展?

在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的。而mongodb主打的就是海量数据架构,他不能解决海量数据怎么行!不行!“分片”就用这个来解决这个问题。

传统数据库怎么做海量数据读写?其实一句话概括:分而治之。上图看看就清楚了,如下 taobao岳旭强在infoq中提到的 架构图:

上图中有个TDDL,是taobao的一个数据访问层组件,他主要的作用是SQL解析、路由处理。根据应用的请求的功能解析当前访问的sql判断是在哪个业务数据库、哪个表访问查询并返回数据结果。具体如图:

说了这么多传统数据库的架构,那Nosql怎么去做到了这些呢?mysql要做到自动扩展需要加一个数据访问层用程序去扩展,数据库的增加、删除、备份还需要程序去控制。一但数据库的节点一多,要维护起来也是非常头疼的。不过mongodb所有的这一切通过他自己的内部机制就可以搞定!顿时石化了,这么牛X!还是上图看看mongodb通过哪些机制实现路由、分片:

从图中可以看到有四个组件:mongos、config server、shard、replica set。

mongos,数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

config server,顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,这个可不能丢失!就算挂掉其中一台,只要还有存货, mongodb集群就不会挂掉。

shard,这就是传说中的分片了。上面提到一个机器就算能力再大也有天花板,就像军队打仗一样,一个人再厉害喝血瓶也拼不过对方的一个师。俗话说三个臭皮匠顶个诸葛亮,这个时候团队的力量就凸显出来了。在互联网也是这样,一台普通的机器做不了的多台机器来做,如下图:

一台机器的一个数据表 Collection1 存储了 1T 数据,压力太大了!在分给4个机器后,每个机器都是256G,则分摊了集中在一台机器的压力。也许有人问一台机器硬盘加大一点不就可以了,为什么要分给四台机器呢?不要光想到存储空间,实际运行的数据库还有硬盘的读写、网络的IO、CPU和内存的瓶颈。在mongodb集群只要设置好了分片规则,通过mongos操作数据库就能自动把对应的数据操作请求转发到对应的分片机器上。在生产环境中分片的片键可要好好设置,这个影响到了怎么把数据均匀分到多个分片机器上,不要出现其中一台机器分了1T,其他机器没有分到的情况,这样还不如不分片!

replica set,上两节已经详细讲过了这个东东,怎么这里又来凑热闹!其实上图4个分片如果没有 replica set 是个不完整架构,假设其中的一个分片挂掉那四分之一的数据就丢失了,所以在高可用性的分片架构还需要对于每一个分片构建 replica set 副本集保证分片的可靠性。生产环境通常是 2个副本 + 1个仲裁。

说了这么多,还是来实战一下如何搭建高可用的mongodb集群:

首先确定各个组件的数量,mongos 3个, config server 3个,数据分3片 shard server 3个,每个shard 有一个副本一个仲裁也就是 3 * 2 = 6 个,总共需要部署15个实例。这些实例可以部署在独立机器也可以部署在一台机器,我们这里测试资源有限,只准备了 3台机器,在同一台机器只要端口不同就可以,看一下物理部署图:

架构搭好了,安装软件!

  • 1、准备机器,IP分别设置为: 192.168.0.136、192.168.0.137、192.168.0.138。

1 2

#存放mongodb数据文件 mkdir -p /data/mongodbtest

1

wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.8.tgz

  • 4、分别在每台机器建立mongos 、config 、 shard1 、shard2、shard3 五个目录。 因为mongos不存储数据,只需要建立日志文件目录即可。 1 2 #建立mongos目录 mkdir -p /data/mongodbtest/mongos/log 1 2 #建立config server 数据文件存放目录 mkdir -p /data/mongodbtest/config/data 1 2 #建立config server 日志文件存放目录 mkdir -p /data/mongodbtest/config/log 1 2 #建立config server 日志文件存放目录 mkdir -p /data/mongodbtest/mongos/log 1 2 #建立shard1 数据文件存放目录 mkdir -p /data/mongodbtest/shard1/data 1 2 #建立shard1 日志文件存放目录 mkdir -p /data/mongodbtest/shard1/log 1 2 #建立shard2 数据文件存放目录 mkdir -p /data/mongodbtest/shard2/data 1 2 #建立shard2 日志文件存放目录 mkdir -p /data/mongodbtest/shard2/log 1 2 #建立shard3 数据文件存放目录 mkdir -p /data/mongodbtest/shard3/data 1 2 #建立shard3 日志文件存放目录 mkdir -p /data/mongodbtest/shard3/log
  • 5、规划5个组件对应的端口号,由于一个机器需要同时部署 mongos、config server 、shard1、shard2、shard3,所以需要用端口进行区分。 这个端口可以自由定义,在本文 mongos为 20000, config server 为 21000, shard1为 22001 , shard2为22002, shard3为22003.

1

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --configsvr --dbpath /data/mongodbtest/config/data --port 21000 --logpath /data/mongodbtest/config/log/config.log --fork

1

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongos  --configdb 192.168.0.136:21000,192.168.0.137:21000,192.168.0.138:21000  --port 20000   --logpath  /data/mongodbtest/mongos/log/mongos.log --fork

1 2

#在每个机器里分别设置分片1服务器及副本集shard1 /data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --shardsvr --replSet shard1 --port 22001 --dbpath /data/mongodbtest/shard1/data  --logpath /data/mongodbtest/shard1/log/shard1.log --fork --nojournal  --oplogSize 10

1 2

#连接到mongos /data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:20000

  • 10、目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片,就差那么一点点,一点点。。。 连接在mongos上,准备让指定的数据库、指定的集合分片生效。 1 2 #指定testdb分片生效 db.runCommand( { enablesharding :"testdb"}); 1 2 #指定数据库里需要分片的集合和片键 db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } ) 我们设置testdb的 table1 表需要分片,根据 id 自动分片到 shard1 ,shard2,shard3 上面去。要这样设置是因为不是所有mongodb 的数据库和表 都需要分片!

1 2

#连接mongos服务器 /data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:20000

整个分片集群搭建完了,思考一下我们这个架构是不是足够好呢?其实还有很多地方需要优化,比如我们把所有的仲裁节点放在一台机器,其余两台机器承担了全部读写操作,但是作为仲裁的192.168.0.138相当空闲。让机器3 192.168.0.138多分担点责任吧!架构可以这样调整,把机器的负载分的更加均衡一点,每个机器既可以作为主节点、副本节点、仲裁节点,这样压力就会均衡很多了,如图:

当然生产环境的数据远远大于当前的测试数据,大规模数据应用情况下我们不可能把全部的节点像这样部署,硬件瓶颈是硬伤,只能扩展机器。要用好mongodb还有很多机制需要调整,不过通过这个东东我们可以快速实现高可用性、高扩展性,所以它还是一个非常不错的Nosql组件。

再看看我们使用的mongodb java 驱动客户端 MongoClient(addresses),这个可以传入多个mongos 的地址作为mongodb集群的入口,并且可以实现自动故障转移,但是负载均衡做的好不好呢?打开源代码查看:

它的机制是选择一个ping 最快的机器来作为所有请求的入口,如果这台机器挂掉会使用下一台机器。那这样。。。。肯定是不行的!万一出现双十一这样的情况所有请求集中发送到这一台机器,这台机器很有可能挂掉。一但挂掉了,按照它的机制会转移请求到下台机器,但是这个压力总量还是没有减少啊!下一台还是可能崩溃,所以这个架构还有漏洞!不过这个文章已经太长了,后续解决吧。

参考: http://docs.mongodb.org/manual/core/sharding-introduction/

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 搭建高可用mongodb集群(四)—— 分片

    Posted on 29 三月, 2014 by lanceyan | 104 Replies

    拓荒者
  • CentOS7/RHEL7-使用yum快速安装mongodb3.6

    CentOS上安装epel-release的yum源之后就可以安装MongoDB,但是版本都是比较老的,如果使用MongoDB官方的yum就可以安装到比较新版本...

    拓荒者
  • CentOS7.2中安装MongoDB

    MongoDB是由C++编写的NoSQL的分布式文件数据库,用的json格式的k-value存储方式。

    拓荒者
  • 搭建高可用mongodb集群(四)—— 分片

    按照上一节中《搭建高可用mongodb集群(三)—— 深入副本集》搭建后还有两个问题没有解决:

    九州暮云
  • 搭建高可用mongodb集群(四)—— 分片

    Posted on 29 三月, 2014 by lanceyan | 104 Replies

    拓荒者
  • 简单易学的机器学习算法——极限学习机(ELM)

    一、极限学习机的概念        极限学习机(Extreme Learning Machine) ELM,是由黄广斌提出来的求解单隐层神经网络的算法。 EL...

    zhaozhiyong
  • “猜你喜欢”的背后揭秘——我偷偷知道你喜欢什么哟

    话说,最近的瓜实在有点多,从我科校友李雨桐怒锤某男、陈羽凡吸毒被捕、蒋劲夫家暴的三连瓜,到不知知网翟博士,再到邓紫棋解约蜂鸟、王思聪花千芳隔空互怼。

    用户1621951
  • Golang Leetcode 442. Find All Duplicates in an Array.go

    版权声明:原创勿转 https://blog.csdn.net/anakinsun/article/details/89143761

    anakinsun
  • 数组乘积--满足result[i] = input数组中除了input[i]之外所有数的乘积(假设不会溢出

    数组乘积(15分) 输入:一个长度为n的整数数组input 输出:一个长度为n的整数数组result,满足result[i] = input数组中除了inp...

    猿人谷
  • hdu1010

    @坤的

扫码关注云+社区

领取腾讯云代金券