首页 » PHP教程 » phpmongodb时光技巧_技能干货|MongoDB时间序列集合

phpmongodb时光技巧_技能干货|MongoDB时间序列集合

访客 2024-12-02 0

扫一扫用手机浏览

文章目录 [+]

Glossary

bucket:带有相同的元数据且在一段有限定的间 隔区间内的丈量值组。

phpmongodb时光技巧_技能干货|MongoDB时间序列集合

bucket collection :用于存储时序型凑集的底层的分组桶的系统凑集。
复制、分片和索引都是在桶级别上完成的。

phpmongodb时光技巧_技能干货|MongoDB时间序列集合
(图片来自网络侵删)

measurement:带有特定时间序列的K-V凑集。

meta-data:时序序列里很少随韶光变革的K-V对,同时可以用于识别全体时序序列。

time-series:一段间隔内的一系列丈量值。

time-series collection:一种表示可写的非归天的视图的凑集类型,它许可存储和查询多个韶光序列,每个序列可以有不同的元数据。

MongoDB 在5.0中支持了新的timeseries collection类型的选项,该类型用于存储时序型数据。
timeseries collection供应了一组用于插入和查询丈量值的大略接口,同时底层实际的数据是存储在以bucket形式的凑集中。

在创建timeseries collection时,timeField字段是最小必备的配置项。
metaField是另一个可选的、可被指定的元数据字段,它是用于在bucket中对丈量值分组的依据。
MongoDB通过供应expireAfterSeconds字段选项,也支持了对丈量值的过期机制。

在mydb数据库中有个以mytscoll 命名的timeseries collection,该凑集在MongoDB内部的catelog(用于存储凑集或视图的信息)里是由一个视图和一个别系凑集组成的。

mydb.mytscoll 是个视图,它在MongoDB底层是用bucket collection作为包含特定属性的原始凑集实现的:该视图便是通过aggregation里的$_internalUnpackBucket来实现展开bucket里数据的。
该视图是可写的(仅支持插入)。
同时每个被插入的文档必须包含韶光字段。
在查询视图时,它会隐式地展开底层在bucket collection中存储的数据,然后返回原始的非bucket形式的文档数据。
该系统凑集的命名空间是mydb.system.buckets.mytscoll,它是用来存储实际数据的。
每一个在bucket collection里的文档,都表示了一组区间间隔的时序型数据。
如果在创建timeseries collection时,定义了metaField元数据字段,那么所有在bucket里的丈量值都会有这个通用的元数据字段。
除了韶光范围,bucket还限定了每个文档数据的总条数以及丈量值的大小。

Bucket Collection Schema

{ _id: <Object ID with time component equal to control.min.<time field>>, control: { // <Some statistics on the measurements such min/max values of data fields> version: 1, // Version of bucket schema. Currently fixed at 1 since this is the // first iteration of time-series collections. min: { <time field>: <time of first measurement in this bucket, rounded down based on granularity>, <field0>: <minimum value of 'field0' across all measurements>, <field1>: <maximum value of 'field1' across all measurements>, ... }, max: { <time field>: <time of last measurement in this bucket>, <field0>: <maximum value of 'field0' across all measurements>, <field1>: <maximum value of 'field1' across all measurements>, ... }, closed: <bool> // Optional, signals the database that this document will not receive any // additional measurements. }, meta: <meta-data field (if specified at creation) value common to all measurements in this bucket>, data: { <time field>: { '0', <time of first measurement>, '1', <time of second measurement>, ... '<n-1>': <time of n-th measurement>, }, <field0>: { '0', <value of 'field0' in first measurement>, '1', <value of 'field0' in first measurement>, ... }, <field1>: { '0', <value of 'field1' in first measurement>, '1', <value of 'field1' in first measurement>, ... }, ... }}

索引

indexes

为了担保timeseries collection的查询可以受益于索引扫描而不是全表扫描,timeseries collection许可索引可以被创建在韶光上,元数据上以及元数据的子属性上。
从MongoDB5.2开始,在timeseries collection大概可索引被创建在丈量值上。
用户利用createIndex命令供应的索引规范被转换为底层buckets collection的模式。

timeseries collection与底层的buckets collection之间的索引映射转换关系细节,你可以参考timeseries_index_schema_conversion_functions.h.在v5.2及以上版本的最新支持的索引类型,timeseries collection会存储用户原始的索引定义到变换后的索引定义上。
当从底层的bucket collection的索引映射到timeseries collections的索引时,会返回用户原始的索引定义。

当索引被创建后,可以通过listIndexes命令或$indexStats聚合操持来检讨。
listIndexes 和$indexStats是浸染于timeseries collections的,实行时,它们会在内部将底层的bucket collection的索引转化成timeseries格式的索引,并返回。
比如,当我们在元数据字段中定义有mm的timeseries collection上实行listIndexes命令时,底层的bucket collection的{meta:1}索引,将会以{mm:1}格式返回。

dropIndex 和collMod (hidden: <bool>, expireAfterSeconds: <num>) 也同样支持在timeseries collection上。

韶光字段上支持的索引类型:

单字段索引组合索引哈希索引通配符索引稀疏索引多键索引带排序的索引

元数据字段和元数据子字段支持的索引类型:

支持所有韶光字段上支持的索引类型v5.2及以上版本支持2d 索引v5.2及以上版本支持2dsphere 索引v5.2及以上版本支持 Partial索引

仅在v5.2及以上版本,丈量值字段支持的索引类型:

单字段索引组合索引2dsphere部分条件索引

`timeseries collections 上不支持的索引类型,包括 唯一索引以及文本索引。

桶目录

Catalog

为了担保高效地桶(分组)操作,我们在BucketCatalog里掩护了一组开启的桶,你可以在bucket_catalog.h找到。
在更高的级别,我们考试测验着把并发写程序的写操作分组合并为可以一起提交地批处理,以减少对底层文档的写次数。
写程序会插入它的输入批处理里的每一个文档到BucketCatalog,然后BucketCatalog会返回一个BucketCatalog::WriteBatch的处理器。
一旦完成上面那些插入操作后,写程序就会检讨每个写批处理。
如果没有其他的写程序已经对批处理声明提交的权利,那么它会声明权利,并会提交它的批处理。
否则,写程序将会稍后再提交处理。
当它检讨完所有的批处理,写程序将会等待其他的写程序提交每个剩下的批处理。

在内部,BucketCatalog掩护一组对每个bucket 文档的更新操作。
当批处理被提交时,它会将这些插入转换到成buckets的列格式,并确保任何control字段的更新(例如control.min 和 control.max)。

当bucket文档在没有通过BucketCatalog的情形下被更新时,写程序就须要为有问题的文档或命名空间去调用BucketCatalog::clear ,这样它就可以更新它的内部状态,避免写入任何可能毁坏bucket 格式的数据。
这常日由OP不雅观察者处理,但可能须要通过其他地方去调用。

bucket既可以通过手动设置选项control.closed 标识来关闭,也可以在许多场景下通过 BucketCatalog 自动关闭。
如果BucketCatalog利用了超出给定的阈值(可通过做事器参数timeseriesIdleBucketExpiryMemoryUsageThreshold掌握)的更多内存,此时它将会开始去关闭空闲的bucket。
如果bucket是开启的且它没有任何未处于等待中未提交的丈量值时,那么它就会被视为空闲的bucket。
不才面这些场下 BucketCatalog 也会关闭bucket: 如果它拥有超过最大阈值(timeseriesBucketMaxCount)的丈量值数据的数量;如果它拥有过大的数据量大小(timeseriesBucketMaxSize);又或者一个新的丈量值数据是否是会导致bucket在其最旧的韶光戳和最新的韶光戳之间跨度比许可的间隔更长的韶光(当前硬编码为一小时)。
如果传入的丈量值在事理上与已经到达给定bucket的度量不兼容,该bucket将被关闭,同时可以利用numBucketsClosedDueToSchemaChange度量进行跟踪。

在第一次提交给定bucket的写批处理时,就会天生新的完全的文档。
后续的批处理提交中,我们只实行更新操作,不再天生新的完全的文档(因此称为‘经典’更新),是直接创建DocDiff(“delta”或者v2的更新)。

粒度

Granularity

timeseries collection的granularity 选项在凑集创建的时候,可以被设置成seconds,minutes或者hours。
后期可通过colMod操作来修正这个选项从seconds到minutes或者从minutes到hours,除此之外的转化修正目前都是不支持的。
该参数想要表示在已给定的时序型丈量数据之间的粗略的韶光间隔,同时也用于调节其他内部参数对分组的影响。

单个bucket被许可的最大韶光跨度,是由granularity选项掌握,对付seconds,最大的韶光跨度被设置成1小时,对付minutes便是24小时,对付hours便是30天。

当通过BucketCatalog开启新的bucket时,_id里的韶光戳便是等同于control.min.<time field>的值,该值是从第一个插入bucket的丈量数据中根据granularity选项来向下近似舍入而得到的。
对付seconds,它将向下舍入到最靠近的分钟,对付minutes,将向下舍入到最靠近的小时,对付hours,它将向下舍入到最靠近的日期。
在闰秒和日历中的其他不规则情形下,这种舍入可能并不完美,并且常日通过对自纪元以来的秒数进行基本模运算来完成,假设每分钟 60 秒,每小时 60 分钟,以及每天 24 小时。

更新和删除

timeseries collection 支持符合以下限定的删除语句:

仅支持metaField的属性的查询语句支持批量操作

同时更新知足上面同样的条件,其余遵照:

仅支持metaField对应的属性值更新操作指定一个带有更新运算符表达式的更新文档(而不是更换文档或者更新的pipeline操作)不支持upsert:true 操作

这些更新与删除的实行都会被转换成相对应的底层的bucket collection的更新或删除操作。
特殊是,对付查询和更新文档,我们会利用真正的字段meta 更换凑集的metaField。
(拜会 Bucket 凑集规范)

例如,对付一个利用 metaField: "tag"创建的timeseries凑集db.ts,考虑一个对这个凑集的更新操作,其查询语句是{"tag.tag.a": "a"} ,同时更新文档语句是 {$set: {"tag.tag.a": "A"}, $rename: {"tag.tag.b": "tag.tag.c"}}。
这个更新操作在 db.system.buckets.ts上会被转换成,查询语句是{"meta.tag.a": "a"},更新语句是 {$set: {"meta.tag.a": "A"}, $rename: {"meta.tag.b": "meta.tag.c"}}。
然后这个转换后的更新语句就可以像普通的更新操作一样实行。
上面这些转换流程也适用于删除操作。

参考文献

References

MongoDB Blog: Time Series Data and MongoDB: Part 2 - Schema Design Best Practices

关于作者:黄璜

目前就职于上海DerbySoft,紧张从事根本架构中业务流程设计及研发的事情,平时事情中MongoDB利用的较多。
在提升自己外文的能力的同时,也希望为社区做出眇小的贡献。

社区招募为了让社区组委会成员和志愿者朋友们灵巧参与,同时我们为想要深度参与社区培植的伙伴们开设了“招募通道”,如果您想要在社区里面结交志同道合的技能伙伴,想要通过在社区沉淀有代价的干货内容,想要一个展示自己的舞台,提升自身的技能影响力,即刻加入社区贡献军队~ 点击链接提交申请:http://mongoingmongoing.mikecrm.com/CPDCj1B

标签:

相关文章

Java代码虚拟化保护技术与应用前景

软件应用的需求日益增长,软件开发过程中对代码的保护成为了一个重要议题。Java作为一种广泛应用于企业级应用的编程语言,其代码虚拟化...

PHP教程 2025-03-02 阅读1 评论0

CAD插件错误代码与应对步骤

CAD(计算机辅助设计)软件在工程设计领域得到了广泛应用。CAD插件作为提升设计效率的重要工具,在提高设计师工作效率的也带来了一定...

PHP教程 2025-03-02 阅读1 评论0

上古卷轴代码规则大全游戏背后的编程奥秘

《上古卷轴》作为一款深受玩家喜爱的角色扮演游戏,自问世以来便以其丰富的世界观、独特的游戏体验和深厚的文化底蕴吸引了无数玩家。在这款...

PHP教程 2025-03-02 阅读1 评论0