bcache后端设备attach到cache设备时会启动一个writeback线程和一个更新writeback速度的定时任务(更新周期writeback_rate_update_seconds默认值5s)。
在刷脏线程中,遍历writeback_keys(红黑树,按key排序),一次最多将5个脏key写入后端盘,完成后休眠加一个delay。刷脏的快慢通过这个delay值来控制。
在解绑或者writeback_percent设置成0的时候,计算出的delay值为0,此时刷脏速度不受控。其他情况下,根据刷掉的脏数据大小和刷脏速率计算下次刷脏的时间。
刷脏速率通过PI控制算法计算,误差值error为当前脏数据dirty与目标脏数据target的差值,目标是让脏数据与目标值一致。
error(t) = dirty(t) -target(t)
首先引入比例控制,即让刷脏速度u(t)与误差error(t)成一定的比例,误差越大刷得越块。
u(t)=Kp*error(t)
比例控制器的作用是对偏差瞬间做出反应,偏差一旦产生控制器立即产生作用,使其控制量朝减少偏差的方向变化,当Kp值较大时,系统响应快,但也容易出现震荡,Kp较小时,系统响应慢,并且当目标值比较接近时,比例的作用非常有限。引入积分控制,对累积的误差进行调节。
writeback_rate_p_term_inverse默认值为40、writeback_rate_i_term_inverse为10000,即Kp=1/40、Ki=1/10000。