timingwheel
timingwheel copied to clipboard
TimingWheel中currentTime和overflowWheel变量存在竞争问题
TimingWheel结构体中currentTime变量同时为多个goroutine访问,其中 add方法是只读,addvanceClock则是先去读currentTime变量,再判断,然后写入。使用了atomic只保证了读写currentTime变量那一个操作原子化,但是advanceClock则是先读再判断最后再写入, 会与add函数发生竞争,同理overflow变量也是一样好。粗略看了一下,kafka源码里面采用了是读写锁临时保护了这些变量
确实是这样,kafka源码中的注释也提到了advanceClock和add不能同时调用,具体实现的方式就是读写锁
使用了atomic只保证了读写currentTime变量那一个操作原子化,但是advanceClock则是先读再判断最后再写入, 会与add函数发生竞争,同理overflow变量也是一样好。
@juine @yunlong0928 两位好!请问具体是什么竞争,以及会导致什么问题,方便具体描述下吗?
TimingWheel结构体中currentTime,当add方法和addvanceClock方法并发时,存在如下这种竞争情况:add方法执行完atomic.LoadInt64(&tw.currentTime)后addvanceClock方法使用atomic.StoreInt64(&tw.currentTime, currentTime)改变了currentTime,致使add方法关于t.expiration 和 currentTime+tw.tick大小的判断出现问题。
https://github.com/RussellLuo/timingwheel/blob/54845bda31084d50d98d83afb01bd89d48154668/timingwheel.go#L68-L88
除非确保advanceClock方法和add方法不同时调用
详见yunlong0928:master