MongoDB(五)之分片

参考:http://www.lanceyan.com/tech/arch/mongodb_shard1.html

一、mongodb分片简介

在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的。而mongodb主打的就是海量数据架构,他不能解决海量数据怎么行!不行!“分片”就用这个来解决这个问题。 传统数据库怎么做海量数据读写?其实一句话概括:分而治之。上图看看就清楚了,如下 taobao岳旭强在infoq中提到的 架构图:

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

说了这么多传统数据库的架构,那Nosql怎么去做到了这些呢?mysql要做到自动扩展需要加一个数据访问层用程序去扩展,数据库的增加、删除、备份还需要程序去控制。一但数据库的节点一多,要维护起来也是非常头疼的。不过mongodb所有的这一切通过他自己的内部机制就可以搞定!还是上图看看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,其他机器没有分到的情况,这样还不如不分片!

分片的一些名词解释:

片键 :当设置分片时,需要从集合里面选择一个或几个键,把选择出来的键作为数据拆分的依据,这个键叫做片键或复合片键。 选好片键后,MongoDB将不允许插入没有片键的文档,但是允许不同文档的片键类型不一样。

块(chunk) :在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。chunk的产生,会有以下两个用途:

  • Splitting: 当一个chunk的大小超过配置中的chunk size时,MongDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况。
  • Balancing: 在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shard server的负载。

二、环境搭建

1、实验环境介绍

2、同步时间

[[email protected] ~]#  ntpdate 202.120.2.101
[[email protected] ~]# ntpdate 202.120.2.101
[[email protected] ~]# ntpdate 202.120.2.101
[[email protected] ~]# ntpdate 202.120.2.101

3、安装mongodb

注意剩下三台前面已经安装了mongodb这里就不列举了。

[[email protected] ~]#  
yum localinstall -y mongo-10gen-2.4.14-mongodb_1.x86_64.rpm mongo-10gen-server-2.4.14-mongodb_1.x86_64.rpm

4、配置config server

[[email protected] ~]# vim /etc/mongod.conf 
dbpath=/data/mongodb
configsvr = true
[[email protected] ~]# mkdir -p /data/mongodb
[[email protected] ~]# chown -R mongod.mongod /data/mongodb
[[email protected] ~]# service mongod start
Starting mongod: about to fork child process, waiting until server is ready for connections.
forked process: 130046
all output going to: /var/log/mongo/mongod.log
    
child process started successfully, parent exiting
                                                           [确定]
[[email protected] ~]# ss -tnlp |grep mongod
LISTEN     0      128                       *:28019                    *:*      users:(("mongod",130046,10))
LISTEN     0      128                       *:27019                    *:*      users:(("mongod",130046,9))

5、配置mongos

注意在前面做副本集实验时已经使用该机器,这里需要将在做副本集实验时的配置删除,并按以下配置。

[[email protected] ~]# vim /etc/mongod.conf 
#dbpath=/data/mongodb
configdb = 192.168.1.6:27019
[[email protected] ~]# mongos -f /etc/mongod.conf
Sat Sep 26 21:50:57.282 warning: running with 1 config server should be done only for testing purposes and is not recommended for production
about to fork child process, waiting until server is ready for connections.
forked process: 7485
all output going to: /var/log/mongo/mongod.log
child process started successfully, parent exiting
[[email protected] ~]# ss -tnlp |grep mongos
LISTEN     0      128                       *:28017                    *:*      users:(("mongos",7485,8))
LISTEN     0      128                       *:27017                    *:*      users:(("mongos",7485,6))

6、shard节点配置并启动

node1和node2节点也是在前面做副本集的实验中使用过,这里需要将在前面所增加的配置给删除,并按以下配置。

[[email protected] ~]# vim /etc/mongod.conf 
dbpath=/data/mongodb
[[email protected] ~]# service mongod start
[[email protected] ~]# vim /etc/mongod.conf 
dbpath=/data/mongodb
[[email protected] ~]# service mongod start

7、连入mongos

[[email protected] ~]# mongo --host 192.168.1.8
MongoDB shell version: 2.4.14
connecting to: 192.168.1.8:27017/test
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
 "_id" : 1,
 "version" : 3,
 "minCompatibleVersion" : 3,
 "currentVersion" : 4,
 "clusterId" : ObjectId("5606a2c30b2c688bc754432d")
}
  shards:
  databases:
 {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }

添加shard节点:
mongos> sh.addShard("192.168.1.9:27017")
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard("192.168.1.10:27017")
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
 "_id" : 1,
 "version" : 3,
 "minCompatibleVersion" : 3,
 "currentVersion" : 4,
 "clusterId" : ObjectId("5606a2c30b2c688bc754432d")
}
  shards:
 {  "_id" : "shard0000",  "host" : "192.168.1.9:27017" }
 {  "_id" : "shard0001",  "host" : "192.168.1.10:27017" }
  databases:
 {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
 {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }

将testdb库分片:

mongos> sh.enableSharding("testdb")
{ "ok" : 1 }
mongos> use testdb
switched to db testdb
mongos> sh.shardCollection("testdb.testcoll",{Age: 1,Name: 1})
{ "collectionsharded" : "testdb.testcoll", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
 "_id" : 1,
 "version" : 3,
 "minCompatibleVersion" : 3,
 "currentVersion" : 4,
 "clusterId" : ObjectId("5606a2c30b2c688bc754432d")
}
  shards:
 {  "_id" : "shard0000",  "host" : "192.168.1.9:27017" }
 {  "_id" : "shard0001",  "host" : "192.168.1.10:27017" }
  databases:
 {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
 {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
 {  "_id" : "testdb",  "partitioned" : true,  "primary" : "shard0001" }
  testdb.testcoll
   shard key: { "Age" : 1, "Name" : 1 }
   chunks:
    shard0001 1
   { "Age" : { "$minKey" : 1 }, "Name" : { "$minKey" : 1 } } -->> { "Age" : { "$maxKey" : 1 }, "Name" : { "$maxKey" : 1 } } on : shard0001 Timestamp(1, 0)

增加数据用来查看是否能分片:

mongos> for(i=1;i<=1000000;i++) db.testcoll.insert({Name: "User"+i,Age:(i%150),Address: "xinyang"})

另一台机器接入mongos,查看输入存放状态:

[[email protected] ~]# mongo --host 192.168.1.8
MongoDB shell version: 2.4.14
connecting to: 192.168.1.8:27017/test
mongos> use testdb
switched to db testdb
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
 "_id" : 1,
 "version" : 3,
 "minCompatibleVersion" : 3,
 "currentVersion" : 4,
 "clusterId" : ObjectId("5606a2c30b2c688bc754432d")
}
  shards:
 {  "_id" : "shard0000",  "host" : "192.168.1.9:27017" }
 {  "_id" : "shard0001",  "host" : "192.168.1.10:27017" }
  databases:
 {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
 {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
 {  "_id" : "testdb",  "partitioned" : true,  "primary" : "shard0001" }
  testdb.testcoll
   shard key: { "Age" : 1, "Name" : 1 }
   chunks:
    shard0000 1
    shard0001 3
   { "Age" : { "$minKey" : 1 }, "Name" : { "$minKey" : 1 } } -->> { "Age" : 1, "Name" : "User1" } on : shard0000 Timestamp(2, 0)
   { "Age" : 1, "Name" : "User1" } -->> { "Age" : 64, "Name" : "User92614" } on : shard0001 Timestamp(2, 2)
   { "Age" : 64, "Name" : "User92614" } -->> { "Age" : 149, "Name" : "User899" } on : shard0001 Timestamp(2, 3)
   { "Age" : 149, "Name" : "User899" } -->> { "Age" : { "$maxKey" : 1 }, "Name" : { "$maxKey" : 1 } } on : shard0001 Timestamp(1, 4) 
mongos> db.testcoll.find({Age: {$gt: 140}}).limit(3)
{ "_id" : ObjectId("5606b672ef76b4db97a7d713"), "Name" : "User100041", "Age" : 141, "Address" : "xinyang" }
{ "_id" : ObjectId("5606b672ef76b4db97a7d7a9"), "Name" : "User100191", "Age" : 141, "Address" : "xinyang" }
{ "_id" : ObjectId("5606b672ef76b4db97a7d83f"), "Name" : "User100341", "Age" : 141, "Address" : "xinyang" }
mongos> sh.getBalancerState()
true

总结:

这里只是简单的演示了mongodb的分片机制,在该实验中有几点问题需要解决:

  • shard节点出现故障就会出现数据丢失,故shard节点需要做副本集来增加高可用。
  • 同样config server也需要做到高可用。

以上就是我所想到的问题点,然而实际中还是有很多问题需要解决,本人水平有限,这里就不多说了,下面一个连接讲的架构就是利用三台机器做到的shard的高可用,但实际中还是不建议这么玩,在所有的分布式系统中建议还是增加主机使用,若机器较少,还是使用集中式的解决方案。毕竟关系型数据库技术是很成熟的,而所有的nosql也是这几年火起来的,若想使用还是要看公司的研发能力。个人认为在使用任何一个新技术术时一定不要盲目使用,需要看其缺点,而不是只看优点,同时根据自身的需求选择软件。只有最合适的没有最好的!我在使用四台虚拟机做该实验时本本是4G的内存,CPU是i5-5200U,可是还是卡的要死,所以伙伴们还是根据自身的硬件在玩mongodb吧,我这只是抛砖引玉。

时间: 2024-10-14 17:04:56

MongoDB(五)之分片的相关文章

走进MongoDB(五)---- 分片

本文从以下几个方面对MongoDB进行介绍 一.分片键组件 二.分片键 三.哈希分片 四.范围分片 五.区间 六.分片部署实例 Sharding概述 是分片.或者分区的意思.分片是一个数据库架构,可以通过key 范围拆分数据并且把拆分后的数据分散的存储到两个或多个数据库实例.分片提供了水平扩展的功能. MongoDB使用分片来支持超大数据集和高操作性能的部署要求.我们可以使用两种方法来支持数据量的大量增加和高性能操作要求:垂直扩展和水平扩展 1.垂直扩展: 通常是增加单机容量,例如.使用性能更高

【MongoDB】03、MongoDB索引及分片

一.MongoDB配置 mongodb配置文件/etc/mongodb.conf中的配置项,其实都是mongod启动选项(和memcached一样) [[email protected] ~]# mongod --help Allowed options: General options:   -h [ --help ]               show this usage information   --version                   show version inf

Mongodb副本集和分片的概念

副本集(Replica Set): 通俗的说,副本集就是集群,主从复制,读写分离,故障切换. 副本集是Mongodb原来的主从模式的升级版本,官方已经不再推荐使用主从模式. MongoDB的副本集与主从有所不同,主从在主机宕机后所有服务将停止,而副本集在主机宕机后,副本会接管主节点成为主节点,不会出现宕机的情况. mongodb的复制至少需要两个节点.其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据. mongodb各个节点常见的搭配方式为:一主一从.一主多从. 主

Mongodb 笔记07 分片

分片 1. 分片(sharding)是指将数据拆分,将其分散存放在不同的机器上的过程.有时也用分区(partitioning)来表示这个概念.将数据分散到不同的机器上,不需要功能强大的大型计算机就可以 存储更多的数据,处理更大的负载. 2. MongoDB支持自动分片(autosharding),可以使数据库架构对应用程序不可见,也可以简化系统管理.对应用程序而言,好像始终在使用一个单机的MongoDB服务器一样.另一方面, mongoDB自动处理数据在分片上的分布,也更容易添加和删除分片技术.

MongoDB中的分片

通过分片能够增加更多的机器来应对不断增加的负载和数据,还不影响应用.分片(sharding)是指将数据拆分,将其分散到不同的机器上,不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载. MongoDB支持自动分片,可以摆脱手动分片的管理困扰,集群自动切分数据,做负载均衡.分片的基本思想就是将集合切分成小块,这些块分散到若干片里面,每个片只负责总数据的一部分.应用程序不必知道哪片对应哪些数据,甚至不知道数据已经拆分,所以在分片之前要运行一个路由进程(mongos),这个路由知道所有数据

MongoDB学习笔记——分片(Sharding)

分片(Sharding) 分片就是将数据进行拆分,并将其分别存储在不同的服务器上 MongoDB支持自动分片能够自动处理数据在分片上的分布 MongoDB分片有三种角色 配置服务器:一个单独的mongod进程,主要记录了哪个分片服务器包含了哪些数据的信息,保存的只是数据的分布表,如果配置服务器不可用时,将变为只读,不能进行分片和数据迁移, 配置服务器的1KB空间相当于真实数据的200MB,所以配置服务器不需要太多的资源和配置.但是每个配置服务器都建议部署在不同的物理机上, 配置服务器相当于整个集

Mongodb 部署一个分片集群

根据下面的任务顺序来部署一个分片集群: 警告 分片和"localhost"地址 如果你使用"localhost"或者是127.0.0.1 作为任一节点标识的主机名部分,例如addShard 方法的host 参数或者是运行时操作 --configdb的值,那么你必须为集群中的所有MongoDB的所有节点设置都使用"localhost"或者是127.0.0.1.如果你把本地地址和远程地址混合使用的话,MongoDB将会出现错误. 启动Config S

MongoDB Sharding Cluster分片集群

MongoDB Sharding Cluster 第1章 分片技术简述: sharding是MongoDB用来将大型集合分割高不同服务器上所采用的方法,尽管分片起源于关系型数据库分区,但MongoDB分片完全又是另一回事 和mysql分区方案相比,MongoDB的最大区别在于它几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同的服务器之间的均衡 1.1 分片的目的: ?  垂直扩展:增加更多的cpu和存储资源来扩展容量,也属于硬件扩展 ?  水平扩展:将数据集分布

MySQL Cluster 与 MongoDB 复制群集分片设计及原理

分布式数据库计算涉及到分布式事务.数据分布.数据收敛计算等等要求 分布式数据库能实现高安全.高性能.高可用等特征,当然也带来了高成本(固定成本及运营成本),我们通过MongoDB及MySQL Cluster从实现上来分析其中的设计思路,用以抽象我们在设计数据库时,可以引用的部分设计方法,应用于我们的生产系统 首先说说关系及非关系数据库的特征 MySQL的Innodb及Cluster拥有完整的ACID属性 A 原子性 整个事务将作为一个整体,要么完成,要么回滚 C 一致性 事务开始之前和事务结束以

MongoDB 副本集+分片 认证方式搭建

MongoDB 副本集+分片 认证方式搭建 参考资料: https://www.cnblogs.com/ityouknow/p/7344005.htmlhttps://jorwen-fang.iteye.com/blog/2031756https://www.cnblogs.com/bjx2020/p/9350232.htmlhttps://www.jb51.net/article/161315.htmhttps://blog.51cto.com/beigai/1751381 环境规划: 服务器