分片简介
什么是分片
高数据量和高吞吐量的数据库应用会对单机的性能造成较大压力,大的查询会将单机的 CPU 耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存压力转移到磁盘 IO 上。
为了解决这些问题,有两个基本的方法:
垂直扩展:增加更多的 CPU 和存储资源来扩展容量
水平扩展:将数据集分布在多个服务器上
MongoDB 的分片就是水平扩展的体现,使用分片减少了每个分片需要处理的请求数。通过水平扩展,集群可以提高自己的存储容量和吞吐量。
何时分片
通常来说,不宜过早对数据进行分片,这会增加部署的复杂性;也不应该过晚进行分片,因为很难在不停止运行的情况下对超载的系统进行分片。
通常情况下,分片用于以下情况:
增加可用 RAM
增加可用磁盘空间
减少服务器的负载
处理单个 mongod 无法承受的吞吐量
哈希分片
分片过程中可以使用哈希索引作为分片键,其最大的好处是能保证数据在各个节点分布基本均匀。
对于基于哈希的分片,MongoDB 计算一个字段的哈希值,并用这个哈希值来创建数据块。在使用基于哈希分片的系统中,拥有相近分片键的文档很可能不会存储在同一个数据块中,数据的分离性更好一些。基于哈希分片可以很好地在集群中分配负载,但是,如果随机访问超出了 RAM 大小的数据时,效率会比较低。
范围分片
对于基于范围的分片,MongoDB 按照分片键的范围把数据分成不同部分。
在使用分片键做范围划分的系统中,拥有相近分片键的文档很可能存储在同一个数据块中,因此也会存储在同一个分片中。
如果这个分片键是一个自增的值时,将会使 MongoDB 难以保持块的均衡,因为 MongoDB 需要不断将最后一个分片的数据块移动到其他分片上。
哈希和范围的结合
哈希分片更适合随机访问,不适合范围查询;范围分片则是适合范围查询,不适合平衡负载。
一个自定义的方案是,对自增字段构建哈希索引(尽可能是仍然保持有序的哈希算法)即可解决。
部署分片集群
每一个分片都应该安装MongoDB实例,和前面的主从复制类似,也需要将bin文件复制到每个分片中,并且创建db文件以及log文件存放数据库数据和日志数据
启动分片服务1
然后进入要分片的数据库bin目录中,启动cmd
mongod --shardsvr --replSet shard1 -port 4006 -dbpath D:\shard1\shard11\data -logpath D:\shard1\shard11\log\shard11.log
--shardsvr为分片声明 不要关闭此窗口,最小化即可 再次进入要分片的数据库bin目录中,启动cmd
mongod --shardsvr --replSet shard1 -port 4007 -dbpath D:\shard1\shard12\data -logpath D:\shard1\shard12\log\shard12.log
启动分片服务2
进入要分片的数据库bin目录中,再再次启动cmd
mongod --shardsvr --replSet shard2 -port 4008 -dbpath D:\shard2\shard21\data -logpath D:\shard2\shard21\log\shard21.log
进入分片一 初始化分片集
mongo -port 4006
use admin
config={_id:"shard1",members:[ {_id:0,host:"localhost:4006",priority:2},{_id:1,host:"localhost:4007",priority:1}]}
进入分片二 初始化分片集
mongo -port 4008
use admin
config={_id:"shard2",members:[ {_id:0,host:"localhost:4008",priority:2},{_id:1,host:"localhost:4009",priority:1}]}
配置启动Config Server
值得注意的是:在MongoDB3版本后config服务必须配置为从副本集,所以直接用前面设置好了的副本启动即可
老样子,每个文件夹添加data和log
启动Config1:
进入要分片的数据库bin目录中
--configsvr 这里我们完全可以像启动普通mongodb服务一样启动,不需要添加一shardsvr和configsvr参数。因为这两个参数的作用就是改变启动端口的,所以我们自行指定了端口就可以。
三个实例共三个cmd窗口[一次性启动服务,不要关闭cmd窗口,最小化即可]
mongod --configsvr --replset confset --dbpath "D:\mongodb\config1\db"--port4002 --logpath "D:\mongodb\config1\1og\config1.1og"
启动Config2:
mongod --configsvr --replSet confset -port 4003 -dbpath D:\config\config2\data -logpath D:\config\config2\log\conf2.log
进入任何一个配置服务器的节点初始化配置服务器的群集
重新打开一个cmd,再bin目录下
mongo -port 4002
配置设置
use adnim
config={_id:"confset",configsvr:true,members:[
{_id:0,host:"localhost:4002"},
{_id:1,host:"localhost:4003"}
]}
配置路由服务器Route Process
可以创建专门的文件夹存放日志
在进入要分片的数据库bin目录中启动cmd
mongos: mongos就是一个路由服务器,它会根据管理员设置的“片键”将数据分摊到自己管理的 mongod集群,数据和片的对应关系以及相应的配置信息保存在"config服务器"上。
mongod --configsvr --replSet confset -port 4003 -dbpath D:\config\config2\data -logpath D:\config\config2\log\conf2.log
配置分片sharding,添加分片索引
bin目录下使用MongoDB Shell登录到mongos,添加Shard节点
mongo 127.0.0.1:4000
sh.addshard("shard1/1ocalhost:4006,localhost:4007")
sh.addshard("shard2/1ocalhost:4008,localhost:4009")
查看分片集
db,getsiblingDB("config").shards,find()
mongodb分片测试
登入4000端口
指定要分片的数据库
sh.enablesharding("test")
指定数据库里需要分片的集合和片键,片键根据实际情况选择
sh.shardcollection("test.c2",{"id":1})//1表示范围分片,“hashed”表示哈希分片
如果集合已经包含数据,则必须在分片集合之前创建一个支持分片键的索引,如果集合为空,则 mongodb将创建索引。
向test库里的c2集合插入10000条数据
这里可能是数据量太少了,出来的结果并不是我想像的那样,根据官方说明,单调变化的键上进行分片,考虑使用哈希分片。
robo 3T查看分片集
robo 3T链接4000端口进行查看
也可以连接两个shard端口查看分片情况
最后
重新打开mongodb服务,即可像原来一样使用,但是数据存储方式和原来已经不一样了,变成了分布式的分片存储
tips:
电脑版本比较高,所以的cmd需要使用管理员身份运行
启动服务均为一次性服务,关闭cmd即为关闭服务,所以在未完成前,请勿关闭实例均未添加至系统环境变量,请在bin目录下启动
虽然窗口很多,操作不太友好,但是在win系统下,还是多有耐心一点,linux会简单一些,详情看书上。
总结:
MongoDB分片集群的部署通常涉及以下几个步骤:
-
配置分片(shard)服务器
-
配置配置服务器(config servers)
-
设置mongos路由实例
-
启动集群
-
分片数据
需要注意的问题:
MongoDB分片集群的部署可能存在以下问题
-
配置复杂:分片集群需要配置多个组件,如mongos、config server、shard(分片)、以及各种相关的配置和监控工具。
-
单点故障:任何一个组件都可能成为单点故障,比如配置服务器。
-
维护复杂:集群运维更加复杂,需要有更多的专业知识和经验。
-
数据分布不均:在数据写入时,如果不正确地设置分片键,可能导致数据分布不均。
-
读写压力:大量的读写请求可能会超出单个服务器的处理能力。
-
存储限制:单个分片的存储容量可能受到物理存储的限制。
-
性能瓶颈:查询可能会受到网络延迟的影响,导致性能下降。
-
数据一致性问题:在分片集群中,数据复制和一致性保持是一个挑战。
-
维护工具:缺乏成熟的自动化运维工具和方便的数据迁移工具。
-
版本兼容性:不同版本间的分片集群升级可能存在兼容性问题。
解决这些问题通常需要专业的知识和经验,以及对MongoDB集群管理的深入理解。在实际部署时,应该考虑到备份和恢复策略、监控系统、容错和负载均衡等多个方面。
提示:
MongoDB分片集群的部署对于不同版本的计算机没有特别的要求,但是需要确保满足MongoDB的最小硬件要求。MongoDB的分片集群通常包括以下几个组件:
-
分片(Shard):数据分布在不同的分片中,通常是mongod实例。
-
配置服务器(Config Server):存储集群的元数据和配置信息,通常使用3个mongod实例。
-
路由进程(Mongos):客户端连接的入口,负责分发请求到正确的分片。