Skip to content
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

CloudJump: Optimizing Cloud Databases for Cloud Storages #28

Open
mrdrivingduck opened this issue Jul 28, 2024 · 7 comments
Open

CloudJump: Optimizing Cloud Databases for Cloud Storages #28

mrdrivingduck opened this issue Jul 28, 2024 · 7 comments

Comments

@mrdrivingduck
Copy link
Owner

mrdrivingduck commented Jul 28, 2024

拜读下现老板大作,货很干。

本地存储和云存储有着明显的不同。基于本地存储设计的数据库被搬到云存储上以后会有哪些问题,如何优化?

p3432-chen.pdf

@mrdrivingduck
Copy link
Owner Author

mrdrivingduck commented Jul 28, 2024

本文中云存储特指可以被多个数据库节点共享的弹性分布式块存储:

截屏2024-07-28 23 45 02

与本地 SSD 相比存在的挑战:

  1. I/O 延时高:因为需要通过网络访问远程的分布式存储
  2. 整体 I/O 带宽高:因为存储集群由多台机器组成,但数据库在设计上没有充分利用大带宽
  3. 为单机存储设计的 page cache 在云存储的多个数据库节点之间维护一致性开销很大
  4. 多种类型的数据库 I/O 操作之间隔离性较差(额,local SSD 是不是也有这个问题)
截屏2024-07-28 23 52 25

@mrdrivingduck
Copy link
Owner Author

线程级别并行写入 WAL 日志:

截屏2024-07-29 00 01 00

原先 WAL buffer 是全局的,因此写入 WAL 日志时线程间需要做同步。本文提出:

  1. 对 WAL buffer 根据 page ID 分多个区,那么线程向不同分区写入时是并行的
  2. 维护每个分区中的 LSN 边界
  3. 并行的 log writer 异步写入存储

Log writer 在写入日志时,会将每一个 WAL buffer 分区中的内容切成适合云存储的 I/O 大小的 slice 或做必要的补齐,然后同时发起多个异步 I/O 请求,将每一个 slice 打散写入到文件的不同 chunk 上。

截屏2024-07-29 00 20 51

@mrdrivingduck
Copy link
Owner Author

Prefetch:当第一个满足条件的 B-Tree 页面被定位时,其后续的兄弟页面有较大可能被需要,因此提前预取可以抹去云存储较高的 I/O 开销。

@mrdrivingduck
Copy link
Owner Author

锁粒度细化:由于云存储的访问延时高,因此持有锁的时间会变长,线程间同步开销更大。因此需要尽量让持有锁的粒度更细,最好能不加锁,这样所有线程可以最大程度并发。

  • Shadow page:将索引页面写入存储时,原先是在 I/O 过程中全程持有锁;优化后的思路是先对页面加锁,然后在内存中快速拷贝出一个 shadow page,然后立刻把锁释放掉;后续 I/O 线程把 shadow page 刷回存储就可以了,原先的页面在锁释放后可以继续被其它线程操作
  • 索引 SMO 时,parent 节点会加锁阻塞,另外索引上不允许并发的 SMO;优化后的思路是节点分裂过程中不对 parent 节点上排他锁,只对正在分裂的节点和新节点上排他锁;后续释放掉两个新节点的锁,然后重新从根节点开始锁到 parent 节点并使 parent 节点引用分裂出的新节点

@mrdrivingduck
Copy link
Owner Author

数据打散:在分布式存储中,分配 chunk 时放置在相同或不同的节点上有着不同的优势。放在相同节点上,则更省机器;放在不同的节点上,则利用了更多硬件资源,因此组合带宽更高。WAL 日志写入经过分片拆分后可以写入到多个节点上,从而最大化带宽利用。

@mrdrivingduck
Copy link
Owner Author

绕开为单机而设计的缓存:随着 RO 的数量越来越多,维护缓存一致性的代价也越来越高。索性绕开缓存,使用其它手段提升性能,从而使 RO 数量增大时数据库的性能能够 scale。

@mrdrivingduck
Copy link
Owner Author

基于优先级的 I/O 调度。数据库的四种主要的 I/O 类型:

  • 写日志:第一优先级,因为涉及到事务提交
  • 读数据:重要,影响查询性能
  • 写数据:可以 delay,慢慢刷脏
  • 读日志:只有 recovery 和 replication 的时候才会用到

由于存储层不识别 I/O 的类型,非重要的 I/O 可能会 delay 重要的 I/O。在数据库内需要根据不同类型的 I/O 有不同优先级的队列。

另外由于云存储的单次 block size 通常比 local SSD 要大,因此 I/O 请求发出时应该在数据库内被对齐。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant