【问题标题】:How to increase concurrent performance of Buffer Pool in database systems?如何提高数据库系统中 Buffer Pool 的并发性能?
【发布时间】:2017-11-08 16:21:51
【问题描述】:

在数据库系统教程中,像教科书数据库系统概念,有一个模块叫做缓冲池/缓冲管理器/寻呼机/任何东西。我没有看到它的太多细节,所以我很好奇你如何提高它的并发性能?

例如,假设我们有一个 Trie 索引。如果我们在 trie 内部进行分页,没有缓冲池,我们可以很容易地让多个线程同时加载或驱逐叶子节点:你需要做的就是从上到下获取节点的共享锁和独占锁。叶节点的父节点。

但是,如果您改为让缓冲池处理分页的事情,那么我想您可能需要获取缓冲池的排他锁。然后,只有一个线程可以同时加载或驱逐页面。

实际上,我已经在数据库实现中尝试过这个。旧版本没有缓冲池,在 trie 索引中管理分页的东西。并且新版本有一个缓冲池来完成这项工作,而不是 trie 索引本身。有一个大锁保护将 Page ID 映射到缓冲池中相应页面的 hashmap。单线程测试快 40%,但是,使用 10 个并发线程,慢 5 倍!

我猜无锁数据结构可能会有所帮助?但我也猜想这很难直截了当。那么你们是如何设计和实现缓冲池的呢?谢谢!

【问题讨论】:

    标签: database multithreading concurrency paging


    【解决方案1】:

    感谢the discussion here (in Chinese, sorry),我解决了这个问题。解决方案非常简单,只需对缓冲区管理器进行分片。通过对页码进行散列处理,将每个页面委托给一个分片。只要这个散列函数的结果是均匀分布,多个线程等待同一个锁的概率就会很低。

    在我的例子中,我将缓冲区管理器分为 128 个分片,哈希函数为 page_no % 128,有 10 个线程,一个简单的基准测试的结果看起来相当惊人:

    • 使用分片缓冲区管理器:7.73 秒
    • 使用缓冲区管理器:123 秒
    • 没有缓冲区管理器,即 trie 自己进行分页:19.7 秒

    顺便说一句,MySQL 似乎也采用这种方法(如果我误解了,请纠正我):https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-buffer-pools.html

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2011-01-01
      • 2010-09-13
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多