论文学习:Low-Latency Transaction Scheduling via Userspace Interrupts:Why Wait or Yield When You Can Preempt?
数据库相关论文学习
论文学习:Low-Latency Transaction Scheduling via Userspace Interrupts:Why Wait or Yield When You Can Preempt?
Huang, Kaisong, et al. “Low-Latency Transaction Scheduling via Userspace Interrupts: Why Wait or Yield When You Can Preempt?.” Proceedings of the ACM on Management of Data 3.3 (2025): 1-25.
本文主要解决的问题:
本文主要解决了在混合长短事务和不同优先级的数据库负载下,传统非抢占式调度导致高优先级短事务延迟过高的问题。传统调度方式(如FIFO和协作式yield)无法及时响应高优先级事务请求,导致短事务等待长事务完成,延迟大幅增加。抢占式调度虽然理论上可以缓解,但由于软件中断延迟高和锁冲突导致的工作浪费,在数据库系统中很少被采用。
补充理解:
协作式yield的一个例子是 LevelDB 的 compaction 过程。LevelDB 在后台线程中执行 compaction 操作,这个过程可能会占用较长时间。如果 compaction 线程会在程序写死的固定位置主动检查当前是否存在 flush 操作,如果有,则暂停 compaction,切换到 flush 操作,完成后再继续 compaction。 </small>
本文insight:
- 抢占式调度在现代数据库系统中变得可行 传统观点认为数据库系统不适合抢占式调度,主要因为悲观锁(如两阶段锁)导致抢占时工作浪费和死锁风险。但现代内存优化型数据库普遍采用乐观并发控制和多版本机制,读操作无需持锁,因此抢占不会造成严重的工作浪费。
- 用户态中断(userspace interrupt)为低延迟抢占提供硬件支持 新一代 x86 CPU 支持用户态中断(uintr),可以在用户空间直接触发和处理中断,无需切换到内核态,极大降低了抢占延迟(实测低于1微秒)。
本文具体的解决方案:
- 利用现代 CPU 的用户态中断(uintr)机制,在用户空间实现高效的事务抢占,无需切换到内核态,极大降低了抢占延迟。
- 事务上下文切换机制:每个工作线程维护两个事务上下文(低优先级和高优先级),通过用户态中断触发上下文切换,将正在执行的低优先级事务挂起,立即处理高优先级事务,处理完后再恢复原事务。
- 事务控制块(TXCB):用于保存和恢复事务的执行状态(寄存器、局部变量等),保证事务可以在任意指令处被抢占和恢复。
- 透明的上下文本地存储(CLS)机制:解决多上下文下线程本地变量冲突问题,使数据库和依赖库无需修改即可安全支持抢占。(同一个工作线程可能因为中断执行多个不同的事务,事务之间如果使用相同的线程局部变量必然导致混乱,因此需要为每个事务维护独立的本地变量。本文用一个不执行的pthread的线程的本地变量存储一个事务的本地变量)
- 非抢占区机制:通过API标记关键代码段(如加锁、内存分配等)为不可抢占,防止死锁和数据一致性问题。
- 调度策略:包括批量抢占(稍微延迟批量化,一次处理一批高优先级事务)和饥饿预防(动态监控高优先级事务消耗的CPU周期,防止低优先级事务被长期饿死)。
本文由作者按照 CC BY 4.0 进行授权
