赞
踩
在mongodb学习阶段,一般用的都是单台服务器,一个mongod服务进程。如果仅仅作为学习开发是可以的,但是如果用到生产环境,风险会很高,例如服务器崩溃、硬件出现问题,最坏的情况是磁盘或网络出问题可能会导致数损坏或数据不可访问。
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
在一个MongoDB副本集集群中,各个服务器有以下几种状态:
副本集是一组维护相同数据集的mongod实例。
副本集是一组服务器,其中有一个是主服务器(primary),用于处理客户端请求;还有多个备份服务器(secondary),用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器会自动将其中一个成员升级为新的主服务器。
MongoDB复制结构图如下所示:
当一个备份节点无法与主节点连通,会联系其他副本成员将自己选为主节点。其他成员会判断自身与主是否连通,被选举的备份节点数据是否最新,有没有其他更高优先级成员可以被选举。
最终被选举的节点的得票数,需满足所有节点一半以上的成员。
在某些情况下(例如您有一个primary服务器和一个second服务器,但由于成本限制,禁止添加另一个second服务器),您可以选择将mongod实例作为仲裁者添加到副本集。
仲裁者唯一的最用就是参与选举,仲裁者并不保存数据,也不会为客户端提供服务,它只是为了帮助具有两个成员的副本集能够满足"大多数"这个条件。
仲裁者的存在使得复制集可以以偶数个节点存在,而无需为复制集再新增节点 不要将投票节点运行在复制集的主节点或从节点机器上。 仲裁者与其他 复制集节点的交流仅有:选举过程中的投票,心跳检测和配置数据。这些交互都是不加密的。
典型的副本集是一主两从,允许有一台挂掉。实际应用中,应用在资源有限的情况下(mongodb需要运行在高性能服务器上),不得不采用一主一从的架构,那么额外配置一台普通服务器充当仲裁者,其目的仅仅是参与选举投票,作为一台凑数服务器使用。
需要注意的是:仲裁者只有副本集是偶数个时才能用。如果可能在副本集中使用奇数个数据成员,而不要使用仲裁者。
分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。通过一个名为mongos
的路由进程进行操作,mongos
知道数据和片的对应关系(通过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差,查询则尽量避免跨分片查询。使用分片的时机:
1,机器的磁盘不够用了。使用分片解决磁盘空间的问题。
2,单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
3,想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。
MongoDB中数据的分片是以集合为基本单位的,集合中的数据通过片键(Shard key)被分成多部分。其实片键就是在集合中选一个键,用该键的值作为数据拆分的依据。
所以一个好的片键对分片至关重要。片键必须是一个索引,通过sh.shardCollection
加会自动创建索引(前提是此集合不存在的情况下)。一个自增的片键对写入和数据均匀分布就不是很好,因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按照片键查询会非常高效。
随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询,mongos会对结果进行归并排序。
对集合进行分片时,你需要选择一个片键,片键是每条记录都必须包含的,且建立了索引的单个字段或复合字段,MongoDB按照片键将数据划分到不同的数据块中,并将数据块均衡地分布到所有分片中。
为了按照片键划分数据块,MongoDB使用基于范围的分片方式或者基于哈希的分片方式。
注意:
分片键是不可变。
分片键必须有索引。
分片键大小限制512bytes。
分片键用于路由查询。
MongoDB不接受已进行collection级分片的collection上插入无分片键的文档(也不支持空值插入)。
在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。chunk的产生,会有以下两个用途:
Splitting:当一个chunk的大小超过配置中的chunk size时,MongoDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况
Balancing:在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shard server的负载,系统初始1个chunk,chunk size默认值64M,生产库上选择适合业务的chunk size是最好的。MongoDB会自动拆分和迁移chunks。
分片集群的数据分布(shard节点):
(1)使用chunk来存储数据
(2)进群搭建完成之后,默认开启一个chunk,大小是64M,
(3)存储需求超过64M,chunk会进行分裂,如果单位时间存储需求很大,设置更大的chunk
(4)chunk会被自动均衡迁移。
chunk分裂及迁移:
随着数据的增长,其中的数据大小超过了配置的chunk size,默认是64M,则这个chunk就会分裂成两个。数据的增长会让chunk分裂得越来越多。
这时候,各个shard 上的chunk数量就会不平衡。这时候,mongos中的一个组件balancer 就会执行自动平衡。把chunk从chunk数量最多的shard节点挪动到数量最少的节点。
Sharded Cluster支持将单个集合的数据分散存储在多shard上,用户可以指定根据集合内文档的某个字段即shard key来进行范围分片(range sharding)。
对于基于范围的分片,MongoDB按照片键的范围把数据分成不同部分。
假设有一个数字的片键:想象一个从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点。MongoDB把这条直线划分为更短的不重叠的片段,并称之为数据块,每个数据块包含了片键在一定范围内的数据。在使用片键做范围划分的系统中,拥有”相近”片键的文档很可能存储在同一个数据块中,因此也会存储在同一个分片中。
因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写热点。同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。而不能像一个比较均衡分发的系统那样,只需要纠正小的不均衡就好了。
我们可以用一些无规律的字段,比如UUID,作为升序片键,使其规避掉不均衡分发的为问题。
分片过程中利用哈希索引作为分片的单个键,且哈希分片的片键只能使用一个字段,而基于哈希片键最大的好处就是保证数据在各个节点分布基本均匀。
对于基于哈希的分片,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块。在使用基于哈希分片的系统中,拥有”相近”片键的文档很可能不会存储在同一个数据块中,因此数据的分离性更好一些。
Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。
基于范围划分对于范围查询比较高效。假设在shard key上进行范围查询,查询路由很容易能够知道哪些块与这个范围重叠,然后把相关查询按照这个路线发送到仅仅包含这些chunks的分片。但是基于范围划分很容易导致数据不均匀分布,这样会削弱分片集群的功能。例如当shard key是个成直线上升的字段,如时间。那么,所有在给定时间范围内的请求都会映射到相同的chunk,也就是相同的分片上。这种情况下,小部分的分片将会承受大多数的请求,那么系统整体扩展并不理想。
相反的,基于散列划分是以牺牲高效范围查询为代价,它能够均匀的分布数据,散列值能够保证数据随机分布到各个分片上。
分片注意:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。