【数据库09】数据库系统体系结构 1

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【数据库09】数据库系统体系结构

1.概述

最早的数据库是在单台支持多任务的物理机器上运行的,这种集中式的数据库系统仍然在被广泛使用,如今在集中式数据库系统上运行的企业级应用可能拥有成千上万的用户,数据库的规模从兆字节到数百G字节不等。


并行数据库系统(paraller data system)是上世纪80年代末开始开发的,用在大量计算机上并行执行任务,它是为处理高端企业应用而开发的,用于在大量计算机并行执行任务。


并行数据存储系统(paraller data storage system)主要被设计用于存储和检索基于码的数据,与并行数据库不同,数据库存储系统通常对事务提供非常有限的支持,而且它们缺乏对声明性查询的支持。另外,这样的系统能够在非常多的机器(成千上万)上并行运行,这是大多数并行数据库无法处理的规模。


此外,数据通常在不同的数据库上生成和存储,从而需要跨多个数据库执行查询和更新事务,这导致了分布式数据库系统的发展。分布式数据库环境中开发的容错技术在确保大规模并行数据库和数据存储系统的可靠性和可用性。


2.集中式数据库系统

集中式数据库系统是运行在单个计算机系统上的系统,这些数据库系统应用很广,既有单用户系统,又有多用户系统。集中式数据库系统广泛应用于企业级应用。


使用计算机通常有两种方式:作为单用户系统和作为多用户系统。智能手机和个人电脑属于第一类。典型的单用户系统(single user system)是由单个人使用的系统,通常只有一个处理器(一般有多个核)、一个或两个磁盘。典型的多用户系统有多个磁盘、多个处理器和大量内存。这种系统为大量与远程用户连接的用户服务,因此被称为服务器系统(server system)


为单用户系统设计的系统一般不提供多用户数据库系统所提供的的许多功能,特别是,它可能只支持非常简单的并发控制方案,因为对数据库进行高并发访问基本是不太可能的。支持弱的故障恢复(更新前备份)或者不支持。可能不支持SQL,而是提供用于数据访问的API。因为通常被设计来链接到单个应用程序,只能从该应用程序访问,因此,这些系统被称为嵌入式数据库


多数据库系统支持之前章节学习到的全部事务特性,被称为服务器。


如今我们使用的大多数通用计算机系统都有几个多核处理器(通常是1-4个),每个多核处理器有几个核(通常是4-8个)。主存在所有处理器之间共享。具有这样少量的核和共享内存的并行被称为粗粒度并行(coarse-grained parallelism)


在单处理器系统上运行的操作系统支持多任务,允许多个进程以分时方式运行在同一个处理器上,因此,不同进程的动作可能是交错的。为单处理器机器设计的数据库长期以来一直被设计为允许多个进程或线程并发访问共享的数据库结构。因此,在处理真正并行运行的多个进程时的许多问题(例如对数据的并发访问)已经有为单处理器机器设计的数据库解决。其结果是,为分时的单处理器机器设计的数据库系统可以相对容易的在粗粒度并行系统上运行。


在粗粒度并行机器上运行的数据库通常不会尝试将单个查询划分给多个处理器,而是将每个查询运行在单个处理器上,允许多个查询并发执行。因此,这样的系统支持更高的吞吐量,也就是说,允许每秒运行更多的事务,尽管单个事务不会运行得更快。近年来,甚至连移动电话都开始支持多核,粗粒度并行系统也在不断演进,以支持对单个查询的并行处理。


细粒度并行(fine-grained parallelism)的机器拥有大量的处理器,在这类机器上运行的数据库系统视图对用于提交的单个任务(例如查询)进行并行化。


总的来说,并行性已经成为软件系统设计的一个关键问题,第4节将介绍并行数据库系统的体系结构。


3.服务器系统体系结构

服务器系统可以大致分为事务服务器和数据服务器。


3.1 事务服务器体系结构

事务服务器系统也被称为查询服务器,它提供接口,客户端通过向该接口发送请求来执行操作,服务器将执行结果返回给客户端。迄今为止,相对于数据服务器系统结构,事务服务器体系结构应用更加广泛。


当今典型的事务服务器系统有访问共享内存的多个进程组成,如下图,构成数据库系统的组成部分的进程包括。


服务器进程。该进程接收用户的查询(事务),执行结果并返回。查询可以来自用户视图或者运行嵌入式SQL的用户进程,也可以是通过JDBC或者ODBC将其提交到服务器进程。有些数据库对每个用户使用一个单独的数据库进程,有些数据库会对所有用户使用一个数据库进程,但是使用多个线程来让查询并发执行。许多数据库系统使用混合体系结构,具有多个进程、每个进程运行多个线程。

锁管理进程。实现锁管理功能,包括锁授予、锁释放和死锁检测。

数据库写进程。一个或者多个进程不断地将修改过的缓冲块输出到磁盘。

日志写进程。服务器进程会将日志简单的输出到日志缓冲区,如果需要强制输出日志,日志写进程会将日志记录从缓冲区输出到稳定的存储器。

检查点进程。定期执行检查点操作。(检查点:实现介质恢复时将以最近的checkpoint为执行事务前滚的参照点)

进程监控进程。

b4398beb820045b89895b4334b479cd4.png

共享内存包含所有的共享数据。

缓冲池

高速缓存的查询计划。它在同一个查询再次被提交时可以复用。

锁表。

日志缓冲区。包含待输出到稳定存储器上的日志记录。

由于多个进程可以访问数据库,必须设计一种机制确保互斥,即同一时刻最多有一个进程来修改共享内存中的数据结构,且当数据结构被写时不能有进程读。


可以通过操作系统的信号量实现互斥,但是使用计算机硬件所支持的原子操作指令(atomic instruction)开销更小。比如compare-and-swap或者test-and-set。


原子指令的实现机制一般是在cpu的互联网络中实现一个全局的原子寄存器,所有cpu对这个原子寄存器的访问是互斥的。cpu使用原子指令申请访问原子寄存器时,互联网络会对所有CPU进行仲裁,确保只有一个cpu可以获得对原子寄存器的访问权;如果有cpu获得了原子寄存器访问权,其他cpu必须等待该cpu释放权限才能继续执行。

原文链接:https://blog.csdn.net/qianniuwei321/article/details/124817265


注意原子操作指令可以用于互斥,但是这仅相当于支持排它锁,不支持共享锁,不能够直接用于实现数据库中通用的锁,但是原子操作指令可以用于实现短时间的锁,也称为闩(shuuan)锁,以用于数据库中的互斥。


共享锁与排它锁

1.共享锁,又称之为读锁,简称S锁,当事务对数据加上读锁后,其他事务只能对该数据加读锁,不能做任何修改操作,也就是不能添加写锁。只有当数据上的读锁被释放后,其他事务才能对其添加写锁。共享锁主要是为了支持并发的读取数据而出现的,读取数据时,不允许其他事务对当前数据进行修改操作,从而避免”不可重读”的问题的出现。

2.排它锁,又称之为写锁,简称X锁,当事务对数据加上写锁后,其他事务既不能对该数据添加读写,也不能对该数据添加写锁,写锁与其他锁都是互斥的。只有当前数据写锁被释放后,其他事务才能对其添加写锁或者是读锁。写锁主要是为了解决在修改数据时,不允许其他事务对当前数据进行修改和读取操作,从而可以有效避免”脏读”问题的产生。


为了避免消息传递带来的开销,许多数据库系统直接更新共享内存的锁表(锁表如下图),而不是向锁管理器进程发送锁消息。

079a313623fe4072b78f11b3cd081665.png

进程必须保证对锁表访问互斥,这通常是通过获取锁表上的互斥锁完成的,方法是在代表锁表的锁的内存位置上使用test-and-set或compare-and-swap指令。


通过直接更新共享内存中锁表的方式,可以按以下步骤执行希望获得锁的事务。

1.获取锁表上的互斥锁(闩锁)

2.检查是否可以分配请求的锁,如果可以,则更新锁表以表示已分配锁,否则,更新锁表以表示锁请求在该锁的队列中

3.释放表上的互斥锁。


如果由于锁冲突而无法立即获取锁,则事务可以定期读取锁表,检查是否有锁释放可以将锁分配给它。这个过程是:

1.获得锁表上的互斥锁

2.对于即将被释放的锁,从锁表中删除其记录项。

3.如果有任何其他挂起的锁请求该数据项,且锁可以分配给该请求,锁表将被更新以将这些请求标记为已分配。

4.释放表上的互斥锁。


为了避免对锁表进行不必要的重复检查,锁请求代码可以使用操作系统的信号量来等待锁授予的通知,然后,锁释放代码必须使用信号量机制通知等待事务其锁已经被授予。


即使系统是通过共享内存来处理锁的请求的,也仍然使用锁管理器进程进行死锁检测。


3.2 数据服务器与数据存储系统

数据服务器系统允许客户端以文件、页面或对象发送读取或更新数据的请求,从而与服务器进行交互。例如,文件服务器提供一个文件系统接口,客户端可以在其中创建、更新、读取和删除文件。同时,数据服务器系统提供对于小于文件大小的数据单元的支持,比如页面元组或者对象。还提供索引工具和事务工具,以保证数据在客户端或者进程故障时数据不会处于不一致的状态。数据服务器系统被广泛应用于处理网络规模的流量。


数据服务器最初是允许程序员使用面向对象数据库访问设计而开发的,面向对象允许程序员使用允许创建、检索和更新持久对象的编程语言。


面向对象数据库的许多目标应用都需要对检索到的设计软件进行大量的计算,比如CAD软件可以存储计算机芯片或者建筑物的模型,进行仿真等,这在CPU上的代价是很大的。


如果将所有计算都放在服务端,那么服务器就会过载。相反,这种情况下将数据存储在单独的数据服务器上,在需要时将数据提取到客户端,由客户端执行计算,将更新后的数据存储回服务器。


已经开发了许多并行数据存储系统来处理大量的数据和事务。这样的系统不必支持SQL,而是仅仅用于存储、检索和更新数据项的API。存储在此类系统的数据项可以是元组,也可以是JSON或XML等格式表示的对象,甚至可以是文件或文档。


我们使用术语数据项来指代元组、对象、文件或文档,也交替使用术语数据服务器和数据存储系统。


早期存储系统中的数据服务器支持页面传送,如今不再支持,因为存储系统不应该向客户端公开底层的存储布局。

3.3 客户端高速缓存

客户端与服务端通信相比本地内存引用的时间代价是很高的。


客户端可以采取优化策略来减少网络延迟(network-latency,指在网络上发消息得到响应的时间)的影响。数据库系统也可以采取同样的策略。


预取。当一个数据项被请求时,同时发送可能在不久的将来使用的其他数据项。

数据高速缓存。在单个事务范围内或者事务完成后,都可以将数据缓存在客户端。但是高速缓存一致性(cache coherecy)是一个值得关注的问题,可能服务器的数据已经被其他客户端更新了,而本地客户端与其不一致。

锁高速缓存。如果数据的使用主要是在客户端之间进行划分的,而客户端很少请求其他客户端也请求的数据项,可以将锁也在客户端高速缓存。假设客户端在高速缓存中找到一个数据项,并且它还找到访问该数据项所需要的锁,那么就可以在不与服务器进行任何通信的情况下继续进行该访问,但是服务器必须跟踪被高速缓存的锁,如果客户端向服务器请求锁,服务器必须从高速缓存该锁的任何其他客户端回调数据项上的所有冲突锁。如果考虑机器故障,此任务变得更加复杂。

自适应锁粒度。如果一个事务需要对事务中的多个数据项加锁,并且获取每个锁都需要与数据服务器进行往返通信,则该事务在锁的获取上会浪费大量时间。这种情况下可以使用多粒度锁来避免多重请求。例如,一个页面中存储了多个数据项,那么单个的页面锁较于多个数据项锁更敏捷。但是锁争用较多的情况下,获取粗粒度锁会显著影响并发度。锁降级是在出现高争用是自适应降低锁粒度的方式。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5月前
|
存储 安全 关系型数据库
|
6月前
|
SQL Oracle 关系型数据库
数据库SQL语言实战(四)(数据库系统概念第三章练习题)
本文的SQL语言适用的是Oracle数据库与mySQL可能存在略微不同
数据库SQL语言实战(四)(数据库系统概念第三章练习题)
|
6月前
|
存储 负载均衡 容灾
软件体系结构 - 关系数据库(4)分区
【4月更文挑战第27天】软件体系结构 - 关系数据库(4)分区
67 1
|
6月前
|
存储 SQL 缓存
软件体系结构 - 关系数据库(2)反规范化
【4月更文挑战第25天】软件体系结构 - 关系数据库(2)反规范化
119 1
|
6月前
|
存储 关系型数据库 MySQL
数据库期末考试基础——数据库系统概述
数据库期末考试基础——数据库系统概述
46 2
|
6月前
|
存储 SQL Oracle
【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数
【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数
112 7
|
6月前
|
SQL Oracle 关系型数据库
数据库SQL语言实战(五)(数据库系统概念第三章练习题)
本文的SQL语言适用的是Oracle数据库与mySQL可能存在略微不同
|
6月前
|
运维 负载均衡 监控
软件体系结构 - 关系数据库(3)主从架构
【4月更文挑战第26天】软件体系结构 - 关系数据库(3)主从架构
96 0
|
6月前
|
存储 数据库
软件体系结构 - 关系数据库(1)规范化
【4月更文挑战第24天】软件体系结构 - 关系数据库(1)规范化
73 0
|
6月前
|
存储 SQL 数据库
软件体系结构 - 架构风格(10)数据库系统架构风格
【4月更文挑战第21天】软件体系结构 - 架构风格(10)数据库系统架构风格
147 0