MongoDB简介
MongoDB是由C++编写的非关系数据库,是一个基于分布式文件存储的数据库系统,是一个面向集合,模式自由的文档型数据库。
MongoDB介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的非关系数据库。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。
Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB特性
1.易用性:MongoDB面向文档,不再有"行"的概念,取而代之的是更为灵活的"文档"模型。通过在文档中嵌入文档和数组的方式,在一条记录中表现复杂的层级关系。另外,MongoDB没有预定义模式,文档的键和值无须定义固定的类型和大小,这使得添加或删除字段变得更为容易,因此开发者能够进行快速迭代,加快开发进程。
2.高性能:MongoDB对文档进行了填充,对数据文件进行了预分配,用空间来保证性能的稳定。MongoDB的优化器会标记出查询效率最高的方式,以便生成高效的查询计划。MongoDB提供高性能数据持久化可以减少数据库系统的I/O活动,也可以通过索引支持更快的查询。
3.高可用性:MongoDB副本所组成的一个集群,成为副本集,它提供了自动故障转移和数据冗余功能,以防止数据丢失,从而提高数据的可用性。
4.易扩展性:MongoDB的设计采用水平扩展,可通过分片将数据分布在集群及其中。MongoDB能够自动处理跨集群的数据和负载,自动重新分配文档,并将用户的请求路由到正确的机器上。
5.索引和查询:MongoDB支持各种类型的索引,包括单字段索引、复合索引、全文索引和地理空间索引等。它提供了强大的查询语言,支持丰富的查询操作,如范围查询、排序、聚合等。
MongoDB逻辑结构
MongoDB的逻辑结构是体系结构的一种形式,是一种层级结构,主要由数据库、集合和文档组成。逻辑结构的这三个层级相互之间关联,构成了MongoDB的数据存储模型。数据库包含集合,集合包含文档,而每个文档则是实际存储数据的基本单位。具体如下:
1.数据库(Database):在MongoDB中,数据库是数据的物理和逻辑容器。每个数据库都有自己的文件系统命名空间,用于存储其包含的集合和索引。一个MongoDB服务器可以包含多个数据库,每个数据库可以独立进行管理,并有自己的权限控制。MongoDB默认提供admin、local、config和test四个数据库。admin数据库主要存储数据库账号的相关信息,local数据库存储限于本地单台服务器的任意集合,如复制集的操作日志(oplog)和各个实例的状态信息等,该数据库的数据不会被复制到从节点上。config数据库用于存储分片集群中与分片相关的元数据信息。test数据库是MongoDB默认创建的一个测试库,当连接mongoDB服务时,如果不指定连接的数据库,默认就会连接到test数据库。
2.集合(Collection):集合是一组文档的分组,类似于关系数据库中的表。不同于关系数据库,集合中的文档可以拥有不同的字段,也可以任意删减某个文档的字段,因此集合更加灵活。集合中的文档以键值对的形式存储,每个文档可以有不同的字段和数据类型。集合分为一般集合和上限集合。一般集合没有上限,可以存储任意数量的文档和数据。而上限集合限制了集合的容量大小,在数据存满时,上限集合会从头开始覆盖最开始的文档,从而进行循环写入。
3.文档(Document):文档是MongoDB中的基本数据单元,使用BSON格式表示。它类似于关系数据库中的行,但是更加灵活,可以包含不同类型和数量的字段。文档采用键值对的形式表示,其中文档的键是字符串,文档中不能由重复的键,每个文档都有一个默认的_id键,它相当于关系数据库的主键,在同一个集合当中必须是唯一的。_id键默认是ObjectId类型,在插入文档的时候,如果用户不设置文档的_id键,MongoDB会自动生成一个唯一的ObjectId值进行填充。文档的值可以是各种数据类型,包括字符串、整数、日期、数组等,还可以是内嵌文档。
MongoDB副本集
副本集是一组MongoDB实例保持其相同数据库的集群,由一个主服务器和多个副本服务器构成。通过复制将数据的更新由主服务器推送到其他副本服务器上,在一定的延迟之后,达到每个MongoDB实例维护相同的数据集副本。
MongoDB副本集的功能
1.数据的冗余:副本集可以确保副本结点与主结点数据的更新,以防止单个数据库服务宕机造成数据丢失的问题。这些副本结点可以和主结点位于同一数据中心或处于安全考虑分布于其他数据中心。
2.自动故障转移:副本集没有固定的主结点,整个集群会选举出一个主结点,当这个主结点不能正常工作时,会选举出一个副本结点切换为主结点,客户端会连接到这个新的主结点,并且数据和应用程序都将保持可用。MongoDB副本集实现这样的切换是自动的,因此副本集是保证MongoDB高可用的基础。
3.读写分离:通过配置副本集的读写分离功能,可以使应用程序可以直接从备份节点读取数据,而不必都去访问主节点。一般来说,可以将所有的写操作都发送到主节点,而将读操作发送到备份节点。这样可以减轻主节点的负载压力,并提高整个系统的并发处理能力和读取性能。但是,由于副本集的异步复制机制,即使读操作发送到了备份节点,也无法保证读取到的数据是最新的。
MongoDB副本集成员
一般来说,副本集有三个主要成员,主结点,副本结点和仲裁结点。
客户端程序通过驱动器连接副本集主结点进行读写操作,当主结点数据副本发生变化时候,副本结点通过复制同步主结点的数据副本,使副本集中的副本结点与主结点存储相同的数据副本。副本集中的各结点还会通过传递心跳信息来检测各自的健康状态。当主结点故障时,拥有投票权的副本结点和总裁结点会触发一次新的选举操作,并从副本结点中选取新的主结点,以确保副本集正常运行。以下是三个主要成员的介绍。
1.主结点:主结点是副本集中负责处理客户端请求和读写数据主要成员。主结点通过oplog(操作日志)记录所有操作。副本集中有且只有一个主结点,如果当前主结点不可用,则会从副本结点中选举出新的主结点。
2.副本结点:副本结点定期轮询主结点来获取oplog记录的操作内容,然后对自己的数据副本执行这些操作,从而保证副本结点的数据副本与主结点保持一致。副本集中可以有一个或多个副本结点。当主结点宕机时,副本集会根据副本结点的优先级进行选举,确定哪个副本结点成为新的主结点。
3.仲裁结点:仲裁结点不会同步主结点的数据副本,也不会被推荐为主结点,它主要是参与选举投票。由于仲裁结点没有访问压力,比较空闲,因此仲裁结点需要的资源很小。当副本集中成员个数为偶数时,建议添加一个仲裁结点,防止选举新的主结点过程中出现票数一致,导致无法选举出新的主结点,使副本集处于只读状态无法写入数据。
MongoDB分片
MongoDB分片是MongoDB支持的另一种集群形式,它可以满足MongoDB数据量呈爆发式增长的需求。当MongoDB存储海量的数据时,一台及其可能无法满足数据存储的需求,也可能无法提供可接受的读写吞吐量,这时,我们就可以通过在多台机器上对海量数据进行划分,即分片。这使得MongoDB数据库系统能够存储和处理更多的数据。分片和副本集主要区别在于,分片是每个结点存储数据的不同片段,而副本集是每个结点存储数据的相同副本。
MongoDB分片策略
MongoDB内置了分片策略。通过分片键将集合中的数据划分为多个块,然后根据分片策略将划分的块分发到分片集群中。分片键可以是集合文档中的一个或多个字段。
1.范围分片:MongoDB根据分片键的值范围将数据划分为不同块,每个分片都包含了分片键在一定范围内的数据。这样的话,若有文档写入,MongoDB会根据该文档的分片键,从而交由指定分片服务器去处理,这使得查询的效率提高。分片键可以是任何合适的字段,如时间戳、价格、地理位置等。但是,当数据集中在一定范围内时,就会导致MongoDB数据分布不均匀,从而导致其中一个分片服务器负载过重。
2.哈希分片:哈希分片类似范围分片,两者的区别是范围分片是MongoDB根据分片键的值直接进行范围划分,而哈希分片则先将分片键的值进行哈希计算,然会对这些哈希值进行范围划分,从而使得每个分片都包含了哈希值在一定范围内的数据。范围分片可以支持符合分片键,而哈希分片只支持单个字段作为分片键。哈希值的随机性,使得数据随机分布在分片集群中不同的分片服务器上。使用哈希分片时候,拥有相近分片键的文档不会存储在同一个分片服务器中,这样数据的分离性会更好,可以保证分片集群中数据分布均衡。但是,由于数据是通过哈希计算进行随机存放的,因此会降低查询性能。
MongoDB分片集群架构
MongoDB分片集群中主要由三个部分组成,即分片服务器(Shard)、路由服务器(Mongos)和配置服务器(Config Server)组成。
1.分片服务器:即MongoDB实例,分片服务器是实际存储数据的组件,持有完整数据集中的一部分,每个分片服务器都可以是一个MongoDB实例,也可以是一组MongoDB实例组成的集群。分片服务器之间是相互独立的,可以在不同的物理机器或虚拟机上部署,以实现分布式存储和负载均衡。
2.路由服务器:即mongos,主要提供客户端应用程序与分片集群交互的接口,所有请求都需要通过路由服务器进行协调工作。路由服务器实际上就是一个消息分发请求中心,它负责把客户端应用程序对应的数据请求转发到对应的分片服务器上。应用程序将查询、存储、更新等请求原封不动发送给路由服务器,路由服务器询问配置服务器操作分片服务器需要获取哪些元数据,然后连接相应的分片服务器进行相关操作,最后将各个分片服务器的响应进行合并,返回给客户端应用程序。一个分片集群通常会有多个路由服务器,一方面可以解决多个客户端同时请求,从而达到负载均衡的效果。另一方面可以解决路由服务器宕机时导致整个分片集群无法使用的问题。
3.配置服务器:配置服务器存储了分片集群的元数据,记录了分片集群的拓扑结构、数据分片规则和分片键范围等重要信息,并且这些数据是不允许丢失的。因此,需要配置多个配置服务器以防止数据丢失,即使其中一台配置服务器宕机,还有其他配置服务器从而保证MongoDB分片集群依然能够正常工作。当路由服务器初次启动或关闭重启时,就会从配置服务器中加载分片集群的元数据。若是配置服务器的信息发生变化,则会通知所有路由服务器更新自己的状态,这样路由服务器就能继续准确协调客户端与分片集群的交互工作。
MongoDB GridFS
GridFS是MongoDB的一个子模块,使用GridFS可以基于MongoDB来持久化文件,并且支持分布式存储和读取。
GridFS也是文件存储的一种方式,它不会将文件存储在单个文档中,而是将文件分为多个块,并将每个块存储为单独的文档。默认情况下,GridFS使用的块大小为255KB。GridFS使用chunks集合和files集合来存储文件和元数据。chunks集合用于存储文件的数据块,每个块存储一个文件的一部分数据。每个块都有一个唯一的标识符(chunk id)和一个顺序号,用于重建文件数据。files集合用于存储文件的元数据信息,包括文件名、文件大小、上传日期等。
当客户端在GridFS中查询文件时,MongoDB首先从files集合中获取该文件的元数据信息,然后根据获取的元数据信息在chunks集合查找符合要求的块(即files id与元数据中_id相同的块),最后将这些块重新组装后返回给客户端。在查询时还可以指定查询范围,访问文件中的任意部分信息。
MongoDB的优缺点
优点:
1.MongoDB不需要预定义的模式或表结构。这意味着可以根据需要存储不同结构的数据,而无需修改现有的模式。这种灵活性使得MongoDB在应对不断变化的数据需求时更加方便。
2.MongoDB可以轻松地处理大规模数据和高并发访问。通过添加更多的节点和分布式集群,可以增加数据库的容量和吞吐量。
3.MongoDB的分片和副本集可以支持海量数据的存储和处理。它还提供了水平扩展和垂直扩展的方式,可以根据应用程序的需求进行扩展。
缺点:
1.MongoDB的查询缓存机制需要使用大量的内存来存储常用的数据。在处理大规模数据时,可能会对系统资源造成一定压力。因此,在设计和配置数据库时需要注意内存的管理和调整。
2.MongoDB不支持复杂的查询,例如表连接和子查询。如果需要执行这些查询,可能需要进行数据转换和处理,这会增加开发者的工作量。
3.MongoDB的灵活性和快速迭代可能会造成存储空间的浪费。如果设计不好,可能造成数据冗余或文档结构膨胀,这将增加存储空间的成本。