牛骨文教育服务平台(让学习变的简单)

这次还是以介绍TokuDB内部机制为主, 本篇来谈谈TokuDB内部的线程池模型。

TokuDB内部有一个线程池实现kibbutz, 代码: https://github.com/Tokutek/ft-index/blob/master/util/kibbutz.cc

其调度思想基于work-stealing, 代码也很简洁, 大体思路就是:维护一个任务队列, 空闲线程自己去这个队列领取任务。

kibbutz中文为“基布兹”,是以色列的一个集体社区,感兴趣的戳这里

TokuDB内部线程池按功能可以分为以下3大块:

节点“饱和”apply线程池

当一个节点“饱和”的时候,TokuDB需要把节点message buffer中的数据apply到子节点(这个行为是由TokuDB的特殊索引结构决定)。

这个线程池的作用是实现并发apply“饱和”节点,线程数目为物理CPU的个数。

缓存专用线程池

这个线程池专门为缓存服务,包括两大块:

a) 节点预读线程,比如做区间查找的时候,在某些条件下会触发子节点预读,提前在后台线程把节点读取到缓存。

b) LRU剔除线程,当缓存大小到达高水位的时候,后台线程把LRU尾端的脏节点刷到磁盘,并从LRU中清除。

这个池子里的线程数目较多,干的活也比较重,线程数目为物理CPU数*2。

checkpoint克隆线程池

这个线程池比较特殊。

做checkpoint的时候,如果一个节点处于“pin”状态,并且它是可克隆的,就使用后台线程把它的数据克隆出来并刷到磁盘,这样checkpoint可以继续进行下去(如果此节点不可克隆,checkpoint线程会一直等到这个pin状态结束)。

这个线程数为物理CPU数/4(如果CPU > 4)。

好的线程池设计+好的任务调度算法,应该是一个引擎高效的最基本条件,让任务尽量并行起来。