共计 1780 个字符,预计需要花费 5 分钟才能阅读完成。
Mongodb是一个基于分布式的文件存储的内存型的非关系型数据库(NoSQL),由C++编写。
架构模式
- 单库:一般测试用,没有高可用,容易部署
- 主从复制:这种架构至少需要两台服务器构成一主一备,也可以支持一主多备。当然,也可以通过同一台服务器的多个实例配置成一主一备或一主多备,只不过灵活性,备份,高可用,扩展性都不好。
- 副本集(Replica set):也叫复制集。副本集就是一个可以自动故障切换的主备库集群。和主从架构的最大区别就是没有一个固定的主库(primary),而是由集群选举一个主库,当前的主库挂掉,集群会自动从备库(secondary)中选举一个转变为主库。primary负责读写请求,secondary负责读请求。是一个HA架构,解决了单点故障的问题。
- 分片集群(Sharding cluster):mongo进行数据水平扩展的常用手段。复制集架构的最大的缺点就是集群容量受限于单个节点的磁盘大小,如果数据量不断增加,对它进行扩容非常困难,所以使用Sharding模式来解决这个问题。原理:将整个集合(colletion)的数据根据sharding key,被sharding到多个mongo节点上,即每个节点持有colletion的一部分数据,这个集群持有全部数据,所以原则上sharding可以支持数TB的数据。
分片集群(Sharding cluster)
分片几个基本概念
- 分片(shard):每个分片包含了分片数据的一个子集,每个分片可以作为一个副本集部署。
- mongos路由:路由器的角色,提供者客户端应用和分片集群的接口。
- 配置服务器(config servers):配置服务器存储着集群的元数据和配置设置,MongoDB3.4之后,配置服务就必须部署为副本集
分片主键
为了能在集合中分配文档,MongoDB使用分片主键分割集合。分片主键由不重复的字段或字段集合组成。
对于一个集合分片时,要选择一个主键,分片主键在分片后就不能修改。一个分片只能有一个分片主键
对于非空集合进行分片,集合必须有一个以分片主键开头的索引。对于空集合,如果集合对于分片主键没有一个合适的索引,MongoDB将创建索引。
区块
MongoDB分割分片数据到区块,每一个区块包含基于分片主键的左闭右开的区间范围。
分片的优点
MongoDB通过集群中的分片分配读写的工作负载,允许每一个分片处理集群中的一部分操作,读写可以通过添加分片进行横向扩展。包含分片主键或组合前缀的查询,mongos可以定位这个查询到特定的分片或分片子集上,这个定位操作比广播到所有分片的效率高得多。
随着数据的增长,增加额外的分片可以增加集群的存储能力。
即使集群中的一个或多个分片不可用,集群也可以继续执行一部分可用的读写操作。在宕机期间,可用分片的读写操作还是可以被成功处理的。每一个分片部署成副本集,可以提供可增长的冗余和高可用。
分片的缺点
分片集群的基础需求需要小心的计划,执行和维护。谨慎的考虑分欧安主键是确保集群性能所必须的。分片之后,分片主键就不能更改,也不能使集合不分片。如果查询不包含分片主键或组合主键的前缀,mongos将进行广播,查询所有分片,这些查询将花费很长时间。
分片与不分片
一个数据库可以由分片集合和不分片集合的混合。分片集合通过集群中的分片进行分割和分配,不分片集合存储在基础分片中。每个数据库都有一个自己的基础分片。
连接分片集群
客户端必须通过mongos路由和分片中或不分片的集合进行交互。客户端是不能连接一个单独的分片进行操作的。
持久化原理
MongoDB具有高度可配置的持久化设置,从完全没有任何保证到完成持久化。
mongodb和mysql不同,mysql的每一次更新操作都会直接写入磁盘,但是mongo不会,作为内存型数据库,数据操作会先写入内存,然后再持久化到磁盘。
mongodb在启动时,专门初始化一个线程不断循环,用于一定时间周期内来从defer队列中获取要持久化的数据并写入磁盘的 joural (日志)和 mongofile(数据)中,当进行CUD操作时,记录都是被放入defer队列中,以提供延时批量(groupcommit)提交写入。所以时间周期参数是个需要认真考虑的参数,系统是90毫秒,太低会导致频繁的磁盘操作,太高有可能导致业务系统宕机时数据丢失。