THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
...
缺点:以单个TsFileResource作为缓存管理的粒度,缓存的开销比方案1要大
可以考虑实现这种方案,TsFileResourceManager需要实现的接口为
- 标记某一批TsFileResource被读取了
- 添加新的TsFileResource,例如创建和merge
- 升级一批TsFileResource.(什么条件升级)
- 如果因为索引问题导致的误读而访问tsfile,那还是要升级,因为老是误读,因此升级是合理的。
- 为了防止全表扫描污染缓存,则需要加点逻辑来防止这种情况。例如如果一个文件如果是文件级的索引,在一段时间内被访问次数超过一个阈值就升级它。
- 移除旧的TsFileResource,例如删除和merge
TsFileResourceManager的主要逻辑:
- 初始化,从磁盘中按时间戳逆序来构建TsFileResource缓存
- 升级TsFileResource,从磁盘中读取TsFile构建设备级索引
- 降级TsFileResource,将内存中的TsFileResource的索引改成文件级
- 筛选TsFileResource进行升级或降级
- 升级,上层调用标记TsFileResource被访问后,检查这些TsFileResource如果是文件级的索引,并且在一段时间内被访问次数超过一个阈值就升级它。
- 降级,添加新的TsFileResource或者标记某些TsFileResource被访问后,替换掉最近最少使用的设备级的TsFileResource
TsFileResourceManager的主要辅助成员:
- LRU cache,不对外公开,存放的都是设备级的TsFileResource,主要用来判断哪些最近被访问,
- Map<TsFileResource, Pair<lastCheckTime, queryCount>> waitUpgradeTsFileResource, 不对外公开,key是文件级索引的TsFileResource, value是一个数据结构,该结构主要有两个字段,lastCheckTime是该TsFileResource上次被访问的时间,超过某个阈值(例如1min)就重新设置为当前时间,queryCount也清零。queryCount是自上次被访问的时间以来被访问的次数。筛选时,如果某个文件级的TsFileResource自上次被访问时间以来,queryCount累计超过阈值(例如5),就升级它。
- 有可能某段时间所有的TsFileResouce都访问得比较频繁,设备级的的TsFileResource比文件级的TsFileResource更频繁,但是依然会被替换掉。
方案1 & 方案2有个共同的优点,可以复用MTree那边缓存的实现逻辑
...