Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Schema和历史resource单独分配大小;下文仅考虑其余写数据部分大小。
  • 每个SG统计自身的chunk_metadata和unseal_resource大小;
  • 全局ArrayPool统计buffered和out of buffer的array大小
  • 系统统计总的大小


写入线程

  1. 如果是非空的写入线程
    • 在 StorageEngine 中检查SystemInfo是否为reject状态;如果是,则该写入线程循环sleep 100ms(等待flush线程释放内存,system置回正常状态)再进行写入;如果等待6000ms后仍为reject状态,抛出写入异常;
    检查SystemInfo是否为reject状态;如果是,则该写入线程循环sleep 100ms 等待flush线程释放内存,system置回正常状态再进行写入;如果等待6000ms后仍为reject状态,抛出写入异常;
    • 进入对应的StorageGroupProcessor,获取 writeLock
    • 进入对应分区的 TsFileProcessor:(1)获取已有的可写入的顺序或乱序 TsFileProcessor(2)如果没有可写入的TsFileProcessor,创建新的 TsFileProcessor
      • 统计当前写入计划新增的内存占用,增加至TspInfo和SgInfo中:(1)新测点增加 chunk_
  2. metadata(2)新设备增加 unclosed resource(3)TEXT 类型数据(4)
      • metadata(2)TEXT 类型数据(3)TVList 中增加的
  3. PrimitiveArray(5)flush内存
      • PrimitiveArray(4)flush内存
      • 如果 SGInfo 增量超过阈值(storage
  4. 如果SGInfo变化超过System 上报的阈值(storage
      • _group_size_report_threshold=16M)
      • 向SystemInfo进行上报;
            • 向SystemInfo进行上报(将当前 TsFileProcessor 传入);
              synchronized(SystemInfo) {
              • 更新 SystemInfo 内存占用。
              • 如果 SystemInfo 内存占用 < 总写入内存 * flush_proportion,返回 true。
              • 如果 总写入内存 * flush_
      • proportion <=
              • proportion ≤ SystemInfo 内存占用 < 总写入内存 * reject_proportion, 执行 写入线程的提交flush流程,返回 true。
              • 如果 总写入内存 *
      • 80% <=
        }
              • reject_proportion ≤ SystemInfo 内存占用, SystemInfo 置为 reject
      • 状态,触发flush,返回 false。
              • 状态, 执行 写入线程的提交flush流程,记返回值为 flag
                • 如果 flag = true 
                  • 如果 SystemInfo 内存占用 < 总写入内存,则返回 true
                  • 如果 SystemInfo 内存占用 ≥ 总写入内存,直接抛 写入Reject 异常
                • 如果 flag = false,则返回 false
                  }
            • 判断 向SystemInfo上报 的返回结果
              • 如果返回 false,则该写入线程循环 writeLock.condition.await(50ms) ,检查 SystemInfo 的 reject 状态如果不 reject,执行正常写入。如果等待 max_waiting_time_when_insert_blocked 后仍为reject状态,抛出写入异常
              • 如果返回 true,则执行正常写入
              • 如果捕获到 写入Reject 异常,reset SystemInfo,并继续向上抛
        • 在 StorageGroupProcessor 里检查 shouldFlush,如果为true,进行异步flush过程
        • StorageGroupProsessor. 释放writeLock
      • 如果是空的写入线程
        • 进入对应的 StorageGroupProcessor,获取 writeLock
        • 获取对应分区的 TsFileProcessor:如果(其 workingMemtable 不为空且 shouldFlush 为 true),则提交 flush 任务;否则直接返回。
        • StorageGroupProsessor. 释放writeLock


    Flush流程:

    flush 分为两种 一种为正常flush,为写入过程中触发,在insertPlan写入完成后正式开始进行异步flush(正常写入流程中flush);另一种为异步即时flush,即触发后立刻开始flush(flush释放内存后,若System总内存仍处于flush阈值之上且当前没有flush任务时触发)

    写入线程的提交flush流程:

    1. 获取整个系统当前正在 Flush 的线程个数,如果大于 0,就返回
    2. 使用 PriorityQueue 对当前 TsFileProcessor 占用内存由大到小排序,逐个标记 shouldFlush,直到标记的这些 TsFileProcessor 刷盘后内存能降到 flush 阈值的50%

    Flush 线程的提交flush流程:

    写入线程的提交flush流程

    1. 使用 PriorityQueue 对当前系统所有 memtable 按占用内存由大到小排序
    2. boolean flag = false
    3. 当前活跃内存 = SystemInfo 总内存 - SystemInfo flush内存
    4. 对 PriorityQueue 的每个 workingMemtable 逐个标记 shouldFlush,(直到标记的这些 TsFileProcessor 刷盘后 当前活跃内存 能降到 flush 阈值之下)
      1. 提交一个异步的空的写入线程(写入被标记的 Memtable 中)
      2. 判断此 workingMemtable 是否属于当前 TsFileProcessor,如果属于,flag = true
    5. 返回 flag


    Flush 流程:

    1. 先更新 SystemInfo flush 内存
    2. 将 workingMemtable 移到 flushingMemtables 中
    3. 获取整个系统当前正在 Flush 的线程个数,如果大于 1,就返回
    4. 通过上报到system里的sgInfo,找到所有的TSP;
    5. 使用PriorityQueue pop出当前workMemTable内存占用最大的Top K个TSP,进行异步flush;如果flush此memtable后系统仍在flush阈值以上,再从PriorityQueue pop出一个TSP进行异步flush,直到这些memtable flush后会回到flush阈值一下或者PriorityQueue为空


    关闭TsFile文件逻辑:

    文件封口触发逻辑与现有master版本相同,都为一个insertPlan写入完成后,检查该TSP是否需要flush,如果需要,再检查是否TsFile大小超过阈值,如果超过,flush memtable后将文件封口。

    ...