分布式查询
一、分片集群读操作
分片集群允许您分割一个数据库设置为mongod实例集群的一部分,这种方式对应用程序来说近乎是透明的。对于分片集群的概念,请参阅本手册的分片部分。
对于分片集群,应用程序发出操作到与集群关联的mongos实例之一。
分片集群图
当直接定向到一个分片时在分片集群上的读操作是最有效的。分片的集合的查询将包含一个分片的key。当一个查询包含一个分片的key,mongos能用集群元数据从配置数据库路由查询到分片。
读操作一个分片集群。查询条件包括分片key。查询路由mongos可以定位查询到相应的分片或分片组。
如果查询不包括分片key,mongos直接查询集群中的所有分片。这些聚集查询是低效的。在更大的集群,分散聚集查询的日常操作是不可行的。
读操作一个分片集群。查询条件不包括分片key。查询路由mongos必须发送查询到所有的分片集
合。
对于读操作到分片群集的更多信息,参阅分片集群查询路由和分片key部分。
二、读操作到副本集
副本集用读取优先来决定路由查询到哪里的副本集成员。默认情况下,MongoDB总是从副本集的主读取数据。你可以通过改变读取优先模式修改那个行为。
可以基于每个连接或每个操作为基础配置读取优先模式,以允许从从读取数据:
减少多数据中心部署的延迟,
通过分发高读取量(相对于大量写)提高读取的吞吐量,
用于备份操作,和/或,
允许在故障转......
写操作概述
一个写操作可以是任何在MongoDB实例中的创建或者修改数据的操作。在MongoDB中,写操作作用于一个单独的集合。在MongoDB中所有的写操作在一个单独文档级别是原子的。
在MongoDB中有三种写操作,如果你能指定标准或条件,符合条件的文档将更新或者删除。这些操作使用相同的查询语法来指定标准的读操作。
MongoDB允许应用程序以确定写入操作不需要确认的可接受水平。更多信息查看写关注。
一、创建
创建操作添加新的文档到一个集合中。在MongoDB中,db.collection.insert()方法执行创建操作。
下面的图表高亮突出了MongoDB插入操作部分。
MongoDB插入操作部分
下面的图表显示了在sql中同样的查询操作。
sql插入操作部分
例子
下面的操作插入一个新的文档到users集合。新文档有四个字段:name,age,status和_id。_id字段总是会添加到文档中,就算MongoDB不存在这个字段。
db.users.insert(
{
name: "sue",
age: 26,
status: "A"
}
)
更多信息,查阅do.collection.insert()和插入文档。
一些更新操作也能创建记录。如果一个更新操作用upsert标志,而且查询没有匹配的文档,更新操作会插入一个新的文档。如果有匹配的文档,更新操作会对这些文档进行修改。
用一个upsert,应用程序会在insert和update两者之间决定单独调用执行哪一个。update()方法和save()方法两个都能执行一个unsert。查看......
写关注
写关注描述一个写操作是否成功的报告时的MongoDB提供的保证。写关注的强度决定了保证的级别。当插入,更新和删除有一个弱的写关注,写操作的返回是很快的。在一些失败的例子中,用弱的写关注发出的写操作可能无法持久。用强的写关注,发送一个写操作到MongoDB后客户端等待确定这个写操作。
MongoDB中提供了不同级别的写关注,以更好地满足应用的特定需求。客户端可以通过调整写关注,以确保最重要的操作成功地持续到整个MongoDB的部署。对于其他不太重要的业务,客户端可以调整写关注,以确保更快的性能,而不是保证持久化到整个部署。
在版本2.6中的变化:对于写操作的新协议,集成了写操作写关注。
关于写关注配置的详细信息,请参阅写关注参考。
一、注意事项
默认写关注
mongo命令行和MongoDB驱动使用Acknowledged做为默认的写关注。
查看Ackowledged的更多信息,以及这个写关注成为默认。
读隔离
MongoDB允许客户端在提交插入修改到磁盘之前读取插入或修改的文档。不管写关注级别或日记配置。作为默认,应用程序可能会发现两类行为:
对于有多个并发读和写的系统,MongoDB将允许客户端读取写操作返回之前写操作的结果。
如果mongod在日志提交之前终止,即使写成功返回。查询可能已经读过了mong的重新启动后不存在数据。
其他数据库系统指这些隔离语义为已读未提交。对于所有的插入和更新,MongoDB修改......
分布式写操作
一、分片集群的写操作
对于分片集群的分片集合,mongos决定写操作从应用到负责将数据集的特定部分的分片。mongos用集群元数据从配置数据库路由写操作到合适的分片。
一个分片集群图
MongoDB根据分片键的值在一个分片集合内分割数据到一定范围。然后,MongoDB分步这些数据块到分片。分片键决定块到分片的分配。在一个集群里这个能影响写操作的性能。
重要提示:
影响单个文件的更新操作必须包括分片键或_id字段。在某些情况下,如果它们具有分片键,更新影响多个文档是更有效的,但能传播到所有的分片。
如果分片键的值增加或减少在针对单一分片的每一个的插入,所有的插入操作。其结果是,单个分片的容量成为限制分片集群的插入的容量。
更多信息,查看分片集群教程和在MongoDB中批量插入。
二、在副本集上的写操作
在副本集,所有的写操作进入设置的主,它应用写操作然后记录写操作在主的操作日志或oplog。oplog是对数据集操作的可再现序列。设备的从成员用一个异步的进程不断复制oplog和应用操作到它自身。
读和写到主的默认路线图
大量的写操作,特别是批量操作,可能造成在足够的速度下从成员应用从主复制操作困难的情况。这可能导致从成员的状态跟不上主。从成员显著落后于主为副本集的正常操作出现问题。尤其是在故障转移回滚的形式以及一般的读一致性。
为了避免这个问题,你可以定义写关注每100或1000个操作从......
写操作性能
一、索引
在每个插入、更新、删除操作后,MongoDB必须更新与每一个集合中除了数据本身相关联的索引。因此,在集合上的每个索引为写操作的性能增加了额外的开销。[1]
在一般情况下,索引为读操作提供性能提升在插入上的惩罚是值得的。无论如何,为了在可能的情况来优化写性能,创建新的索引时要小心,并评估现有的索引,以确保您的查询实际上使用这些索引。
对于索引和查询,查看索引优化。更多索引的信息,查看索引和索引策略。
[1]对于插入和更新到非索引字段,稀疏索引的开销小于非稀疏索引。此外对于非稀疏索引,更新,不改变记录的大小,索引开销较少。
二、文件增长
如果一个更新操作导致一个文档超过当前分配记录的大小。MongoDB为文档在磁盘上重新配置足够的空间来保存文档。这些重新分配的时间比在立即更新时时间要长,特别是如果集合具有索引。如果集合具有索引,MongoDB必须更新所有索引条目。因此,对于有很多索引的集合,此举将影响写入吞吐量。
一些更新操作,就像$inc操作,不导致增加的文件大小。对于这些更新操作,MongoDB可以申请就地更新。其他更新操作,如$push操作,会改变文档的大小。就地更新比造成文件增长的更新更有显著的成效。如果可能的话,使用数据模型,最大限度地减少了需要的文件增长。
更多信息请参阅存储。
三、存储性能
硬件
对于MongoDB的写操作的性能存储系统......