控制器里反复入队同一个对象会不会处理很多次?两个 worker 会不会同时处理同一个对象?失败了多久后重试,一直失败会怎样?这篇用 workqueue 包写 60 行代码,把去重、串行、退避的数字逐个打出来。
入队 101 次(100 次同一个 key + 1 个别的 key)后,队列长度 Len()=2 依次取出:default/web, default/db;取出后队列长度 Len()=0 default/web 还在处理中(没有 Done)时再 Add:Len()=0(不会马上入队,先记为 dirty) default/web 调用 Done 之后:Len()=1(之前的 Add 此刻才进入队列)
对同一个 key default/web 连续 Add 100 次,再 Add 一个 default/db:队列长度 Len()=2,重复的被合并;取出后 Len()=0。default/web 还在处理(没有 Done)时再 Add:Len() 仍是 0,先记为 dirty;调用 Done 之后 Len()=1,之前的 Add 此刻才进入队列。所以控制器队列里放的是 key(namespace/name),不是对象,处理时再去读缓存拿最新值。
4 个 worker 在 0.5 秒里不停地 Add "hot-key" 和另外 3 个 key:共处理 367 次;同一个 key 同时被处理的最大个数=1;所有 key 同时被处理的最大个数=4
4 个 worker 在 0.5 秒里不停地 Add "hot-key" 和另外 3 个 key:共处理 367 次,同一个 key 同时被处理的最大个数是 1,不同 key 同时被处理的最大个数是 4。控制器因此可以放心写 reconcile:同一个对象不会并发被处理,不同对象可以并行。
DefaultControllerRateLimiter 对同一个 key 连续失败 12 次的等待时间:[5ms 10ms 20ms 40ms 80ms 160ms 320ms 640ms 1.28s 2.56s 5.12s 10.24s];NumRequeues=12 Forget 之后再失败一次的等待时间:5ms;NumRequeues=1 单纯的指数退避(5ms 起,上限 1000s):[第10次=2.56s 第20次=16m40s 第30次=16m40s] 不同 key 互不影响:5 个新 key 的第一次等待时间:[5ms 5ms 5ms 5ms 5ms]
DefaultControllerRateLimiter 对同一个 key 连续失败 12 次的等待时间是 5ms、10ms、20ms、40ms、80ms、160ms、320ms、640ms、1.28s、2.56s、5.12s、10.24s(每次翻倍),NumRequeues=12;成功后调 Forget 把计数清零,下一次失败又回到 5ms。单纯的指数退避(5ms 起、上限 1000s):第 10 次 2.56s,第 20 次和第 30 次都是 16m40s,已经封顶。不同 key 各自计数,互不影响。
基础延迟 50ms 的限速队列:第 1/2/3 次 AddRateLimited 后 Get 阻塞了 50ms / 102ms / 202ms;NumRequeues=3 AddAfter(200ms):Get 阻塞了 200ms 才拿到 later;Forget 之后 NumRequeues=0
基础延迟 50ms 的限速队列:对同一个 key 第 1/2/3 次 AddRateLimited 后 Get 分别阻塞了 50ms / 102ms / 202ms,NumRequeues=3;AddAfter(200ms) 精确延迟 200ms;Forget 之后 NumRequeues=0。