点击领会阿里云MongoDB数据库运维
MongoDB 4.4提供了您最需要的特征和增强功效。MongoDB 4.4 版本是“用户驱动的工程”,建立在MongoDB 4.x版本家族的基础上,是未来数据处置的理想平台。
MongoDB 4.4 使您能够:
更高效地构建事务、操作和剖析型应用随着需求的生长,可以随时随地天真界说和优化数据漫衍,从而在全球局限内扩展应用程序同时为您提供全球随便位置最优异的延迟,弹性和平安性控制体验。
MongoDB 4.4 作为每年一度的大版本更新,已经在 7.30 号正式宣布 GA,不像之前的大版本,总是有一些重磅 Feature 的公布,好比 3.6 的 Change Stream & Causal Consistency,4.0 的多文档事务,4.2 的漫衍式事务,这次的 4.4 版本更像是一个维护性的版本,而且是一个用户期待已久的维护性版本,MongoDB 官方也把这次公布称之为「User-Driven Engineering」,说明新版本主要是针对用户呼声最高的一些痛点,重点举行了改善。
MongoDB 在 3.0 支持新的 WiredTiger 引擎后经由几年的快速奔跑,终于在 4.4 稍作歇息,最先在细节上举行打磨,4.4 公布的新特征许多,下面笔者就针对一些用户关注度比较高的 Feature 举行重点先容。
扩展性和性能增强
Hidden Indexes
Hidden Index 是阿里云 MongoDB 和 MongoDB 官方杀青战略互助后共建的一个 Feature。我们都知道数据库维护太多的索引会导致写性能的下降,然则往往营业上的庞大性决议了运维 MongoDB 的同砚不敢容易的删除一个潜在的低效率索引,忧郁错误的删除会带来营业性能的发抖,而重修索引往往价值也异常大。
Hidden Index 正是为领会决 DBA 同砚面临的上述逆境,它支持通过 collMod 下令对现有的索引举行隐藏,保证后续的 Query 都不会利用到该索引,在考察一段时间后,确定营业没有异常,可以放心的删除该索引。
db.runCommand( {
collMod: ‘testcoll’,
index: {
keyPattern: ‘key_1’,
hidden: false
}
} )
需要注重的是,索引被隐藏之后只是对 MongoDB 的执行计划器不能见,并不会改变索引自己的一些特殊行为,好比唯一键约束,TTL 镌汰等。
索引在隐藏时代,若是新的写入,也是会被更新的,以是也可以通过作废隐藏,很利便的让索引马上变的可用。
Refinable Shard Keys
当使用 MongoDB 分片集群时,信赖人人都知道选择一个好的 Shard key 是何等的主要,由于它决议了分片集群在指定的 Workload 下是否有优越的扩展性。然则在现实使用 MongoDB 的过程中,纵然我们事先仔细斟酌了要选择的 Shard Key,也会由于 Workload 的转变而导致泛起 Jumbo Chunk,或者营业流量都打向单一 Shard 的情形。
在 4.0 及之前的版本中,聚集选定的 Shard Key 及其对应的 Value 都是不能更改的,在 4.2 版本,虽然可以修改 Shard Key 的 Value,然则数据的跨 Shard 迁徙以及基于漫衍式事务的实现机制导致性能开销很大,而且并不能完全解决 Jumbo Chunk 或接见热门的问题。好比,现在有一个订单表,Shard Key 为 {customer_id:1},在营业初期每个客户不会有许多的订单,这样的 Shard Key 完全可以知足需求,然则随着营业的生长,某个大客户累积的订单越来越多,进而对这个客户订单的接见成为某个单一 Shard 的热门,由于订单和customer_id自然的关联关系,修改customer_id并不能改善接见不均的情形。
针对上述类似场景,在 4.4 中,你可以通过 refineCollectionShardKey 下令给现有的 Shard Key 增添一个或多个 Suffix Field 来改善现有的文档在 Chunk 上的漫衍问题。好比,在上面形貌的订单营业场景中,通过refineCollectionShardKey下令把 Shard key 更改为{customer_id:1, order_id:1},即可制止单一 Shard 上的接见热门问题。
需要领会的是,refineCollectionShardKey 下令性能开销异常低,只是更改 Config Server 上的米数据,不需要任何形式的数据迁徙(由于单纯的添加 Suffix 并不会改变数据在现有chunk 上的漫衍),数据的打散仍然是在后续正常的 Chunk 自动盘据和迁徙的流程中逐步举行的。此外,Shard Key 需要有对应的 Index 来支持,以是refineCollectionShardKey 要求提前建立新 Shard Key 对应的 Index。
由于并不是所有的文档都存在新增的 Suffix Field(s),以是在 4.4 中现实上隐含支持了「Missing Shard Key」的功效,即新插入的文档可以不包罗指定的 Shard Key Field。然则,笔者不建议这么做,很容易发生 Jumbo Chunk。
Compound Hashed Shard Keys
在 4.4 之前的版本中,只能指定单字段的哈希片键,缘故原由是此时 MongoDB 不支持复合哈希索引,这样导致的效果是,很容易泛起聚集数据在分片上漫衍不均。
而在 4.4 中支持了复合哈希索引,即,可以在复合索引中指定单个哈希字段,位置不限,可以作为前缀,也可以作为后缀,进而也就提供了对复合哈希片键的支持,
sh.shardCollection(
“examples.compoundHashedCollection”,
{ “region_id” : 1, “city_id”: 1, field1″ : “hashed” }
)
sh.shardCollection(
“examples.compoundHashedCollection”,
{ “_id” : “hashed”, “fieldA” : 1}
)
有这个新功效之后,会带来许多利益,好比在如下两个场景下,
在没有「复合哈希片键」支持的情形下,只能由营业对需要的字段提前盘算哈希值,存储到文档中的某个特殊字段中,然后再通过「局限分片」的方式指定这个预先盘算出哈希值的特殊字段及其他字段作为片键来解决上述问题。
而在 4.4 中直接把需要的字段指定为为哈希的方式即可轻松解决上述问题,好比,对于上文形貌的第二个问题场景,片键设置为 {customer_id:’hashed’, order_id:1} 即可,大大简化了营业逻辑的庞大性。
Hedged Reads
接见延迟的升高可能会带来直接的经济损失,Google 有一个研究报告解释,若是网页的加载时间跨越 3 秒,用户的跳出率会增添 50%。以是,在 4.4 中 MongoDB 提供了 Hedged Reads 的功效,即在分片集群场景下,mongos 会把一个读请求同时发送到某个分片的两个副本集成员,然后选择最快的返回效果回复客户端,来削减营业上的 P95 和 P99 延迟。
Hedged Reads 功效是作为 Read Preference 的一部门来提供的, 以是可以是在 Operation 粒度上做设置,当 Read Preference 指定 nearest 时,默认启用 Hedged Reads 功效,当指定为 primary 时,不支持 Hedged Reads 功效,当指定为其他时,需要显示的指定 hedgeOptions,如下,
db.collection.find({ }).readPref(
“secondary”, // mode
[ { “datacenter”: “B” }, { } ], // tag set
{ enabled: true } // hedge options
)
此外,Hedged Reads 也需要 mongos 开启支持,设置 readHedgingMode 参数为 on,默认 mongos 开启该功效支持。
db.adminCommand( { setParameter: 1, readHedgingMode: “on” } )
降低复制延迟
主备复制的延迟对 MongoDB 的读写有异常大的影响,一方面,在一些特定的场景下,读写需要守候,备库需要实时的复制并应用主库的增量更新,读写才气继续,另一方面,更低的复制延迟,也会带来备库读时更好的一致性体验。
Streaming Replication
在 4.4 之前的版本中,备库通过不停的轮询主库来获取增量更新操作。每次轮询时,备库自动给主库发送一个 getMore 下令读取其上的 Oplog 聚集,若是有数据,返回一个最大 16MB 的 Batch,若是没有数据,备库也会通过 awaitData 选项来控制备库无谓的 getMore 开销,同时能够在有新的增量更新时,第一时间获取到对应的 Oplog。
拉取是由单个 OplogFetcher 线程来完成,每个 Batch 的获取都需要履历一个完整的 RTT,在副本集网络状态欠好的情形下,复制的性能就严重受限于网络延迟。以是,在 4.4 中,增量的 Oplog 是不停的“流向”备库的,而不是依赖备库自动轮询,相比于之前的方式,至少在 Oplog 获取上节省了一半的 RTT。
当用户的写操作指定了 “majority” writeConcern 的时刻,写操作需要守候足够多的备库返回复制乐成的确认,MongoDB 内部的一个测试解释,在新的复制机制下,在高延迟的网络环境中,可以平均提升 50% 的 majority 写性能。
另外一个场景是用户使用了Causal Consistency,为了保证可以在备库读到自己的写操作(Read Your Write),同样强依赖备库对主库 Oplog 的实时复制。
Simultaneous Indexing
在 4.4 之前的版本中,索引建立需要在主库完成之后,才会复制到备库上执行。备库上的建立动作,在差别的版本中,由于建立机制和建立方式(前台、后台)的差别,对备库Oplog 的应用影响也大为差别。
然则,纵然在 4.2 中,统一了前后台索引建立机制,使用了相当细粒度的加锁机制——只在索引建立的最先和竣事阶段对聚集加独占锁,也会由于索引建立自己的性能开销(CPU、IO),导致复制延迟,或者由于一些特殊操作,好比 collMod 下令修改聚集米信息,而导致 Oplog 的应用壅闭,甚至会由于主库历史Oplog 被覆盖掉而进入 Recovering 状态。
在 4.4 中,主库和备库上的索引建立操作是同时举行的,可以大幅削减由于上述情形所带来的主备延迟,只管保证纵然在索引建立过程中,备库读也可以接见到最新的数据。
此外,新的索引建立机制是在 majority 的具备投票权限的数据承载节点返回乐成后,索引才会真正生效。以是,也可以减轻在读写星散场景下,由于索引差别而导致的性能差异。
可用性和容错性增强
Mirrored Reads
在服务阿里云 MongoDB 客户的过程中,笔者考察到有许多的客户虽然购置的是三节点的副本集,然则现实在使用过程中读写都是在 Primary 节点,其中一个可见的 Secondary 并未承载任何的读流量。
那么在偶然的宕机切换之后,客户能显著的感受到营业的接见延迟会有发抖,经由一段时间后才会恢复到之前的水平,发抖缘故原由就在于,新选举出的主库之前从未提供过读服务,并不领会营业的接见特征,没有针对性的对数据做缓存,以是在突然提供服务后,读操作会泛起大量的「Cache Miss」,需要从磁盘重新加载数据,造成接见延迟上升。在大内存实例的情形下,这个问题更为显著。
在 4.4 中,MongoDB 针对上述问题实现了「Mirrored Reads」功效,即,主库会按一定的比例把读流量复制到备库上执行,来辅助备库预热缓存。这个执行是一个「Fire and Forgot」的行为,不会对主库的性能发生任何实质性的影响,然则备库负载会有一定水平的上升。
流量复制的比例是可动态设置的,通过 mirrorReads 参数设置,默认复制 1% 的流量。
db.adminCommand( { setParameter: 1, mirrorReads: { samplingRate: 0.10 } } )
此外,可以通过db.serverStatus( { mirroredReads: 1 } )来查看 Mirrored Reads 相关的统计信息,
SECONDARY>db.serverStatus( { mirroredReads: 1 } ).mirroredReads
{ “seen” : NumberLong(2), “sent” : NumberLong(0) }
Resumable Initial Sync
在 4.4 之前的版本中,若是备库在做全量同步,泛起网络发抖而导致毗邻闪断,那么备库是需要重头最先全量同步的,导致之前的事情所有白费,这个情形在数据量比较大时,好比 TB 级别,加倍让人溃逃。
而在 4.4 中,MongoDB 提供了,因网络异常导致全量同步中止情形下,从中止位置恢复全量同步的能力。在实验恢复一段时间后,若是仍然不乐成,那么会重新选择一个同步源举行新的全量同步。这个实验的超时时间默认是 24小时,可以通过 replication.initialSyncTransientErrorRetryPeriodSeconds 在历程启动时更改。
需要注重的是,对于全量同步过程中遇到的非网络异常导致的中止,仍然需要重新提议全量同步。
Time-Based Oplog Retention
我们知道,MongoDB 中的 Oplog 聚集纪录了所有的数据调换操作,除了用于复制,还可用于增量备份,数据迁徙,数据订阅等场景,是 MongoDB 数据生态的主要基础设施。
Oplog 是作为 Capped Collection 来实现的,虽然从 3.6 最先,MongoDB 支持通过 replSetResizeOplog 下令动态修改 Oplog 聚集的巨细,然则巨细往往并不能准确反映下游对Oplog 增量数据的需求,思量如下场景,
以是,在真实的应用场景下,许多时刻是需要保留最近一个时间段内的 Oplog,这个时间段内发生若干的 Oplog 往往是很难确定的。
在 4.4 中,MongoDB 支持 storage.oplogMinRetentionHours 参数界说最少保留的 Oplog 时长,也可以通过 replSetResizeOplog 下令在线修改这个值,如下,
// First, show current configured value
db.getSiblingDB(“admin”).serverStatus().oplogTruncation.oplogMinRetentionHours
// Modify
db.adminCommand({
“replSetResizeOplog” : 1,
“minRetentionHours” : 2
})
查询能力和易用性增强
传统的关系型数据库(RDBMS)普遍以 SQL 语言为接口,客户端可以在内陆编写融入部门营业逻辑的庞大 SQL 语句,来实现壮大的查询能力。MongoDB 作为一个新型的文档数据库系统,也有自界说的 MQL 语言,庞大查询能力主要借助于 Aggregation Pipeline 来实现,虽弱于 RDBMS,但在最近的几个大版本中也在连续不停的打磨,最终的目的是使用户在享受到 MongoDB 天真性和扩展性的同时,也能享受到厚实的功效性。
Union
在多表团结查询能力上,4.4 之前只提供了一个 $lookup stage 用于实现类似于 SQL 中的「left outer join」功效,在 4.4 中新增的 $unionWith stage 又提供了类似 SQL 中的「union all」功效,用户把两个聚集中的数据聚合到一个效果集中,然后做指定的查询和过滤。区别于 $lookup stage 的是,$unionWith stage 支持分片聚集。当在 Aggregate Pipeline 中使用了多个 $unionWith stage 的时刻,可以对多个聚集数据做聚合,使用方式如下,
{ $unionWith: { coll: “<collection>”, pipeline: [ <stage1>, … ] } }
可以在 pipeline 参数中指定差别的 stage,用于在对聚集数据聚合前,先举行一定的过滤,使用起来异常天真,下面举一个简朴的例子,好比营业上对订单数据按表拆分存储到差别的聚集,第二季度有如下数据(演示目的),
db.orders_april.insertMany([
{ _id:1, item: “A”, quantity: 100 },
{ _id:2, item: “B”, quantity: 30 },
]);
db.orders_may.insertMany([
{ _id:1, item: “C”, quantity: 20 },
{ _id:2, item: “A”, quantity: 50 },
]);
db.orders_june.insertMany([
{ _id:1, item: “C”, quantity: 100 },
{ _id:2, item: “D”, quantity: 10 },
]);
现在假设营业上需要知道,二季度差别产物的销量,在 4.4 之前,可能需要营业自己把数据都读出来,然后在应用层面做聚合才气解决这个问题,或者依赖某种数据仓库产物来做剖析,然则需要有某种数据的同步机制。
而在 4.4 中只需要如下一条 Aggregate 语句即可解决问题,
db.orders_april.aggregate( [
{ $unionWith: “orders_may” },
{ $unionWith: “orders_june” },
{ $group: { _id: “$item”, total: { $sum: “$quantity” } } },
{ $sort: { total: -1 }}
] )
Custom Aggregation Expressions
4.4 之前的版本中可以通过 find 下令中的 $where operator 或者 MapReduce 功效来实现在 Server 端执行自界说的 JavaScript 剧本,进而提供更为庞大的查询能力,然则这两个功效并没有做到和 Aggregation Pipeline 在使用上的统一。
以是,在 4.4 中,MongoDB 提供了两个新的 Aggregation Pipeline Operator,$accumulator 和 $function 用来取代 $where operator 和 MapReduce,借助于「Server Side JavaScript」来实现自界说的 Aggregation Expression,这样做到庞大查询的功效接口都集中到 Aggregation Pipeline 中,完善接口统一性和用户体验的同时,也可以把Aggregation Pipeline 自己的执行模子利用上,实现所谓 「1+1 > 2」 的效果。
$accumulator 和 MapReduce 功效有些相似,会先通过init 函数界说一个初始的状态,然后对于每一个输入的文档,凭据指定的 accumate 函数更新状态,然后会凭据需要决议是否执行 merge 函数,好比,若是在分片聚集上使用了 $accumulator operator,那么最后需要把差别分片上执行完成的效果做 merge,最后,若是指定了 finalize 函数,在所有输入文档处置完成后,会凭据该函数把状态转换为一个最终的输出。
$function 和 $where operator 在功效上基本一致,然则壮大之处是可以和其他的 Aggregation Pipeline Operator 配合使用,此外也可以在 find 下令中借助于 $expr operator 来使用 $function operator,等价于之前的 $where operator,MongoDB 官方在文档中也建议优先使用 $function operator。
其他易用性增强
Some Other New Aggregation Operators and Expressions
除了上述的 $accumulator 和 $function operator,4.4 中还新增了其他多个 Aggregation Pipeline Operator,好比做字符串处置的,获取数组收尾米素的,另有用来获取文档或二进制串巨细的操作符,详细见如下列表,
Connection Monitoring and Pooling
4.4 的 Driver 中增添了对客户端毗邻池的行为监控和自界说设置,通过尺度的 API 来订阅和毗邻池相关的事宜,包罗毗邻的关闭和打开,毗邻池的清算。也可以通过 API 来设置毗邻池的一些行为,好比,拥有的最大/最小毗邻数,每个毗邻的最大空闲时间,线程守候可用毗邻时的超时时间,详细可以参考 MongoDB 官方的设计文档。
Global Read and Write Concerns
在 4.4 之前的版本中,若是操作的执行没有显式指定 readConcern 或者 writeConcern,也会有默认行为,好比readConcern 默认是 local,而 writeConcern 默认是 {w: 1}。然则,这个默认行为并不能以调换,若是用户想让所有的 insert 操作的 writeConcern 默认都是是 {w: majority},那么只能所有接见 MongoDB 的代码都显式去指定该值。
在 4.4 中可以通过 setDefaultRWConcern 下令来设置全局默认的 readConcern 和 writeConcern,如下,
db.adminCommand({
“setDefaultRWConcern” : 1,
“defaultWriteConcern” : {
“w” : “majority”
},
“defaultReadConcern” : { “level” : “majority” }
})
也可以通过 getDefaultRWConcern 下令获取当前默认的readConcern 和 writeConcern。
此外,这次 MongoDB 做的加倍知心,在纪录慢日志或诊断日志的时刻,会纪录当前操作的 readConcern 或者 writeConcern 设置的泉源,二者相同的泉源界说有如下三种,
对于 writeConcern 来说,另有如下一种泉源,
New MongoDB Shell (beta)
对于运维 MongoDB 的同砚来说,使用最多的工具可能就是 mongo shell,4.4 提供了新版本的 mongo shell,增添了像代码高亮,下令自动补全,加倍可读的错误信息等异常人性化的功效,不外,现在照样 beta 版本,许多下令还不支持,仅供尝鲜。
MongoDB云平台
MongoDB 云平台在这次的 4.4 新版本公布中也有异常多的更新,好比,类似于 DynamoDB 的 Auto-Scale 功效,可以凭据营业负载的转变自动调换资源配额,为用户降低成本,索引和 Schema 推荐功效,数据归档和归档查询功效,增强的的数据可视化服务,和收购的移动端数据库 Realm 的整合等。
在剖析能力上,MongoDB 在 2019 年 6 月份推出了自己的 Atlas 数据湖产物,在这次的 4.4 版本公布中,数据湖同样也有多项主要更新,好比联邦查询功效,一条 MQL 语句可以同时查询 Atlas 云服务实例和 AWS S3 中的数据,Aggregation Pipeline 执行效果直接导出到 S3,SQL 查询能力支持,可以更好的配合使用现有的 BI 工具。
总的来说,MongoDB 逐渐的从一个专注于数据库服务的厂商,转变为提供数据平台服务的厂商。
其他
这次的 4.4 公布,前面讲了主要是一个维护性的版本,以是除了上述解读,另有许多其他小的优化,像 $indexStats 优化,TCP Fast Open 支持优化建连,索引删除优化等等,另有一些相对大的增强,像新的结构化日志LogV2,新的平安机制支持等,这些可能不是用户最优先去关注的,在这里就不逐一形貌了,感兴趣的读者可以自行参考官方的 Release Notes。
原文链接:MongoDB4.4新特征新功效