问题与目标

Last查询要对queryDataSource的过程加merge锁。

但由于当前last查询代码逻辑将获取queryDataSource的过程和扫描tsFile获取Last值的过程耦合在一起,在此过程中加锁会导致锁住的时间过长。

因此需要分离获取queryDataSource资源的过程和扫描tsFile文件的过程。


实现方案

在LastQueryExecutor.java中修改 calculateLastPairForSeriesLocally()方法,将整个代码逻辑划分为下列三个阶段:

  1. 遍历所有给定的时间序列,尝试获取所有序列在last cache中的值,存入到最终返回的resultContainer中,resultContainer的类型为List<Pair<Boolean, TimeValuePair>> 。

    Last缓存结果timeValuePair处理如下:

    • 得到有效的缓存结果,且满足last filter,则添加<true, timeValuePair>到resultContainer中。

    • 得到有效的缓存结果,但不满足last filter,则添加<true, null>到resultContainer中。

    • 得到无效的缓存结果,添加<false, null>到resultContainer中。

  2. 对于缓存未命中的时间序列,加merge锁,从queryResourceManager中获取seq文件和unseq文件资源。释放merge锁。

  3. 对于上述缓存未命中的时间序列,需要扫描tsFile并获取Last值。最后存入到resultContainer中。


对于所有访问Last cache的读写操作,在LastQueryExecutor.java中新增内部类LastCacheAccessor。提供用于读取cache的read()方法和用于写入cache的write()方法。


外部接口修改

外部模块如GroupByFillDataSet.java,会调用到LastQueryExecutor.java中calculateLastPairForOneSeriesLocally()方法,该方法用于找到某一个时间序列的last值。

按照上述方案重构之后,接口更改为calculateLastPairForSeriesLocally(),用来找到一个列表中的所有时间序列的last值。

  • No labels