-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Volcano - An Extensible and Parallel Query Evaluation System #9
Comments
这是一篇深刻影响现代 DBMS 设计的论文。Volcano 严格来说不算一个 DBMS,而是一个查询执行系统,因为其中并没有用户友好的 UI、查询语言、类型系统、优化器、catalog 等。Volcano 完成了以下设计特性:
|
Volcano System DesignVolcano 包含两层:
The File System缓冲区管理器只提供 mechanism,比如保持页面、读写 disk page 等;而更高层的软件根据数据的敏感性、重要性、访问模式来决定如何使用这些 mechanism 的 policy。Volcano 中大量使用了这种 mechanism 和 policy 分离的设计策略,从而实现高度的模块化。 文件系统的扫描实现了两套接口。其中一套是标准的文件扫描接口:open、next、close、rewind,为了快速创建文件,还实现了 append。另外,扫描还支持可选的 predicate 函数——由返回下一条记录的 next 调用,并传入参数和记录地址。Predicate 的 support function 以函数指针的方式传递给算子,算子本身并不关心其中具体的逻辑,从而实现了更好的扩展性。 传递给 support function 的参数可以以两种方式被使用:
编译执行和解释执行被实现在了单一的 mechanism 中,由上层 policy 决定使用编译执行还是解释执行。这里又体现了 mechanism 和 policy 分离的设计思想。 Query Processing在 Volcano 中,所有的代数物理算子(与逻辑算子相区分)都被实现为 迭代器模式:它们遵循包含 open-next-close 三个操作协议。分别对应了:首先进行初始化,然后进行循环和递增直到到达循环结束条件,最终进行收尾的三个过程。与每个迭代器相对应的是一个 state 记录,包含了 open 操作中需要用到的参数和状态。 所有对数据对象进行操作和解释的功能都以函数指针的形式提供给物理算子,具体逻辑实现在 support function 中。每个 support function 使用一个参数来标识是进行解释执行还是编译执行。 迭代器(算子)之间可以嵌套,从而以类似子函数的方式被使用。对应地,state 记录也需要通过孩子指针链起来。 使用这种标准的迭代器接口,Volcano 的算子不需要知道它的下层算子是什么类型的,下层算子的记录是如何产生的,只需要调用下层算子的 next 函数即可。这种概念被称为 anonymous inputs 或 streams。Streams 是一个简单但强大的抽象,可以使任意数量和种类的算子节点组合起来,从而执行一个复杂的查询。这是本文提供的核心执行模型。 从最顶层的算子开始调用 一些和查询与环境相关的参数可能会影响 综上,通过将算子实现为迭代器,实现了对树形的查询计划的需求驱动(demand-driven)查询。 |
Dynamic Query Evaluation Plans查询优化器需要对系统中可用资源进行估算,最终查询计划的优劣性直接受估算准确性的影响。Volcano 提供了一个可以避免优化器不准的方法:动态查询计划选择。 在 Volcano 中,引入了一个也被实现为迭代器模式的 choose-plan 算子,它不会对数据有任何操作,所以是一个 meta 算子。该算子的 对上面这张图来说,索引扫描和文件(顺序)扫描在查询不同变量时速度不一样。当索引非聚簇,且选择率较高(一大堆行将会被返回)时,顺序扫描速度更快,否则索引扫描更快。优化器可以为这两种情况准备不同的执行计划,在查询执行时动态选择不同的查询计划可以在两种场景下都收获不错的性能。 Choose-plan 算子虽然能够实现计划的动态选择,但它并不关心具体选择哪个计划,而是直接调用实现了计划选择 policy 的 support function,因此算子本身只提供了 mechanism。这也是 mechanism 和 policy 分离设计的一个体现。 |
Multiprocessor Query Evaluation关系型查询处理系统中能够相对容易使用并行的主要原因:
Volcano 的目标是不修改所有已有的单进程查询处理代码,所有的并行化问题都在一个提供标准迭代器接口的算子内解决,该算子在 Volcano 中被称为 exchange 算子。由于实现了标准的迭代器接口,因此这个算子可以被插入在计划树的任何位置上: Vertical Parallelism所谓垂直并行即进程间的流水化。Exchange 算子的第一个功能就是提供垂直并行能力。算子的 消费者进程中的 exchange 算子也是一个迭代器,唯一的不同是它获取数据的来源是不是递归调用下层迭代器,而是来自进程间通信。当消费者的 生产者进程中,exchange 算子负责驱动在其之下的计划树算子的 通过一个额外的信号量,生产者和消费者之间可以做到流量控制 / 背压。当生产者明显快于消费者时,为了防止共享内存 buffer pool 中过多的记录被锁定,在生产者产生一个数据包后,必须等到消费者将数据包消费完后释放信号量,生产者才可以继续产生下一个数据包。信号量的数值决定了生产者可以领先消费者多少个数据包。 Horizontal Parallelism所谓水平并行分为两类:
Bushy parallelism 能够通过在计划树中插入 exchange 算子轻易实现。 算子内并行需要实现数据分区,是通过使用多个文件实现的。中间结果的分区是通过在 port 中分配多个队列实现的,如果有多个消费者进程,那么它们使用 port 中各自的队列。对于生产者来说,它们使用 support function 来决定把记录输出到哪一个队列中。Support function 的引入意味着可以实现轮转分区、key 值范围分区或 hash 分区。 水平并行需要的条件:在 exchange 算子的 state 中需要有 degree of parallelism,并且还需要提供 support function 来决定把扫描结果发送到哪个进程。如果一个进程组执行同一个算子,那么当计划树被 当 Variant of the Exchange Operator在一些场景中,生产者需要将输出广播给所有消费者。 Exchange 中的输入记录可以根据它们的生产者而分开存放,从而实现 merge。 |
graefe-ieee1994.pdf
Goetz Graefe 发表于 1994 年的文章,介绍了 DBMS 的 迭代器执行模型 (iterator model) 和一种可扩展的 并行执行模型。
The text was updated successfully, but these errors were encountered: