3月30日,openGemini社区发布了v1.0.1版本,较v1.0.0版本,主要修复了一些异常场景下的发现的问题,欢迎大家下载试用和反馈。
v1.0版本新增了多个关键特性,并在数据压缩算法、内存管理、查询引擎等方面做了大量优化工作,整体性能取得进一步提升
由于对数据压缩算法进行了修改,v1.0版本与v0.2版本的数据存在不兼容
社区地址:https://github.com/openGemini
社区联系方式:http://opengemini.org/contact-us
性能优化
内存优化
内存优化是性能优化中非常重要的一部分,openGemini的关键优化项如下:
- 优化乱序文件合并流程 乱序文件合并不再将乱序文件全部加载到内存,改为流式合并方式,不同数据模型下,内存开销可减少20%-80%不等。
- 优化索引搜索流程 一方面在查询场景中,设置时间线内存分配上限,避免因无节制对内存索取,对其他查询请求造成影响;另一方面在查询数据组装过程中,放弃内存拷贝,改为数据原地更新,相比优化前,单次查询可减少40%内存空间使用。
- 查询场景优化
通常一个查询请求到来后,在openGemini内部会生成相关时间线的迭代器,时间线越多,一次性加载时间线元数据和迭代器占用的内存空间越大,采用延迟加载技术,根据需要加载指定时间线的元数据和迭代器,有效提升了内存的利用率,降低内存开销达80%以上。
查询优化
查询优化是性能优化中最为直接的优化源头,但查询优化是一个复杂的工程,需要多方面的数据库领域专家知识和经验,它使用了非常多的优化策略来生成一个最优的查询计划。通过性能测试,openGemini整体的性能较优化前再次提升了30%-80%,主要优化项如下:
- 简化DAG构建流程和编码 在openGemini内部,查询请求被生成为一棵树形的查询计划,为了将查询计划中各个操作尽可能并发起来,以达到查询效率提升的目的,需再转换成表示分布式执行计划的DAG关系图,由ts-sql分发到不同的ts-store节点执行。通常一个简单查询的DAG关系图序列化之后大小为1-2KB,其序列化和网络传输开销却成为了简单查询的性能瓶颈。通过对DAG进行编码,有效降低了网络数据传输数据量,降低网络开销达95%
- 时间范围查询优化 针对时间范围的查询,进行了预裁剪,提升了时间跨度较大场景下的查询性能
- 文件句柄优化 随着系统长期的运行,数据文件越来越多,这对操作系统的文件句柄资源带来较大的消耗,优化采用按需打开的方式进行文件句柄管理,极大的节约了系统文件句柄资源。
- 进程启动RTO优化 ts-store进程重启时,优化了immutable的open速度,支持WAL异步回放机制。优化后,500万时间线,存储共50.4亿条数据(Metrics),进程重启RTO为1.96s,提升400%
- castor服务优化
增加失败重试、连接池以提升可靠性;支持返回更详细的错误信息;castor算子支持Group By time和tags
数据压缩算法优化
openGemini采用列式数据存储,针对每一列数据,根据不同数据类型使用不同的数据压缩算法,从而实现较好的数据压缩效率。 Float类型数据在运维监控等场景下应用非常广泛,当前业界比较常用的是基于Facebook的Gorilla浮点数压缩算法,openGemini亦是如此。
但实际分析来看Gorilla算法在部分数据模型下,压缩率并不理想,存在优化空间,因此在openGemini中采用了自适应的压缩处理方式,根据Float数据特征的不同,选择不同的压缩算法。优化后,openGemini采用了Snappy,Gorilla,RLE三种压缩算法的组合,相比于单独使用Gorilla,压缩率提升了60%,解压耗时减少38%
新增特性
支持多表full join
在某些场景下,为了更灵活地分析时序数据,我们需要使用full join操作。例如:
> SELECT * FROM m
name: m
time host region total val
---- ---- ------ ----- ---
1434055562000000000 1 east 2 3
1434055562000000000 1 west 2 1
1434055562000000000 2 east 2 4
1434055562000000000 2 west 2 2
用户可以编写以下查询语句来使用full join,并得到以下结果:
> SELECT m1.val, m2.val FROM (SELECT val FROM m WHERE host = '1') AS m1 FULL JOIN (SELECT val FROM m WHERE host = '2') AS m2 ON (m1.region = m2.region AND m1.total = m2.total) GROUP BY region, total
name: m1,m2
tags: region=east, total=2
time m1.val m2.val
---- ------ ------
1434055562000000000 3 4
name: m1,m2
tags: region=west, total=2
time m1.val m2.val
---- ------ ------
1434055562000000000 1 2
全连接查询语句以关键字ON后的等效条件连接左右子查询表中的所有行,并可以使用Group BY分组
支持流式聚合计算
海量数据场景下,传统CQ需要从磁盘读取大量数据进行计算,再写回磁盘文件。这种方式会出现一些问题
- 磁盘I/O消耗过大,影响其他业务
- 如果对同一张表做多种降采样,数据重复拉取
- I/O放大效应明显,对内存、磁盘以及网络带宽造成巨大压力
流式聚合计算,采用5级Pipeline,stream阶段负责任务管理,数据接入以及初步过滤。window阶段负责时间窗口过滤、计算、以及数据下盘。该方式具有高性能、网络开销小等优点,能有效降低数据降采样的资源消耗。
创建流式聚合语句如下:
CREATE STREAM cq_basic
INTO average_passengers AS
SELECT mean("passengers")
FROM bus_data
GROUP BY time(1h)," passengers" delay 20s
支持多级降采样
降采样(Downsampling)在此是指对时序数据进行降频,将原本较细粒度的数据降频后得到较粗粒度的数据。这样一来可以成倍减少历史数据规模,使得粗粒度的数据能够以更小的成本保存更长时间。
降采样后的数据点只保留原始数据的一些统计特征,openGemini支持七种统计特征:
- max:采样周期内样本值的最大值
- min:采样周期内样本值的最小值
- mean:采样周期内样本值的平均值
- sum:采样周期内样本值的和值
- count:采样周期内样本数个数
- first:采样周期内样本按时间序的第一个值
- last:采样周期内样本按时间序的最后一个值
可见降采样会造成原始数据失真,而不同场景对数据失真的容忍程度不同,在查询一年趋势的场景下,数据只需要大致的趋势正确即可。
与其他数据库中降采样功能不同的是,openGemini可同时自定义多个降采样时间范围和策略。
创建降采样任务的示例语句如下:
CREATE DownSample
ON autogen.mst (float(sum,mean,count,max,min,first,last),integer(sum,mean,count,max,min,first,last)) With Duration 60d SampleInterval(3d, 6d, 30d) TimeInterval(1m, 5m, 10m)
上述语句中,针对表mst进行降采样,降采样分为三级,从第3天的数据开始做第一级降采样,采样周期为1分钟,采样对象为浮点和整形的字段,采样方法为上述7种统计方法。第6天开始做第二级降采样,以此类推。该功能可有效减少存储空间50%,节约计算资源90%。
支持近似分位数查询
在时序数据分析的场景中,有时需要能够有效的理解数据分布(例如,P50,P90,P95),而无需对庞大的时间序列数据集执行昂贵的计算,则可以使用近似分位数查询。
较多数据库使用 TDigest 算法计算百分位数,例如InfluxDB、ClickHouse,ElasticSearch等,该算法在数据分布末端精度较高,计算速度快,内存开销小。但其缺点是数据非末端时精度可能会降低。openGemini设计的OGSketch近似统计算法,全范围的近似分位数查询能达到更高的精度,并同时考虑了数据增量更新问题,大幅提升每次算法构建与查询的效率,有效降低查询时延。
查询语句示例如下:
> select * from mst
name: mst
time address age alive country height name
---- ------- --- ----- ------- ------ ----
1629129600000000000 shenzhen 12 true china 70 azhu
1629129601000000000 shanghai 20 false american 80 alan
1629129602000000000 beijin 3 true germany 90 alang
1629129603000000000 guangzhou 30 false japan 121 ahui
1629129604000000000 chengdu 35 true canada 138 aqiu
1629129605000000000 wuhan 48 china 149 agang
1629129606000000000 52 true american 153 agan
1629129607000000000 anhui 28 false germany alin
1629129608000000000 xian true japan 179 ali
1629129609000000000 hangzhou 60 false canada 180
1629129610000000000 nanjin 102 true 191 ahuang
1629129611000000000 zhengzhou 123 false china 203 ayin
# percentile_ogsketch函数
> SELECT percentile_ogsketch(age, 50) FROM mst WHERE time >= 1629129600000000000 AND time <= 1629129611000000000 GROUP BY time(5s),country
name: mst
tags: country=american
time percentile_ogsketch
---- -------------------
1629129600000000000 20
1629129605000000000 52
1629129610000000000
name: mst
tags: country=canada
time percentile_ogsketch
---- -------------------
1629129600000000000 35
1629129605000000000 60
1629129610000000000
...
支持holtWinters()时序预测算子
时序预测是一类经典的问题,在学术界和工业界都有着广泛的研究和应用。例如根据过去一段时间的数据预测存储空间何时达到水位线,或者预测一个设备何时可能老化进入故障维修期等。
holtWinters函数可在指定的间隔内预测给定Field Key的n个预测值,但该方法适用于具有周期性规律的时序数据。
使用示例如下:
SELECT HOLT_WINTERS(FIRST("water_level"),10,4) FROM "db0"."autogen"."mst" WHERE "location"='Hunan' AND time >= '2015-08-22 22:12:00' AND time <= '2015-08-28 03:00:00' GROUP BY time(379m,348m)
节点间RPC通信支持数据压缩
openGemini各个节点之间使用RPC通信,当频繁查询大量数据时,可通过配置项打开该功能,可有效减少数据传输带宽,提高数据传输效率。
总结
本文主要介绍了openGemini v1.0新版本为用户提供的特性和性能优化,帮助大家更清楚了解新版本提供的能力,以及如何更好使用好这些能力。
欢迎大家试用和反馈,openGemini将一如既往提供更多更好用的功能,不断推动时序数据库的技术向前发展!
未来还将提供:
- 高可靠性:支持数据多副本
- 可观测性:支持openTelemetry的OLTP协议
- 高时间序列基数:数据库不再受限于时间线规模
- 标准SQL:支持标准SQL,降低学习成本
- 软硬件结合:将DPU技术与openGemini相结合,打造openGemini极致性能
openGemini 共创新,赢未来!