blob: ec8aaa27a9696bdb257623186a2be326aa1fa1ec [file] [log] [blame]
(window.webpackJsonp=window.webpackJsonp||[]).push([[946],{1510:function(a,e,s){"use strict";s.r(e);var t=s(69),n=Object(t.a)({},(function(){var a=this,e=a.$createElement,s=a._self._c||e;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h1",{attrs:{id:"最近时间戳-last-查询"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#最近时间戳-last-查询"}},[a._v("#")]),a._v(" 最近时间戳 Last 查询")]),a._v(" "),s("p",[a._v("Last 查询的主要逻辑在 LastQueryExecutor")]),a._v(" "),s("ul",[s("li",[a._v("org.apache.iotdb.db.query.executor.LastQueryExecutor")])]),a._v(" "),s("p",[a._v("Last查询对每个指定的时间序列执行"),s("code",[a._v("calculateLastPairForOneSeries")]),a._v("方法。")]),a._v(" "),s("h2",{attrs:{id:"读取mnode缓存数据"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#读取mnode缓存数据"}},[a._v("#")]),a._v(" 读取MNode缓存数据")]),a._v(" "),s("p",[a._v("我们在需要查询的时间序列所对应的MNode结构中添加Last数据缓存。"),s("code",[a._v("calculateLastPairForOneSeries")]),a._v("方法对于某个时间序列的Last查询,首先尝试读取MNode中的缓存数据。")]),a._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[a._v("try {\n node = MManager.getInstance().getDeviceNodeWithAutoCreateStorageGroup(seriesPath.toString());\n} catch (MetadataException e) {\n throw new QueryProcessException(e);\n}\nif (((LeafMNode) node).getCachedLast() != null) {\n return ((LeafMNode) node).getCachedLast();\n}\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br"),s("span",{staticClass:"line-number"},[a._v("6")]),s("br"),s("span",{staticClass:"line-number"},[a._v("7")]),s("br"),s("span",{staticClass:"line-number"},[a._v("8")]),s("br")])]),s("p",[a._v("如果发现缓存没有被写入过,则执行下面的标准查询流程读取TsFile数据。")]),a._v(" "),s("h2",{attrs:{id:"last标准查询流程"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#last标准查询流程"}},[a._v("#")]),a._v(" Last标准查询流程")]),a._v(" "),s("p",[a._v("Last标准查询流程需要遍历所有的顺序文件和乱序文件得到查询结果,最后将查询结果写回到MNode缓存。算法中对顺序文件和乱序文件分别进行处理。")]),a._v(" "),s("ul",[s("li",[s("p",[a._v("顺序文件由于是对其写入时间已经排好序,因此直接使用"),s("code",[a._v("loadChunkMetadataFromTsFileResource")]),a._v("方法取出最后一个"),s("code",[a._v("ChunkMetadata")]),a._v(",通过"),s("code",[a._v("ChunkMetadata")]),a._v("的统计数据得到最大时间戳和对应的值。")]),a._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[a._v("if (!seqFileResources.isEmpty()) {\n List<ChunkMetaData> chunkMetadata =\n FileLoaderUtils.loadChunkMetadataFromTsFileResource(\n seqFileResources.get(seqFileResources.size() - 1), seriesPath, context);\n if (!chunkMetadata.isEmpty()) {\n ChunkMetaData lastChunkMetaData = chunkMetadata.get(chunkMetadata.size() - 1);\n Statistics chunkStatistics = lastChunkMetaData.getStatistics();\n resultPair =\n constructLastPair(\n chunkStatistics.getEndTime(), chunkStatistics.getLastValue(), tsDataType);\n }\n}\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br"),s("span",{staticClass:"line-number"},[a._v("6")]),s("br"),s("span",{staticClass:"line-number"},[a._v("7")]),s("br"),s("span",{staticClass:"line-number"},[a._v("8")]),s("br"),s("span",{staticClass:"line-number"},[a._v("9")]),s("br"),s("span",{staticClass:"line-number"},[a._v("10")]),s("br"),s("span",{staticClass:"line-number"},[a._v("11")]),s("br"),s("span",{staticClass:"line-number"},[a._v("12")]),s("br")])])]),a._v(" "),s("li",[s("p",[a._v("乱序文件则需要遍历所有的"),s("code",[a._v("ChunkMetadata")]),a._v("结构得到最大时间戳数据。需要注意的是当多个"),s("code",[a._v("ChunkMetadata")]),a._v("拥有相同的时间戳时,我们取"),s("code",[a._v("version")]),a._v("值最大的"),s("code",[a._v("ChunkMatadata")]),a._v("中的数据作为Last的结果。")]),a._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[a._v("long version = 0;\nfor (TsFileResource resource : unseqFileResources) {\n if (resource.getEndTimeMap().get(seriesPath.getDevice()) < resultPair.getTimestamp()) {\n break;\n }\n List<ChunkMetaData> chunkMetadata =\n FileLoaderUtils.loadChunkMetadataFromTsFileResource(resource, seriesPath, context);\n for (ChunkMetaData chunkMetaData : chunkMetadata) {\n if (chunkMetaData.getEndTime() == resultPair.getTimestamp()\n && chunkMetaData.getVersion() > version) {\n Statistics chunkStatistics = chunkMetaData.getStatistics();\n resultPair =\n constructLastPair(\n chunkStatistics.getEndTime(), chunkStatistics.getLastValue(), tsDataType);\n version = chunkMetaData.getVersion();\n }\n }\n}\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br"),s("span",{staticClass:"line-number"},[a._v("6")]),s("br"),s("span",{staticClass:"line-number"},[a._v("7")]),s("br"),s("span",{staticClass:"line-number"},[a._v("8")]),s("br"),s("span",{staticClass:"line-number"},[a._v("9")]),s("br"),s("span",{staticClass:"line-number"},[a._v("10")]),s("br"),s("span",{staticClass:"line-number"},[a._v("11")]),s("br"),s("span",{staticClass:"line-number"},[a._v("12")]),s("br"),s("span",{staticClass:"line-number"},[a._v("13")]),s("br"),s("span",{staticClass:"line-number"},[a._v("14")]),s("br"),s("span",{staticClass:"line-number"},[a._v("15")]),s("br"),s("span",{staticClass:"line-number"},[a._v("16")]),s("br"),s("span",{staticClass:"line-number"},[a._v("17")]),s("br"),s("span",{staticClass:"line-number"},[a._v("18")]),s("br")])])]),a._v(" "),s("li",[s("p",[a._v("最后将查询结果写入到MNode的Last缓存")]),a._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[a._v("((LeafMNode) node).updateCachedLast(resultPair, false, Long.MIN_VALUE);\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br")])])])]),a._v(" "),s("h2",{attrs:{id:"last-缓存更新策略"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#last-缓存更新策略"}},[a._v("#")]),a._v(" Last 缓存更新策略")]),a._v(" "),s("p",[a._v("Last缓存更新的逻辑位于"),s("code",[a._v("LeafMNode")]),a._v("的"),s("code",[a._v("updateCachedLast")]),a._v("方法内,这里引入两个额外的参数"),s("code",[a._v("highPriorityUpdate")]),a._v("和"),s("code",[a._v("latestFlushTime")]),a._v("。"),s("code",[a._v("highPriorityUpdate")]),a._v("用来表示本次更新是否是高优先级的,新数据写入而导致的缓存更新都被认为是高优先级更新,而查询时更新缓存默认为低优先级更新。"),s("code",[a._v("latestFlushTime")]),a._v("用来记录当前已被写回到磁盘的数据的最大时间戳。")]),a._v(" "),s("p",[a._v("缓存更新的策略如下:")]),a._v(" "),s("ol",[s("li",[a._v("当缓存中没有记录时,对于查询到的Last数据,将查询的结果直接写入到缓存中。")]),a._v(" "),s("li",[a._v("当缓存中没有记录时,对于写入的最新数据如果时间戳大于或等于"),s("code",[a._v("latestFlushTime")]),a._v(",则将写入的数据写入到缓存中。")]),a._v(" "),s("li",[a._v("当缓存中已有记录时,根据查询或写入的数据时间戳与当前缓存中时间戳作对比。写入的数据具有高优先级,时间戳不小于缓存记录则更新缓存;查询出的数据低优先级,必须大于缓存记录的时间戳才更新缓存。")])]),a._v(" "),s("p",[a._v("具体代码如下")]),a._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[a._v("public synchronized void updateCachedLast(\n TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime) {\n if (timeValuePair == null || timeValuePair.getValue() == null) return;\n \n if (cachedLastValuePair == null) {\n // If no cached last, (1) a last query (2) an unseq insertion or (3) a seq insertion will update cache.\n if (!highPriorityUpdate || latestFlushedTime <= timeValuePair.getTimestamp()) {\n cachedLastValuePair =\n new TimeValuePair(timeValuePair.getTimestamp(), timeValuePair.getValue());\n }\n } else if (timeValuePair.getTimestamp() > cachedLastValuePair.getTimestamp()\n || (timeValuePair.getTimestamp() == cachedLastValuePair.getTimestamp()\n && highPriorityUpdate)) {\n cachedLastValuePair.setTimestamp(timeValuePair.getTimestamp());\n cachedLastValuePair.setValue(timeValuePair.getValue());\n }\n}\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br"),s("span",{staticClass:"line-number"},[a._v("6")]),s("br"),s("span",{staticClass:"line-number"},[a._v("7")]),s("br"),s("span",{staticClass:"line-number"},[a._v("8")]),s("br"),s("span",{staticClass:"line-number"},[a._v("9")]),s("br"),s("span",{staticClass:"line-number"},[a._v("10")]),s("br"),s("span",{staticClass:"line-number"},[a._v("11")]),s("br"),s("span",{staticClass:"line-number"},[a._v("12")]),s("br"),s("span",{staticClass:"line-number"},[a._v("13")]),s("br"),s("span",{staticClass:"line-number"},[a._v("14")]),s("br"),s("span",{staticClass:"line-number"},[a._v("15")]),s("br"),s("span",{staticClass:"line-number"},[a._v("16")]),s("br"),s("span",{staticClass:"line-number"},[a._v("17")]),s("br")])])])}),[],!1,null,null,null);e.default=n.exports}}]);