JingsongLi commented on PR #6426:
URL: https://github.com/apache/paimon/pull/6426#issuecomment-4850904892

   看了当前 head `cec7398932a21b2cc5a3a4e95e4e5040d9514fc9`,我的判断是:这个方向确实可以做异步优化,默认 
`dynamic-bucket.empty-bucket-threshold = -1` 
也让风险面默认关闭;但当前实现还不能确认线程安全和内存/backpressure 都可控,建议先修下面几个点再合。
   
   1. `PartitionIndex.assign` 里对 `nonFullBucketInformation` 的更新仍然是 
read-modify-write:先从 iterator 读 `number`,再 `entry.setValue(number + 1)`。后台 
refresh 同时会在 `reconcileBucketWithDisk` 里 `compute` 同一个 bucket。两者交错时,主线程可能覆盖已经 
reconcile 后的值;更严重的是主线程在 bucket 满时 `iterator.remove()` 并删除 
`diskRowCountAtLastRefresh`,慢 refresh 回来后可能用 `inMemory == null ? diskNow` 把当前 
checkpoint 的 in-flight 增量丢掉,导致已满 bucket 又被当作 non-full。这里最好把 assign 侧也改成基于 
`compute`/CAS 的原子更新,避免 `entry.setValue` 覆盖异步 reconcile。
   
   2. `totalBucketSet` 仍然是 `LinkedHashSet`。主线程创建 bucket 时会写 `totalBucketSet` / 
`totalBucketArray`,后台 refresh 在 `reconcileBucketWithDisk` 里读 
`totalBucketSet.contains(bucket)`。这是普通集合的跨线程读写 data race。可以考虑 refresh 启动时复制一个 
owned-bucket snapshot,或者把这部分结构改成明确的并发容器/同步边界。
   
   3. `lastRefreshTime` 由后台线程写、assign 线程读,但不是 `volatile`,`min-refresh-interval` 
的可见性不可靠。这个至少应该改成 `volatile`,或和 `refreshFuture` 的状态更新放进同一个同步/原子流程里。
   
   4. 内存/backpressure 目前只能说“部分可控”,不能说严格有界。每个 `PartitionIndex` 最多保留一个 
`refreshFuture`,运行中的 refresh 并发度受全局 `FileOperationThreadPool` 线程数限制,这是好的一面;但 
`FileOperationThreadPool` 底层默认是无界 `LinkedBlockingQueue`。如果很多活跃分区同时 
near-full,排队的 refresh task 数没有硬上限。每个运行中的 refresh 还会持有 `scanEntries` 结果和 
`tempBucketInfo`,运行中并发有限,但单个大分区扫描的临时内存仍可能比较大。
   
   所以我认可异步 refresh 的优化目标,但这版还不能直接说“没有线程安全问题,且内存问题可控”。建议补一个并发交错测试/压力测试,覆盖 assign 
与 reconcile 同时更新同一 bucket、bucket remove 后慢 refresh 回写、以及大量分区同时触发 refresh 的场景。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to