数据库时多线程的
增加了性能
- throughput 吞吐量,针对多条指令的
- latency 单条的延迟
增加响应性(responsiveness)与可用性(availability)
TCO(total cost of ownership)总所有成本
很多数据库会把资源切开做成分布式的,分布式数据库有很多节点,但是当主机连接上分布式的某一个节点时,无论那个节点,得到的结果都是一样的(和单线程的数据库结果一样)
parallel DBMS(并行的数据库)distributed DBMS(分布式数据库)
parallel DBMS
- 存储都储存在一起
- 资源高速的通信
- 线程之间的通信是很简单且可靠的
distributed DBMS
- 节点之间有可能很远
- 中间通信会很慢, 也有可能经过互联网
- 节点之间通信的问题是要考虑的
agenda
- process model 线程模型
- execution parallelism 并发机制
- I/O Parallelism IO机制
process model 进程模型
worker逻辑上的工作者,例如线程
三个方向:
- process per DBMS worker
- process pool
- thread per DBMS worker
process per DBMS worker
每一个worker分配一个进程来做
依赖于操作系统来执行进程
进程与进程之间一般是用一个shared-memory
来进行通信
一个进程的crash不会让整个程序挂机
客户端发送请求给dispatcher,dispatcher把请求切成不同的工作分配给worker,再把结果返回给客户端,worker与数据库进行通信
如果工作量大就会产生很多的进程,进程的产生与消除有很大的浪费,所以产生了进程池思想
process pool
也是依赖操作系统调度系统,不利于catch
thread per worker
每个worker一个线程
DBMS自己实现调度,有时候用到了调度线程,一个线程的崩溃会导致整个系统崩溃
多线程有点就是线程切换比进程切换块
多线程就不用考虑内存共享分配
针对每一个执行计划,数据库要考虑到去哪里执行,什么时候执行和怎么执行
- 使用多少个任务
- 使用多少CPU资源
- 那些CPU执行那些任务
- 如何把分开的子任务组合起来
尽量用数据库自己控制这些操作
inter-query 不同的查询需要并发的执行
intra-query 一个查询不同线程之间的操作
inter-query
如果所有的操作都是只读的,冲突的协调是很少的
如果并发的操作是更新的话,就会产生并发控制的问题
intra-query
思想很像 producer/consumer 操作
成熟的数据库几乎每一个操作都有并发的版本
- 多个线程都去操作集中的总数据
- 将数据切开,用线程去操作
parallel grace hash join
用多个线程去处理不同坑的数据,因为已经分割好了
intra-query parallelism
内部并发工作
- intra-operator(horizontal 水平的)
- inter-operator(vertical 垂直的)
- bushy
horizontal
把数据切开,每个线程逻辑是一样的(并发进行),但是处理数据是不一样的,之后聚集
exchange operator 数据迁移
- gather 汇聚用的算子
- distribute 分配算子
- repartition 重分配的算子
结合起来就是:
三个并发线程做哈希表,再把哈希表结合起来,再和结果并发join,将结果再汇聚起来
inter-operator vertical
垂直切,下层代码处理完成一个数据之后立刻传给上层,进行并行操作,每一个算子用一个线程来操作,当然会产生等待的浪费
bushy 前两种的结合
一号算子做A join B,二号C join D,将结果内部切开,分给两个算子进行join,再将结果合并,就实现了二者的结合
如果面向磁盘的数据库,其实最大的问题是磁盘的IO
优化硬盘性能:
- I/O parallelism 将数据库切成不同的部分放入不同的硬盘,这时候并发存取就会不用抢占同一个盘来消耗时间
- multi-disk parallelism 存储级的应用磁盘阵列,将多个磁盘进行一些操作让数据库看上去使用一个盘,这个操作不是数据库来实现的,而是硬件及操作系统来实现的(RAID 0),缺点:坏一个磁盘就都坏了,RAID 1 就能解决这个缺点(多个盘存同样数据,有冗余)但并行读更简单
- database partitioning 记住将log file 共享
- partitioning 将一个表物理上分成不同的表,多个表可以并行操作
vertical partitioning 将一个表垂直切成两个表,(就是分成两个表,其中一个表存入不常用,也很大的数据)
horizontal partitioning 水平来一刀,当然最后两个表是按照一个特殊情况来分的,例如一个表示大于一个数据,另一个表存小于这个数据的表
当然还是有很多问题的
表在同一个节点可以分开,那么在不同节点也可以分开,这就是分布式数据库的由来