第41章:MongoDB-集群--Sharding(分片)
分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。
分片是每个分片都拥有整个数据集的一个子集,且相互是不同的数据,多个分片的数据合起来构成整个数据集。
分片的基本思想:
将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分。
mongoDB 的分片,是将collection 的数据进行分割,然后将不同的部分分别存储到不同的机器上,当 collection 所占空间过大时,我们需要增加一台新的机器,分片会自动将 collection 的数据分发到新的机器上。然后通过一个名为 mongos 的路由进程进行操作,mongos 知道数据和片的对应关系(通过配置服务器)。
使用场景:
1)机器的磁盘不够用了,使用分片解决磁盘空间的问题。
2)单个mongod已经不能满足写数据的性能要求,通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
3)想把大量数据放到内存里提高性能,通过分片使用分片服务器自身的资源。
要构建一个MongoDB Sharding Cluster(分片集群),需要三种角色:
1)分片服务器(Shard Server)
mongod 实例,用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组个一个 relica set 承担,防止主机单点故障这是一个独立普通的mongod进程,保存数据信息。可以是一个副本集也可以是单独的一台服务器。
2)配置服务器(Config Server)
mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息。这是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最先开始建立,启用日志功能。像启动普通的 mongod 一样启动 配置服务器,指定configsvr 选项。不需要太多的空间和资源,配置服务器的 1KB 空间相当于真是数据的 200MB。保存的只是数据的分布表。
3)路由服务器(Route Server)
mongos实例,前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息,开启 mongos 进程需要知道配置服务器的地址,指定configdb选项。
片键的意义
片键必须是一个索引 ,通过sh.shardCollection 加会自动创建索引。一个自增的片键对写入和数据均匀分布就不是很好, 因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按照片键查询会非常高效。随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询,mongos 会对结果进行归并排序
为何需要水平分片
1)减少单机请求数,将单机负载,提高总负载
2)减少单机的存储空间,提高总存空间
分片组件组成:mongos、config server、shard、replica set。
1)mongos,
数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。
2)配置服务器(Config servers)
存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。
mongos 第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样mongos 就能继续准确路由。
在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,防止数据丢失!
MongoDB是在collection级别实现的水平分片。
3)数据分片(Shards)
分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。
基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。
分片(Shards)可以是一个单独的mongod实例,也可以是一个副本集。在高可用性的分片架构还需要对于每一个分片构建replica set副本集保证分片的可靠性。生产环境通常是2个副本+1个仲裁。
4)查询路由(Query Routers)
数据库集群请求的入口,所有的请求都通过 mongos 进行协调,不需要在应用程序添加一个路由选择器,mongos 自己就是一个请求分发中心,它负责把对应的数据请求转发到对应的 shard 服务器上。mongos不要配置为rs,因为它不存储数据。
在生产环境通常有多个 mongos 作为请求的入口,防止其中一个挂掉所有的 mongodb 请求都没有办法操作。
5)replica set(副本集)
其实就是shard的备份,防止shard挂掉之后数据丢失。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
6)仲裁者(Arbiter)
是复制集中的一个MongoDB实例,它并不保存数据。仲裁节点使用最小的资源并且不要求硬件设备,不能将Arbiter部署在同一个数据集节点中,可以部署在其他应用服务器或者监视服务器中,也可部署在单独的虚拟机中。为了确保复制集中有奇数的投票成员(包括primary),需要添加仲裁节点做为投票,否则primary不能运行时不会自动切换primary。
总结:应用请求mongos来操作mongodb的增删改查,配置服务器存储数据库元信息,并且和mongos做同步,数据最终存入在shard(分片)上,为了防止数据丢失同步在副本集中存储了一份,仲裁在数据存储到分片的时候决定存储到哪个节点。
人脸:
代表客户端。
mongos:
mongos就是一个路由服务器,它会根据管理员设置的"片键"将数据分摊到自己管理的mongod集群,数据和片的对应关系以及相应的配置信息保存在"config服务器"上。
客户端只需要对mongos进行操作就行了,至于如何进行分片,不需要客户端参与,由mongos和config来完成。
mongod:
一个普通的数据库实例或者副本集
分片集群由以下3个服务组成:
Shards Server: 每个shard由一个或多个mongod进程组成,用于存储数据
Config Server: 用于存储集群的Metadata信息,包括每个Shard的信息和chunks信息
Route Server: 用于提供路由服务,由Client连接,使整个Cluster看起来像单个DB服务器
见分支
MongoDB将文档分组成为块,每个块由给定片键特定范围内的文档组成,一个块只存在于一个分片上,所以MongoDB用一个较小的表就能维护块和分片的映射关系。
块与块间的数据不能重复,因此不能使用数组来作为片键,因为MongoDB会为数组创建多个索引条目,从而导致同一数据在多个块中出现。
注意:块是个逻辑概念,而非物理存储实现
查看块信息
块信息保存在config.chunks集合中,sh.status()里面也带有分块的信息。
如果单个分片键可能重复的话,可以创建复合分片键,方式跟创建复合索引一样。
拆分块
mongos会记录每个块中插入了多少数据,如果一个块的数据大小超出了块的大小,或者达到某个阀值(拆分点), MongoDB会自动的拆分这个块。
拆分的时候,配置服务器会创建新的块文档,同时修改旧的块范围。进行拆分的时候,所有的配置服务器都必须可以到达,否则不会进行拆分,此时就会造成"拆分风暴",也就是mongos不断发起拆分请求,却无法拆分的情况。唯一的解决办法就是保证配置服务器的健康和稳定。
均衡器会周期性的检查分片间是否存在不均衡,如果存在,则开始块的迁移。不均衡的表现是:一个分片明显比其他分片拥有更多的块。
1:均衡器可以是任意一个mongos
2:每隔几秒钟,mongos就会尝试成为均衡器,如果没有其他可用的均衡器,mongos就会对整个集群加锁,以防止配置服务器对集群进行修改,然后做一次均衡操作
3:均衡不会影响mongos的正常路由操作,因此对客户端没有任何影响
4:可以查看config.locks集合,看看哪一个mongos是均衡器,语句如下;
db.locks.findOne({"_id":"balancer"});
(1)_id为balancer的文档就是均衡器
(2)字段who表示当前或者曾经作为均衡器的mongos
(3)字段state表示均衡器是否在运行,0非活动,2正在均衡,1正在尝试得到锁,一般不会看到状态1
默认情况下,MongoDB会在分片间均匀的分配数据,但是,如果服务器配置严重失衡,比如某些机器配置非常高,而其他机器只是普通机器,那么就应该使用maxSize选项,来指定分片能增长到的最大存储容量,单位是MB。
例如:db.runCommand({"addShard":"myrepl/ip:port","maxSize":1000});
注意maxSize更像是一个建议而非规定,MongoDB不会从maxSize处截断一个分片,也不会阻止分片增加数据,而是会停止将数据移动到该分片,当然也可能会移走一部分数据。因此可以理解这个maxSize是一个建议或者提示。
1:如果在从机上查询数据,就必须要可接受过时数据
2:使用集群时,不能把整个集合看成一个"即时快照"了,这个问题很严重,比如:
(1)在一个分片集合上,对数据进行计数,很有可能得到的是比实际文档多的数据,因为有可能数据正在移动复制
(2)唯一索引也无法强制保证了
(3)更新操作也面临问题,无法确保在多个分片间只发生一次,因此要更新单个文档,一定要在条件中使用片键,否则会出现问题
当需要进行迁移的时候,将持有过多数据的分片上的块分割,使得分割出来的区间刚好满足迁移需要,然后再进行迁移。
比如:如果shard 1中存有[a, f]区间的数据,数据量为500G,此时需要从shard 1上面迁移100G到shard 4,以保证数据的均匀分布。经统计,shard 1中的[a, d]段的数据为400G,[d, f]段数据为100G,因此将shard 1中的[d, f]段的数据直接迁移到shard 4上面。
同理,需要从shard 2中迁移100G的数据到shard 3中。这种迁移方式的数据迁移量是理论上的最小值。
第41章:MongoDB-集群--Sharding(分片)的更多相关文章
- MongoDB集群搭建-分片
MongoDB集群搭建-分片 一.场景: 1,机器的磁盘不够用了.使用分片解决磁盘空间的问题. 2,单个mongod已经不能满足写数据的性能要求.通过分片让写压力分散到各个分片上面,使用分片服务器自身 ...
- Mongodb集群与分片 1
分片集群 Mongodb中数据分片叫做chunk,它是一个Collection中的一个连续的数据记录,但是它有一个大小限制,不可以超过200M,如果超出产生新的分片. 下面是一个简单的分片集群 ...
- MongoDB集群之分片
原文:点击打开链接 MongoDB分片 分片(sharding)是将数据拆分,将其分散在不同的机器上的过程.MongoDB支持自动分片 片键(shard key)设置分片时,需要从集合里面选一个键,用 ...
- mongodb集群配置分片集群
测试环境 操作系统:CentOS 7.2 最小化安装 主服务器IP地址:192.168.197.21 mongo01 从服务器IP地址:192.168.197.22 mongo02 从服务器IP地址: ...
- Mongodb集群与分片 2
前面我们介绍了简单的集群配置实例.在简单实例中,虽然MongoDB auto-Sharding解决了海量存储问题,和动态扩容问题,但是离我们在真实环境下面所需要的高可靠性和高可用性还有一定的距离. 下 ...
- mongodb 集群部署--分片服务器搭建
部署分片服务器 1.分片 为了突破单点数据库服务器的I/O能力限制,对数据库存储进行水平扩展,严格地说,每一个服务器或者实例或者复制集就是一个分片. 2.优势 提供类似现行增·长架构 提高数据可用性 ...
- MongoDB集群之分片技术应用 —— 学习笔记
课程链接:https://www.imooc.com/learn/501 一.什么是分片? 分片:将数据进行2拆分,将数据水平的分散到不同的服务器上. 二.为什么要分片? 架构上:读写均衡.去中心化 ...
- 第43章:MongoDB-集群--Sharding(分片)--多机的搭建
①环境准备 服务器规划 服务器[192.168.0.75] 服务器[192.168.0.84] 服务器[192.168.0.86] mongos mongos mongos config server ...
- 第42章:MongoDB-集群--Sharding(分片)--单机的搭建
①配置服务器 在大型的集群中,建议配置3台配置服务器,就足够用了.启动配置服务器的方式: 1:先创建几个存放数据的文件夹,比如在前面的dbs下面创建confdb文件夹,然后在confdb下面创建con ...
随机推荐
- c# 对象的深拷备
C# 引用类型对象在拷备时,一般有浅拷备与深拷备,浅拷备指向的是同一对象的引用地址,一个对象的修改必然会影响另一个对象,而深拷备是直接拷备对象的内容,而不是引用,拷备后的对象拥有新的引用,这里主要介绍 ...
- c++ :
(1)表示机构内位域的定义(即该变量占几个bit空间) typedef struct _XXX{ unsigned char a:4; unsigned char c; } ; XXX
- redis 10个问题
(1)什么是redis? Redis 是一个基于内存的高性能key-value数据库. (有空再补充,有理解错误或不足欢迎指正) (2)Reids的特点 Redis本质上是一个Key-Value类型的 ...
- gentoo Cataclysm - Dark Days Ahead
gentoo 中安装 Cataclysm - Dark Days Ahead,使用web 下载稳定版的安装包,使用 tar 进行解压. 安装需要共享库:sdl2-mixer, 未完待续
- html: 仿制soundmanager2右上角面板
仿制 http://schillmania.com/projects/soundmanager2/#volume 右上角面板 <style type="text/css"&g ...
- 学习C++,应该循序渐进的看哪些书?
在某博客上看到的一个C++书籍阅读清单,可以参考下: 阶段 1<Essential C++>这是一本内容不多但很实用的C++入门书籍,强调快速上手与理解C++编程.本书主要围绕一系列逐渐复 ...
- [leetcode]2. Add Two Numbers.cpp
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- leetcode448
public class Solution { public IList<int> FindDisappearedNumbers(int[] nums) { Dictionary<i ...
- UI5-学习篇-17-云端WEB IDE开发
1.前提条件 SAP云平台账号已申请 云连接器设置完成:UI5-学习篇-15-云连接SAP Cloud Connector 云平台Destination设置完成:UI5-学习篇-16-云端SCP-De ...
- TaskScheduler
一初始化 在SparkContext初始化的时候,同时初始化三个对象.DAGScheduler,TaskScheduler,SchedulerBackend.DAGScheduler,前面已经讲到,做 ...