MongoDB & 关系型数据库
MongoDB 的读操作事务
在读取数据的过程中,需要关注以下两个问题。
第一个问题是由 readPreference 来解决;第二个问题则是由 readConcern 来解决。
什么是 readPreference?
MongoDB 是分布式的架构,在最小的部署下,它必须是一个“主-从-从”一主二从的三个节点的架构,如果涉及到分片,那么可能会有几十个节点。数据分布在这些节点上,从哪个节点读取数据,就是一个非常大的学问。
readPreference 决定使用哪一个节点来满足正在发起的读请求,它的可选值有如下几种。
只选择主节点(默认值)。
优先选择主节点,如果不可用则选择从节点。
优先选择从节点,如果从节点不可用则选择主节点
选择最近的节点(根据 ping time 来决定)
readPreference 的使用场景
因为此时从节点可能还没有复制到新订单。
因为查询历史订单,通常对时效性没有太高的要求。
因为报表对时效性要求不高,但对资源的需求大,可以在从节点上单独处理,避免对线上用户造成影响。
因为这样每个地区的应用都可以选择最近的节点来读取数据。
readPreference & Tag
如上所述,readPreference 可以设置固定的节点角色(主节点/从节点),但有些情况下,可能并没有固定的节点角色,或者需要定向指向某个或某些节点,这时可以考虑使用 Tag。
readPreference 只能控制使用一类节点,Tag 则可以将节点选择控制到一个或几个节点。
假设有如下场景:一个拥有 5 个节点的复制集,3 个节点硬件较好,专用于服务线上用户;2 个节点硬件较差,专用于生成报表。
这时可以使用 Tag 来进行区分控制:为 3 个较好的节点打上 { purpose: “online” };为 2 个较差的节点打上 { purpose: “analyse” },在线应用读取时指定 online,报表读取时指定 analyse。
readPreference 的配置
mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=rs&readPreference=secondary
MongoCollection.withReadPreference(ReadPreference readPref)
db.collection.find({}).readPref(“secondary”)
readPreference 的注意事项
MongoDB 的写操作事务
什么是 writeConcern?
writeConcern 决定一个写操作落到多少个节点上才算成功(决定了 MongoDB 是否会丢失数据)。
writeConcern 的取值有以下几种。
发起写操作,不关心是否成功。
写操作需要被复制到指定的节点数,才算成功。
写操作需要被复制到大多数节点上,才算成功(推荐使用)。
全部节点都需要确认写入,才算成功。
发起写操作的程序,将阻塞到写操作到达指定的节点数为止。
MongoDB 的数据丢失
当应用程序尝试写入一条数据"x = 1",首先进入 primary 节点,如果没有做任何设置,writePreference 默认只写一个节点,一旦写入 primary 则马上返回,表示成功(甚至可能没有写入磁盘,只是保存在 primary 的内存中)。
图中指向从节点的虚线,表示将主节点的写入数据同步复制到从节点上,这个同步的过程是由后台的线程进行的。
所谓的数据丢失,就是指在同步复制的过程中,主节点写入后立马返回,但马上就 crash 宕机,导致从节点并没有复制成功。此时从节点进行新的主节点选举,来继续服务于客户端,但从节点上并没有刚才写入的数据(实际上数据并未丢失,MongDB 会把数据写入到备用文件 —— rollback 文件中)。
writeConcern 的 journal 属性
writeConcern 可以决定写操作到达多少个节点才算成功,而 journal 则是决定如何才算成功,保证数据库节点在宕机后可以快速恢复刚才的写操作。
写操作落到 journal 文件中才算成功。
写操作到达内存中才算成功。
writeConcern 的注意事项
MongoDB 的分片集群
MongoDB 有几种常见的部署架构。
本地开发时使用。
一主二从,高可用。
节点数量和角色较多,横向扩展。
为什么使用分片集群?
完整的分片集群
提供集群的单一入口,转发应用端请求;选择合适的数据节点进行读写;合并多个数据节点的返回;建议至少有 2 个。
标准的普通实例,有 3 个节点;提供集群元数据的存储分片数据分布的映射关系。
以复制集为单位(一个分片即为一个复制集)进行横向扩展,最大为 1024 分片,且分片之间的数据不重复,所有的分片在一起才能完整工作。
MongoDB 分片集群的特点
MongoDB 分片集群的分布方式
选择一个或几个组合字段,将字段值的范围划分成范围空间(例如 chunk1、chunk2…),每个 chunk 仅作为一个逻辑区块,多个 chunk 组合起来存储到映射表中。
对字段做哈希,将数据随机写入到各个区块范围内,实现随机分布到各个节点上,对大量写入很友好,但对查询不友好。
针对地域性字段进行标签化区分。