分片
Last updated
Was this helpful?
Last updated
Was this helpful?
分片就是将一个大数据集切割成多个小数据集, 并将这些小数据集分发到不同机器/服务器上的一种方法, 从而能够存储更多的数据及提高吞吐量。
对单个服务器而言,当数据量比较大,或者吞吐量比较大,都会给其带来极大的挑战。例如,高查询率会耗尽服务器的CPU容量。
解决上述情况的方法有两种:垂直和水平扩展。
垂直扩展通过增加单个服务器的容量和性能来提高性能,例如使用更强大的CPU,添加更多RAM或增加存储空间量。但是这种方式具有一定的局限性,一是具有技术的局限性,毕竟不可能无限制地增加单个机器的配置,其二是现在一般都是采用云服务器,而云提供商提供的硬件配置也是会有上限的。
水平扩展(分片是水平扩展的一种)是通过将数据集进行划并分发到多台机器上来提高性能。虽然单个机器的总体速度或容量可能不高,但每台机器只需处理整个数据集的的子集,所以可能会提供比单个高速大容量服务器更高的效率,而且机器的数量只需要根据数据集大小来进行扩展,这可能比单个机器的高端硬件的总体成本更低。不过这种方式会提高维护和部署的复杂度。
一个MongoDB的分片式集群包含以下的组件:
shard:每个shard包含的是整个数据集的一个子集。每个shard都能被部署成副本集(replica set)的形式。
mongos:mongos扮演的是“查询路由”的角色, 提供了一个让客户端和分片集群通信的接口。
config servers:配置服务器的作用是存储集群的元数据和配置信息。从MongoDB3.4开始,配置服务器必须部署为副本集(CSRS)
架构图如下:
为了更好地说明,博猪又重新画了一个图(画得不好的话请见谅)
我们知道, 数据库包含集合,集合包含文档,文档里面有很多字段/键, 如上图。
对于分片键,它也不是什么高级的东东,它就是文档里面的一个字段,但是这个字段不是普通的字段,有一定的要求
它必须在所有文档中都出现
它必须是集合的一个索引,可以是单索引或复合索引的前缀索引(后面会讲到)
它的值一但定下,就不能改变,或者修改
当然,分片键还不止这些限制,详情可以查看下一篇文章
那分片键有什么作用呢? 它是数据分区,或者数据切割的前提, 从而实现数据分发到不同服务器上,减轻服务器的负担。
如上图,x就是我们的分片键,它的范围是 minKey~maxKey, MongoDB根据它的范围把整个数据集分成了四个数据块。
注:MongoDB分片的级别是精确到文档的,, 所以不一定所有的集合都需要分片,允许分片集合和非分片集合共存。
如上图, 我们知道,数据块就是文档的集合。
那为什么会出现数据块这个东东呢? 首先,MongoDB分片的级别是精确到文档的, 也就是说,一个集合如果有100个文档,就可以切割成100份,再把这100份分发到不同机器上,但这样做是没意义的,还不如直接存储在单机上。所以就有了数据块这个东东,通过一定的策略,把100个文档切割成4个数据块,也就是4分,这样检索和分发的时候不就更为简便?
注: MongoDB数据的迁移是以数据块的数量为单位的,不是以文档的大小或数量。
数据均衡器扮演的是数据块迁移的角色。
因为一开始由于切割策略的不同,必然会导致每台机器上的数据块的数量不同(当然大牛不会出现), 这时,均衡器就会不断检测每台机器上数据块的数量,并把数据块多移到数据块少的,从而实现数据的均匀分布(均匀分布才不会造成单台机器负担过重)
哈希分片
范围分片
详情查看下一篇文章
可以把读请求,写请求都分发到不同机器上,不像副本集写请求是在单台机器上的,所以吞吐量会比较高
副本集是把一份数据复制三份放到三台机器上,分片是把一份数据切割成三份放到三台机器上,所以存储的数据量更大。
副本集相对于分片可用性更高,但是分片也具有一定的可用性,这是因为即使一个或多个分片不可用,剩余可用的分片也可以继续执行部分读/写操作。
注:在生产环境中,应将各个分片部署为副本集,从而提供更高的冗余和可用性。
分片键要认真选择,这关系到整个集群的性能和效率(分片键要修改的话,需要推倒重来)
分片集群基础架构要求和复杂性需要仔细规划,执行和维护。
等等..
MongoDB通过分片键的范围来对数据进行分区,每一个区域的数据被视作一个数据块,分片架构如下:
详情参见在后台运行以跨分片迁移块。
补充: