InfluxDB SHOW SERIES语句按照什么顺序返回?

在这里插入图片描述本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。

文章目录

  • 引言
  • 样例
  • SHOW SERIES比较原理
  • 结论
  • 结束语

引言

influxdb的计算引擎为了做到自底而上的合并逻辑,必然存在某种row的排序规则,这些规则在查询计划的创建阶段就已经确定。

比如group by tags,此类查询基于tag的排序;而group by time的查询,则基于time去做排序;group by tags, time 则是基于tags和time;至于show则是基于field排序;特殊的比如show series cardinality在改写为select后实际是基于tags排序;

事实上要完成一个流式引擎必须自底而上遵循某种排序规则;例如子查询内部的排序规则和内部排序规则不同是则需要重排,这就没法做到流式返回。

样例

show series不是基于serieskey或者基于展开后的tag做排序,简单的看两个show series 返回的case:

"yottadb_partition_replicas_num_lzl_ywq,account_id2=Mqw0vQ\\=\\="
"yottadb_partition_replicas_num_lzl_ywq,account_id4=Mqw0vQ\\=\\="
"yottadb_partition_replicas_num_lzl_ywq,account_id5=Mqw0vQ\\=\\="
"yottadb_partition_replicas_num_lzl_ywq,account_id7=Mqw0vQ\\=\\="
"yottadb_partition_replicas_num_lzl_ywq,account_id8=Mqw0vQ\\=\\="
"yottadb_partition_replicas_num_lzl_ywq,account_id9=Mqw0vQ\\=\\="
account_id2account_id4account_id5account_id7account_id8account_id9
Mqw0vQ\=\=nullnullnullnullnull
nullMqw0vQ\=\=nullnullnullnull
nullnullMqw0vQ\=\=nullnullnull
nullnullnullMqw0vQ\=\=nullnull
nullnullnullnullMqw0vQ\=\=null
nullnullnullnullnullMqw0vQ\=\=

这个case表示不是以serieskey内部的tag本身做排序;因为以这个规则排序展开后account_id9应该排在最前面,因为null本身小于任何值。

"car1,city=city_0dddd,id=2,type=type_2"
"car1,city=city_0dddd\\ ,id=2,type=type_2"
"car1,city=city_1,id=3,type=type_0"

空格的ascall码小于 ‘,’ ,所以也不是以serieskey排序

SHOW SERIES比较原理

我们回到show series,引擎内部迭代器调用栈帧如下:

  1. v1/coordinator/statement_executor.go:createIteratorsV2
  2. influxql/query/select.go:Select
  3. influxql/query/compile.go: (c *compiledStatement) Prepare 已经把shards赋值给preparedStatement.ic
  4. influxql/query/select.go: (p *preparedStatement) Select
  5. influxql/query/select.go:buildCursor
  6. influxql/query/select.go:buildAuxIterator
  7. tsdb/shard.go:(a Shards) CreateIterator
  8. tsdb/shard.go:(s *Shard) CreateIterator
  9. tsdb/engine/tsm1/engine.go:CreateIterator
  10. tsdb/shard.go:(a Shards) CreateIterator
  11. tsdb/shard.go:(a Shards) createSeriesIterator
  12. tsdb/index.go:NewSeriesPointIterator
  13. tsdb/index.go:MeasurementIterator (is IndexSet) measurementIterator()
  14. tsdb/index/tsi1/index.go: (i *Index) MeasurementIterator()
  15. tsdb/index/tsi1/partition.go (p *Partition) MeasurementIterator()
  16. tsdb/index/tsi1/file_set.go (fs *FileSet) MeasurementIterator()
  17. tsdb/index/tsi1/log_file.go (f *LogFile) MeasurementIterator()

事实上createSeriesIterator之下的MeasurementIterator都是基于measurement name做比较,真正的比较是shards中的seriesPointIterator,其首先会获取每一个measurement的全部时间序列对应的tsid,随后从sfile中获取tsid对应的serieskey,直接原地调用sort, 排序seriesKeys,实际调用CompareSeriesKeys作为比较函数。

核心比较函数为CompareSeriesKeys:

func CompareSeriesKeys(a, b []byte) int {
	// Handle 'nil' keys.
	if len(a) == 0 && len(b) == 0 {
		return 0
	} else if len(a) == 0 {
		return -1
	} else if len(b) == 0 {
		return 1
	}

	// Read total size.
	_, a = ReadSeriesKeyLen(a)
	_, b = ReadSeriesKeyLen(b)

	// Read names.
	name0, a := ReadSeriesKeyMeasurement(a)
	name1, b := ReadSeriesKeyMeasurement(b)

	// Compare names, return if not equal.
	if cmp := bytes.Compare(name0, name1); cmp != 0 {
		return cmp
	}

	// Read tag counts.
	tagN0, a := ReadSeriesKeyTagN(a)
	tagN1, b := ReadSeriesKeyTagN(b)

	// Compare each tag in order.
	for i := 0; ; i++ {
		// Check for EOF.
		if i == tagN0 && i == tagN1 {
			return 0
		} else if i == tagN0 {
			return -1
		} else if i == tagN1 {
			return 1
		}

		// Read keys.
		var key0, key1, value0, value1 []byte
		key0, value0, a = ReadSeriesKeyTag(a)
		key1, value1, b = ReadSeriesKeyTag(b)

		// Compare keys & values.
		if cmp := bytes.Compare(key0, key1); cmp != 0 {
			return cmp
		} else if cmp := bytes.Compare(value0, value1); cmp != 0 {
			return cmp
		}
	}
}

结论

所以事实上show series返回的真正顺序遵循以下规则:

  1. 以measurement name排序
  2. 每个measuremnet基于serieskey内部的tag本身做排序

其实很好理解,因为从tsi中获取measurement对应的tsid后又从sfile获取对应的serieskey,此时的serieskey为了解析的性能,事实上进行了二进制编码的,无法直接拿来比较;其次此时是没有schema的概念的,所以如果基于tag去排序效率会及其低下,因为需要先计算合并后的schema结构,然后再生成新的row,所以搞了个这么个性能不错,但是奇奇怪怪的排序方法;

这种比较方式可以应用到流式框架,但是意义不大,因为本身这种排序就没有规定一个全局顺序(不同的tagkey都直接拿来比较了),而且与influxql本来的排序方式差别很大,额外的开发工作很多;

从用户的角度看,show series的顺序没有什么意义,就算希望有意义,当前的show series也无法满足,所以最好的方式就是直接hash merge,不给用户保证show series的返回顺序,influxdb的官网也没有保证show series的顺序。

结束语

花了三十分钟迅速写完这篇文章,倒不是这个点很重要,关键在于我在半年前实现某些特性时"假设"其顺序是serieskey,在第二次实现"假设"其是以tag为顺序,最后发现与想的完全不同。

以后做任何事前都需要提醒自己,合理的规划可以节省大量时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435537.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Web安全靶场】upload-labs-master 1-21

upload-labs-master 其他靶场见专栏… 文章目录 upload-labs-masterPass-01-js前端校验Pass-02-MIME校验Pass-03-其他后缀绕过黑名单Pass-04-.hatccess绕过Pass-05-点空格点代码逻辑绕过Pass-06-大小写绕过Pass-07-空格绕过Pass-08-点号绕过Pass-09-::$DATA绕过Pass-10-点空格…

三、代码结构(不定时更新)

一、装饰器 Entry:标记当前组件是入口组件 Component:标记自定义组件 State:标记该变量是状态变量,值变化时会触发UI刷新 二、自定义组件 // 可复用的UI单元 struct Index {} 三、UI描述 // 其内部以声明式方式描述UI结构 bu…

fatal: unable to access ‘***‘: OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0解决方案

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 大家好,我是水滴~~ 本文主要介绍在从 GitHub 上克隆 stable-diffusion-webui 项目时出现的 fatal: unable to access https://github.com/AUTOMATIC1111/stable-diffusion-webui.…

【STM32】HAL库 CubeMX教程---通用定时器 定时

STM32常用型号的TIM时钟频率 1. STM32F103系列: 所有 TIM 的时钟频率都是72MHz;F103C8不带基本定时器,F103RC及以上才带基本定时器。 2、STM32F407系列: TIM1、8、9、10、11的时钟频率是168MHz;其它TIM的时钟频率是…

【PHP】PHP通过串口与硬件通讯,向硬件设备发送数据并接收硬件返回的数据

一、前言 之前写过两篇PHP实现与硬件串口交互的文章,一篇是【PHP】PHP实现与硬件串口交互,接收硬件发送的实时数据(上)_php串口通信-CSDN博客,另一篇是【PHP】PHP实现与硬件串口交互,向硬件设备发送指令数…

阿里云2核4G服务器支持人数并发测试,2核4G主机测评

阿里云2核4G服务器多少钱一年?2核4G配置1个月多少钱?2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

C++ LRU缓存

题目: //构建双向链表的节点结构(要有两个构造函数) struct Node{int key, val;Node* pre;Node* next;Node():key(0), val(0), pre(nullptr), next(nullptr) {}Node(int _key, int _val): key(_key), val(_val), pre(nullptr), next(nullpt…

基础小白快速入门web前端开发技术------>web概述

Web概述 我们在编程的学习中,随着学习的深入,我们会理解到WEB这个东西,那么 web究竟是个啥,到底该咋用? web,是网站的英文意思,又被称作“下一代Web3.0,互联网”,是在We…

简洁实用的wordpress外贸网站模板

坚果蜜饯wordpress跨境电商模板 木瓜干、菠萝干、夏威夷果、芒果干、椰片、巴旦木等wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3944 珠宝手饰wordpress外贸网站模板 金银手饰、珍珠手饰、翡翠手饰、钻石手饰、玉石珠宝手饰wordpress外贸网站模板。 https:…

docker无法运行问题

场景如下: 执行运行docker命令出现如下错误:systemctl start docker 出现该问题的原因:是因为我们配置的镜像加速器用不了了 去修改我们的镜像加速器, 去到配置镜像加速器的目录 cd /etc/docker 修改镜像加速器 vim daemon.j…

记一次 .NET某设备监控自动化系统 CPU爆高分析

一:背景 1. 讲故事 先说一下题外话,一个监控别人系统运行状态的程序,结果自己出问题了,有时候想一想还是挺讽刺的,哈哈,开个玩笑,我们回到正题,前些天有位朋友找到我,说…

二叉树进阶leetcode

606. 根据二叉树创建字符串 要点:前序遍历,当左子树为空时,右结点有数字时要给左边加括号 class Solution { public:string tree2str(TreeNode* root) {string s;//创建一个字符串if(rootnullptr){return s;}sto_string(root->val);//保存…

LLM | GPT-NEOX论文详解

GPT-NEOX使用旋转位置编码。模型权重使用float16表示。最大序列长度为2048。 论文题目:2022.04.14_GPT-NeoX-20B: An Open-Source Autoregressive Language Model 论文地址:2204.06745.pdf (arxiv.org) 论文代码:EleutherAI/gpt-neox: An imp…

go语言基础 -- 文件操作

基础的文件操作方法 go里面的文件操作封装在os包里面的File结构体中,要用的时候最好去查下官方文档,这里介绍下基本的文件操作。 打开关闭文件 import("os" ) func main() {// Open返回*File指针,后续的操作都通过*File对象操作…

Unsupervised Learning of Monocular Depth Estimation and Visual Odometry 论文阅读

论文链接 Unsupervised Learning of Monocular Depth Estimation and Visual Odometry with Deep Feature Reconstruction 0. Abstract 尽管基于学习的方法在单视图深度估计和视觉里程计方面显示出有希望的结果,但大多数现有方法以监督方式处理任务。最近的单视图…

归并排序总结

1.归并排序 归并排序的步骤如下: ①枚举中点,将区间分为左右两段; ②对左右两段区间分别排序; 这个过程以递归的方式进行。 ③合并两段区间。 是一个模拟的过程。用两个指针分别指向左右区间,判断当前哪个数小&…

FPGA——三速自适应以太网设计(2)GMII与RGMII接口

FPGA——以太网设计(2)GMII与RGMII 基础知识(1)GMII(2)RGMII(3)IDDR GMII设计转RGMII接口跨时钟传输模块 基础知识 (1)GMII GMII:发送端时钟由MAC端提供 下…

k近邻分类算法实现(KNN)

KNN算法实现 最近要用到对 某些数据进行自动识别分类,简单学习了一下k近邻算法,分享一下。 例如:电影动作片爱情片分类识别 这里我们使用了sklearn库,它用起来简单方便。 先提供代码如下: import numpy as np imp…

docker的简单使用

在一些进行使用靶场或者工具的时候,我们可以用docker在线拉取,就可以省去手动搭建靶场的过程 一、docker的配置 因为docker是默认从docker的官网进行拉取,所以拉取经常速度很慢或者失败,我们先要进行一下配置,让他优…

欧科云链:角力Web3.0,香港如何为合规设线?

在香港拥抱Web3.0的过程中,以欧科云链为代表的合规科技企业将凸显更大重要性。 ——据香港商报网报道 据香港明报、商报等媒体报道,港区全国政协兼香港选委界立法会议员吴杰庄在日前召开的全国两会上提出在大湾区建设国际中小企业创新Web3融资平台等提案&#xff0…