zoukankan      html  css  js  c++  java
  • MongoDB学习笔记九:分片

    分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有事也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机既可以存储更多的数据,处理更大的负载。
    『MongoDB中的自动分片』
    MongoDB在分片之前要运行一个路由进程,该进程名为mongos。这个路由器知道多有数据的存放位置,所以应用可以连接它来正常发送请求。mongos对应用隐藏了分片的细节。
    何时分片?
        ·     机器的磁盘不够用了。
        ·     单个mongod已经不能满足写数据的性能需要了。
        ·     想将大量数据放在内存中提高性能。
    『片键』
    设置分片时,需要从集合里面选一个键,用改键的值作为数据拆分的依据。这个键成为片键(shard     key)。
    随着添加(或者删除)片,MongoDB会重新平衡数据,使每片的流量都比较均匀,数据量也在合理范围内。
    『将已有的集合分片』
    假设有个存储日志的集合,现在要分片。我们开启分片功能,然后告诉MongoDB用"timestamp"作为片键,就把所有数据放到了一个片上。可以随意插入数据,但总会是在一个片上。
    而后,增加一个片。这个片建好并运行了以后,MongoDB就会把集合拆分成两半,称为块。每个块中包含片键值在一定范围内的所有文档,所以就假设其中一块包含时间戳在2003年6月26日以前的文档,另一块含有2003年6月27日以后的文档。其中一块会被移动到新片上。
    如果新文档的时间戳在2003年6月27日之前,则添加到第一个块,否则就加到另一个块。
    【建立分片】
    建立分片有两步:启动实际的服务器,然后决定怎么切分数据。
    分片一般会有3个组成部分:
        ·     片
        片就是保存子集合数据的容器。片可以是单个的mongod服务器(开发和测试用),也可以是副本集(生产用)。所以,几遍一片内有多台服务器,也只能有一个主服务器,其他的服务器保存相同的数据。
        ·     mongos
        mongos就是MongoDB各版本中都配的路由器进程。它路由所有请求,然后将结果聚合。它本身并不存储数据或者配置信息(但会缓存配置服务器的信息)。
        ·     配置服务器
        配置服务器存储了集群的配置信息:数据和片的对应关系。mongos不永久存放数据,所以需要个地方存放分片配置。他会从配置服务器获取同步数据。
    『启动服务器』
    首先要启动配置服务器和mongos。配置服务器需要最先启动,因为mongos会用到其上的配置信息。配置服务器的启动就像普通mongod一样。
    $     mkdir     -p     ~/dbs/config
    $     ./mongod     --dbpath     ~/dbs/config     --port     20000
    配置服务器不需要很多空间和资源(200MB实际数据大约占用1KB的配置空间)。
    现在就可以建立mongos进程,以供应用程序连接。这种路由服务器连数据目录都不需要,但一定要指明配置服务器的位置:
    $     ./mongos     --port     30000     --configdb     localhost:20000
    分片管理通常是通过mongos完成的。
    添加片
    片就是普通的mongod实例(或者副本集):
    $     mkdir     -p     ~/dbs/shard1
    $     ./mongod     --dbpath     ~/dbs/shard1     --port     10000
    现在连接刚才启动的mongos,为集群添加一个片。启动shell,连接mongos:
    $     ./mongo     localhost:30000/admin
    MongoDB     shell     version:     1.6.0
    url:     localhost:30000/adminconnecting     to     localhost:30000/admin
    type     "help"     for     help
    >
    确定连接的是mongos而不是mongod后,就可以通过addshard命令添加片了:
    >     db.runCommand({addShard     :     "localhost:10000",     allowLocal     :     true})
    {
        "added"     :     "localhost:10000",
        "ok"     :     true
    }
    挡在localhost上运行分片时,得设定"allowLocal"键。MongoDB尽量避免由于错误配置,将集群配置到本地,所以得让它知道这仅仅是开发,而且我们很清楚自己在做什么。如果实在生产环境中,则要将其部署在不同的机器上。
    想添加片的时候,就运行addShard。MongoDB会负责将片集成到集群。
    『切分数据』
    MongoDB不会将存储的每一条数据都直接发布,得先在数据库和集合的级别将分片功能打开。下面的例子将以"_id"为急转切分foo数据库的bar集合。首先得开启foo的分片功能:
    >     db.runCommand({"enablesharding"     :     "foo"})
    对数据库分片后,其内部的集合便会存储到不同的片上,同时也是对这些集合分片的前置条件。
    在数据库的级别启动了分片以后,就可以使用shardCollection命令来对集合进行分片了:
    >     db.runCommand({"shardCollection"     :     "foo.bar",     "key"     :     {"_id"     :     1}})
    这样集合就按照"_id"分片了,在添加数据,就会依据"_id"的值自动分散到各个片上。
    【生产配置】
    成功地构建分片需要如下条件:
        ·     多个配置服务器。
        ·     多个mongos服务器。
        ·     每个片都是副本集。
        ·     正确设置w。
    例:设置3个配置服务器:
    $     mkdir     -p     ~/dbs/config1     ~/dbs/config2     ~/dbs/config3
    $     ./mongod     --dbpath     ~/dbs/config1     --port     20001
    $     ./mongod     --dbpath     ~/dbs/config2     --port     20002
    $     ./mongod     --dbpath     ~/dbs/config3     --port     20003
    然后,启动mongos的时候应将其连接到这3个配置服务器:
    $     ./mongos     --configdb     localhost:20001,localhost:20002,localhost:20003
    配置服务器使用的是两步提交机制——而不是普通MongoDB的异步复制——来维护集群配置的不同副本。这样能保证集群状态的一致性。这也意味着,某台配置服务器宕掉了以后,集群配置信息将是只读的。客户端还能够读写,但是只有所有配置服务器备份了以后才能重新均衡数据。    
    mongos的数量不受限制。建议针对一个应用服务器只运行一个mongos进程。这样每个应用服务器就可以与mongos进行本地回鹘,如果服务器不工作了,就不会有应用试图与不在的mongos通话了。
    『健壮的片』
    生产环境中,每个片都应是副本集。这样单个的服务器坏了,就不会导致整个片失效。用addshard命令就可以将副本集作为片添加。添加时只要指定副本集的名字和种子就好了。
    比如要添加副本集foo,其中包含一个服务器prod.example.com:27017(还有别的服务器),就可以使用下列命令将其添加到集群里:
    >     db.runCommand({"addshard"     :     "foo/prod.example.com:27017"})
    如果prod.example.com挂了,mongos会知道它所连接的是一个副本集,并会使用新的主节点。
    【管理分片】
    分片信息主要存放在config数据库上,这样就能被任何连接到mongos的进程访问到了。
    『配置集合』
    下几节的代码都假设已经在shell中连接了mongos,并且已经运行了use     config。
    ⒈片
    可以在shards集合中查到所有的片:
    >     db.shards.find()
    {     "_id"     :     "shard0",     "host"     :     "localhost:10000"     }
    {     "_id"     :     "shard1",     "host"     :     "localhost:10001"     }
    ⒉数据库
    databases集合含有已经在片上的数据库列表和一些相关信息:
    >     db.databases.find()
    {     "_id"     :     "admin",     "partitioned"     :     false,     "primary"     :     "config"     }
    {     "_id"     :     "foo",     "partitioned"     :     false,     "primary"     :     "shard1"     }
    {     "_id"     :     "x",     "partitioned"     :     false,     "primary"     :     "shard0"     }
    {
        "_id"     :     "test",
        "partitioned"     :     true,
        "primary"     :     "shard0",
        "sharded"     :     {
            "test.foo"     :     {
                "key"     :     {"x"     :     1},
                "unique"     :     false
            }
        }
    }
    这里是全部可用的数据库和一些基本信息。
        ·     "_id",字符串
        "_id"表示数据名。
        ·     "partitioned",布尔型
        如果为true,则表示已经启用分片功能。
        ·     "primary",字符串
        这个值与片的"_id"相对应,表明这个数据库的“大本营”在哪里。不论分片与否,数据库总是会有个大本营的。要是分片了的话,创建数据库时会随机选择一个片。也就是说,大本营是开始创建数据库文件的位置。虽然分片时数据库也会用到很多别的服务器,但是会从这个片开始。    
    ⒊块
    块信息保存在chunks集合中。它有很多有趣的东西,也可以看到数据到底是怎么切分到集群的:
    >     db.chunks.find()
    {
        "_id"     :     "test.foo-x_MinKey",
        "lastmod"     :     {     "t"     :     1276636243000,     "i"     :     1     },
        "ns"     :     "test.foo",
        "min"     :     {
            "x"     :     {     $minKey     :     1     }
        },
        "max"     :     {
            "x"     :     {     $maxKey     :     1     }
        },
        "shard"     :     "shard0"
    }
    单块的集合就是这样的:块的范围从-∞(MinKey)到∞(MaxKey)。

  • 相关阅读:
    有线电视网络(最小割)
    太空飞行计划问题(最小割,最大权闭合图,网络流24题)
    攻击装置(最小割,最大权独立集)
    王者之剑(最小割,最大独立集)
    善意的投票(最小割)
    有向图破坏(最小割,最小点权覆盖)
    线性代数(最小割,最大密度子图,TJOI2015)
    codewars--js--counting duplicates
    codewars--js--the highest and lowest number + JS 字符串和数组相关知识
    work
  • 原文地址:https://www.cnblogs.com/answernotfound/p/mongodbnote9.html
Copyright © 2011-2022 走看看