本文是我们学院课程中名为MongoDB –可扩展NoSQL DB的一部分 。
在本课程中,您将被介绍到MongoDB。 您将学习如何安装它以及如何通过它的外壳进行操作。 此外,您还将学习如何通过Java以编程方式访问它以及如何将Map Reduce与其一起使用。 最后,将解释更高级的概念,例如分片和复制。 在这里查看 !
目录
1.简介
分片是一种用于在多个服务器实例之间拆分大量数据的技术。 如今,数据量呈指数增长,单个物理服务器通常无法存储和管理如此庞大的数据量。 分片通过将整个数据集划分为较小的部分并将其分布在大量服务器(或分片 )中,有助于解决此类问题。 所有分片共同构成一个完整的数据集,或者就MongoDB而言 ,一个逻辑数据库。
2.配置
MongoDB支持使用分片群集配置来实现即用型分片: 配置 服务器 (三个用于生产部署),一个或多个分片 (用于生产部署的副本集)以及一个或多个查询路由过程。
- 分片存储数据:出于高可用性和数据一致性的原因,每个分片都应是一个副本集 (我们将在第5部分中讨论有关复制的更多内容。 )
- 查询路由器 (mongos过程)前进客户端应用程序和直接操作,以适当的碎片或碎片 ( 分片群集可包含多个查询路由器来平衡负载)
- 配置服务器存储集群的元数据:将集群的数据集映射到分片 ( 查询路由器使用此元数据将操作定向到特定分片 ),为实现高可用性,生产分片集群应具有3个配置服务器,但出于测试目的,可以部署一个配置服务器
每个集合的MongoDB分片(分区)数据。 在分片群集 分片集合应该仅通过查询路由器 (mongos进程)来访问。 与分片的直接连接仅允许访问集群数据的一小部分。 此外,每个数据库都有保存所有在该数据库中的unsharded收藏所谓的主 碎片 。
配置服务器是特殊的mongod流程实例,用于存储单个分片群集的元数据。 每个群集必须具有自己的配置服务器 。 配置服务器使用两阶段提交协议来确保一致性和可靠性。 所有配置服务器必须可用于部署分片群集或对群集元数据进行任何更改。 没有集群元数据,集群将无法运行。
3.分片(分区)方案
MongoDB通过使用分片键对集合的数据进行分区,从而在集合级别在各个分片之间分布数据(有关更多详细信息,请参阅官方文档 )。
分片键是存在于集合中每个文档中的带索引的简单字段或复合字段。 使用基于范围的分区或基于 哈希的分区 , MongoDB将分片键值拆分为多个块,然后将这些块均匀地分布在各个分片上 。 为此, MongoDB使用两个后台进程:
- splitting :后台进程,防止块增长太大。 当特定的块超过指定的块大小(默认为64 Mb )时, MongoDB会将块拆分为一半。 插入和分片收集可能触发分裂的更新。
- 平衡器 :管理块迁移的后台进程。 平衡器在群集中的每个查询路由器上运行。 当分片集合在一个集群中的分布是不均匀的,平衡器从具有块到最低编号块的碎片的数量最多,直到达到平衡的碎片移动块。
基于范围的分片(分区)
在基于范围的分片(分区)中, MongoDB将数据集划分为由分片键值确定的范围。 例如,如果分片键是数字字段,则MongoDB会将整个字段的值范围划分为较小的非重叠间隔(大块)。
尽管基于范围的分片(分区)支持更有效的范围查询,但它可能导致数据分布不均。
基于哈希的分片(分区)
在基于散列的分片(分区)中, MongoDB计算分片键的散列值,然后使用这些散列在分片之间拆分数据。 基于哈希的分区确保数据的均匀分布,但导致范围查询效率低下。
4.添加/删除碎片
MongoDB允许向正在运行的共享集群中添加和删除碎片 。 添加新的分片时,由于新的分片没有任何块,因此会破坏平衡。 当MongoDB立即开始将数据迁移到新的分片时,集群可能需要一段时间才能恢复平衡。
因此,当从集群中删除分片时,平衡器会将所有大块从那些分片迁移到其他分片。 迁移完成后,可以安全地删除碎片。
5.配置分片集群
现在,我们了解了MongoDB分片的基础知识,我们将使用简化的(类似于测试的)配置从头开始部署小型分片集群 ,而无需复制集和单个配置服务器实例。
分片群集的部署开始于使用--configsvr
命令行参数在配置服务器模式下运行mongod服务器进程。 每个配置服务器都需要其自己的数据目录来存储完整的集群元数据,并且应使用--dbpath
命令行参数(在第1部分中已经介绍过)提供该参数--dbpath
安装–如何安装MongoDB 。 话虽如此,让我们执行以下步骤:
- 创建一个数据文件夹(我们只需要做一次):
mkdir configdb
- 运行MongoDB服务器:
bin/mongod --configsvr --dbpath configdb
默认情况下, 配置服务器在端口27019上侦听 。 在启动分片群集之前,所有配置服务器应已启动并正在运行。 在我们的部署中,单个配置服务器在名称为ubuntu的主机上运行。
下一步是运行mongos进程的实例。 这些是轻量级的,只需要知道配置服务器的位置即可。 为此,使用命令行参数--configdb
,后跟逗号分隔的配置服务器名称(在本例中,主机ubuntu上仅单个配置服务器 ):
bin/mongos --configdb ubuntu
mongos进程侦听的默认端口是27017 ,与通常的MongoDB服务器相同。
最后一步是将一些常规的MongoDB服务器实例(分片 )添加到分片 集群中 。 我们在不同的端口上分别启动两个MongoDB服务器实例,分别为27000和27001 。
- 在端口27000上运行第一个MongoDB服务器实例( shard )
mkdir data-shard1
bin/mongod --dbpath data-shard1 --port 27000
- 在端口27001上运行第二个MongoDB服务器实例( shard )
mkdir data-shard2
bin/mongod --dbpath data-shard2 --port 27001
一旦独立的MongoDB服务器实例启动并运行,就可以在MongoDB Shell的帮助下将它们添加到分片群集中 。 到目前为止,我们已经使用MongoDB shell连接到独立的MongoDB服务器。 在分片群集中 , mongos进程是所有客户端的入口点,因此,我们将连接到刚运行的客户端(在默认端口27017上运行 ): bin/mongo --port 27017 --host ubuntu
MongoDB Shell提供了一个有用的命令sh.addShard()
来添加碎片 (请参阅Shell Sharding Command Helpers以获得更多详细信息)。 让我们针对我们之前运行的两个独立的MongoDB服务器实例发出此命令:
sh.addShard( "ubuntu:27000" )
sh.addShard( "ubuntu:27001" )
让我们通过发出另一个非常有用的MongoDB shell命令sh.status()
来检查当前的分片集群配置。
至此,分片集群基础架构已配置完毕 ,我们可以继续分片数据库集合。
分片标签
MongoDB的允许关联标签与碎片的特定碎片或子集的片键的具体范围。 单个碎片可能具有多个标签,并且多个碎片也可能具有相同的标签。 但是任何给定的分片键范围只能分配一个标签。 范围的重叠是不允许的,并且标记同一范围不能超过一次。
例如,让我们通过使用sh.addShardTag()
命令为分片 集群中的每个分片分配标签。
sh.addShardTag( "shard0001", "bestsellers" )
sh.addShardTag( "shard0000", "others" )
要查找与特定标签关联的所有分片,应发出针对配置数据库的命令。 例如,要查找所有标记为“畅销书”的碎片 ,应在MongoDB Shell中键入以下命令:
use config
db.shards.find( { tags: "bestsellers" } )
配置数据库中另一个名为标签的集合包含所有标签定义,并且可以按常规方式查询所有可用标签。
分别标签可以使用的碎片被删除sh.removeShardTag()
命令。 例如:
sh.removeShardTag( "shard0000", "others" )
6.分片数据库和集合
众所周知, MongoDB在收集级别执行分片。 但是在可以对集合进行分片之前,必须为集合的数据库启用分片。 对数据库启用分片并不会重新分发数据,但可以在该数据库中分片集合。
出于演示目的,我们将重用第3部分中的书店示例。MongoDB和Java教程使书集可拆分。 让我们通过额外提供数据库名称bin/mongo --port 27017 --host ubuntu bookstore
(或仅在现有MongoDB Shell会话中发出命令use bookstore)来重新连接到mongos实例,并将几个文档插入books集合中。
db.books.insert( {
"title" : "MongoDB: The Definitive Guide",
"published" : "2013-05-23",
"categories" : [ "Databases", "NoSQL", "Programming" ],
"publisher" : { "name" : "O'Reilly" }
} )
db.books.insert( {
"title" : "MongoDB Applied Design Patterns",
"published" : "2013-03-19",
"categories" : [ "Databases", "NoSQL", "Patterns", "Programming" ],
"publisher" : { "name" : "O'Reilly" }
} )
db.books.insert( {
"title" : "MongoDB in Action",
"published" : "2011-12-16",
"categories" : [ "Databases", "NoSQL", "Programming" ],
"publisher" : { "name" : "Manning" }
} )
db.books.insert( {
"title" : "NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence",
"published" : "2012-08-18",
"categories" : [ "Databases", "NoSQL" ],
"publisher" : { "name" : "Addison Wesley" }
} )
如前所述,尚未为书店数据库或书籍收藏启用分片,因此整个数据集最终都位于主分片上(正如我们在“ 简介”部分中提到的)。 让我们通过在MongoDB Shell中发出命令sh.enableSharding()
为书店数据库启用分片。
我们已经接近使分片集群实际执行一些工作并开始分片实际集合。 每个集合都应具有一个分片密钥 (请参阅分片(分区)方案部分),以便在多个分片之间进行分区。 让我们为基于文档_id字段的图书收集定义基于散列的分片键(请参阅基于散列的分片(分区)部分)。
db.books.ensureIndex( { "_id": "hashed" } )
这样,让我们告诉MongoDB使用sh.shardCollection()
命令对books collection进行分sh.shardCollection()
更多信息请参见Sharding命令和命令助手 )。
sh.shardCollection( "bookstore.books", { "_id": "hashed" } )
这样,分片集群就可以启动并运行了! 在下一节中,我们将仔细研究专门用于管理分片部署的命令。
7.分片命令和命令助手
MongoDB Shell提供了一个命令助手和sh
上下文变量,以简化分片管理和部署。
8.接下来
在本部分中,我们介绍了MongoDB分片(分区)功能的基础。 有关更完整和全面的详细信息,请参阅官方文档 。 在下一节中,我们将研究MongoDB复制。
翻译自: https://www.javacodegeeks.com/2015/09/mongodb-sharding-guide.html