timingwheel icon indicating copy to clipboard operation
timingwheel copied to clipboard

TimingWheel中currentTime和overflowWheel变量存在竞争问题

Open juine opened this issue 4 years ago • 3 comments

TimingWheel结构体中currentTime变量同时为多个goroutine访问,其中 add方法是只读,addvanceClock则是先去读currentTime变量,再判断,然后写入。使用了atomic只保证了读写currentTime变量那一个操作原子化,但是advanceClock则是先读再判断最后再写入, 会与add函数发生竞争,同理overflow变量也是一样好。粗略看了一下,kafka源码里面采用了是读写锁临时保护了这些变量

juine avatar Jan 18 '21 09:01 juine

确实是这样,kafka源码中的注释也提到了advanceClock和add不能同时调用,具体实现的方式就是读写锁

yunlong0928 avatar Feb 23 '21 02:02 yunlong0928

使用了atomic只保证了读写currentTime变量那一个操作原子化,但是advanceClock则是先读再判断最后再写入, 会与add函数发生竞争,同理overflow变量也是一样好。

@juine @yunlong0928 两位好!请问具体是什么竞争,以及会导致什么问题,方便具体描述下吗?

RussellLuo avatar Feb 18 '22 14:02 RussellLuo

TimingWheel结构体中currentTime,当add方法和addvanceClock方法并发时,存在如下这种竞争情况:add方法执行完atomic.LoadInt64(&tw.currentTime)后addvanceClock方法使用atomic.StoreInt64(&tw.currentTime, currentTime)改变了currentTime,致使add方法关于t.expirationcurrentTime+tw.tick大小的判断出现问题。 https://github.com/RussellLuo/timingwheel/blob/54845bda31084d50d98d83afb01bd89d48154668/timingwheel.go#L68-L88 除非确保advanceClock方法和add方法不同时调用 详见yunlong0928:master

M6ZeroG avatar Mar 14 '22 01:03 M6ZeroG