北京儿童插座价格联盟

【技术分享】华胜信泰李海翔:数据库引擎技术架构

只看楼主 收藏 回复
  • - -
楼主

本文整理自SACC2016主题演讲内容,如需转载,请先联系本公众号获取授权!

演讲嘉宾

李海翔

华胜信泰数据库架构师


网名“那海蓝蓝”, 从事数据库研发、数据库架构、数据库技术管理等工作10余年; 历任人北京大金仓研发中心多个项目的技术经理、测试部经理、测试中心总监; Oracle公司MySQL全球开发组Optimizer Team的核心开发人员; 现任北京华胜信泰数据技术有限公司,数据库架构师。


分享内容


今天和大家分享的内容主要有4个方面,第一个是数据库的整体框架,第二个是数据库的前端架构,第三个是数据库的扩展架构,第四个是大家比较关心的集群架构。



前端结构主要包括三个方面,第一是连接协议,第二是面向连接的服务器架构,主要包括多进程、多线程和多协程,第三部分是安全防范。上周美国发生了大规模的Dos攻击,所以我们在这里也谈谈数据库怎么防止DOS攻击。


数据库的整体架构我们主要跟大家分享数据库的执行过程以及事务管理和并发控制技术。


扩展架构里面主要谈论PostgreSQL、MySQL和Informix的扩展。


集群架构主要是谈高可用集群、高可靠高可用集群以及大家所熟悉的分布式数据库的三条路。



数据库的前端架构,如上图所示主要分为两个部分,第一个部分是数据库服务器,第二部分包括两部分,一个是应用,另一个是驱动程序,且如上图面向不同的语言有不同的驱动程序。



在这样的架构中,数据库服务器稍加演变就变成了一个应用,或者说它是在数据库之上的一个数据库管理工具,数据库管理工具和应用是在一个层面上的,它们和数据库服务器交互靠的就是驱动程序,如我们熟悉的TCP/IP协议。有了这一层次之后(这一层指的是驱动程序),驱动程序和数据库服务器是如何交互的呢? 这就需要通讯协议,通讯协议在驱动程序和数据库服务器之间,不同的数据库有不同的通讯协议(格式不同,有简单命令方式的、有简单字符标示的等等)。


数据库应用为了提高整体效率,常用的技术就是连接池。连接词通常出现在应用和DB Tools之间(如上图右下角,标有连接池的方框表明的连接池所处的位置),但是连接词不仅仅可以出现在这个地方,还可以出现在驱动程序里面。举个例子, PostgreSQL在JDBC驱动程序里面就内嵌了一个连接池。(可以通过配置PostgreSQL的JDBC来使用JDBC内置的连接池)。另外,连接池还可以出现在DB Server这一层,如在MySQL的Server层增加连接池以应对互联网常用的秒杀场景。这是和连接池相关的内容,在实践中,需要根据实际情况灵活运用。



多于多进程架构的数据库系统而言,为了响应或者提高用户的连接,通常数据库引擎里面会有一个监听器,它会不断的fork直至进程出现,然后由一个进程去响应一个用户连接,如果有10个用户连接,那么就需要有10个进程。


这种做法有一个弊端,就是当我们计算机资源有限时,fork出的进程也是有限的,如何解决这个问题呢?MySQL同样有一个监听进程,每当一个新的连接来临,监听进程就去创建一个线程,线程占的资源相比进程要少,这样相对来讲就能创造更多的线程来响应客户连接。


但是,这种做法还是治标不治本,在计算机资源有限的情况下,创建的进程或线程的个数同样是有限的,那么这个时候该怎么办呢?


Informix有一个非常好的技术叫做虚拟进程。虚拟进程本质上利用了协程的实现技巧。协程这个概念在很多语言中都得到了体现,如C语言、GOLang语言。但是在Informix数据库里面,虚拟进程和共享内存相结合,然后可以创建出无数个程序段,程序段对应用户连接,如果一个进程中可以创建无数个程序段,那么我们就可以建立无数个连接,机器资源假设可以创建100个进程,PostgreSQL就受限于进程数最多只能应对100个连接,而同样的资源,MySQL也许能够创建1000线程应对1000个连接。那么在机器资源有限的情况下,一个进程里面Informix就可以接受数万个连接甚至更多,这就可以尽可能多的响应巨量连接需求。



现在我们来看安全相关的一些内容。我们使用数据库,一开始一定是输入用户名和密码,它们就是我们安全防范的第一道关卡。除此之外,在数据库的内部还有很多安全防范措施,比如说像用户身份认证,在使用过程当中做标记安全和数据加密、在事后做审计等等。


今天我们分享的技术很少人谈,但是因为很有特色,所以和大家分享一下数据库是怎么防治Dos攻击的。首先我们先看一下Dos攻击是如何产生的?如图所示,这是一个监听,当请求来临时,操作系统发起创建一个socket,数据库去读这个socket,读第一个包/消息,但是用户做到这一步,即邀请服务器发起socket之后便不再继续发送消息。这样整个进程就会被阻塞,不再响应新的请求,于是产生了服务拒绝,这样攻击就生效了。


Informix是怎么应对的呢?很简单,当走到这一步的时候,Informix会创建一个新的协程(实际上是虚拟进程里面的一个类似协程的程序片断,如下我们为了表述方便,使用协程表示),协程去响应用户的需求,然后再加上超时判断,如果这个超时判断为真,那么就终止掉这个连接,否则就正常响应。因为协程的存在,上面就不会再阻塞,所以可以响应新的用户需求,这样在数据库内部就可以防止Dos攻击。



我们简单的来总结一下,在前端架构需要考虑的问题就是怎样使用多用户(如我们前面谈到的协程方式的多连接)、多连接的数据库提供高效(协程方式)、安全的服务(防止Dos攻击)。



第二个部分主要是说数据库的整体架构,上图是数据库整体架构的一个结构图,整个过程是SQL语句的输入输出,数据库引擎内部主要分为以下几个部分,分析器、优化器、执行器、事务管理器以及和数据相关的公共部分。SQL语句进入之后,先在分析器中做词法、语法和语义分析,然后进入优化器中做逻辑和物理优化之后得到一个执行计划并交给一个执行器,执行器是一个动作的发起者,要和各个组件进行交互,尤其是要和事务管理器进行密切的交互,然后协同把整个SQL执行处理完毕。



我们以一个SQL语句为例,在这个语句当中,它首先要词法分析,将SQL语句进行分解,像零部件分解之后再组装成我们常见且易于遍历的语法分析树(语法分析树是常用概念,是词法分析之后进行语法分析阶段处理后的树的样式),语法分析之后我们进行语义分析,比如我们有一个表t1,它要去查找表t1存在与否,如果不存在就会报错,完成这些工作之后我们会得到一个处理完毕的语法树。



完成分析工作之后进入到优化器里面,优化器主要做两个工作,一个是逻辑优化,一个是物理优化。



优化完成之后会得到一个执行计划,我们以查询语句为例看一下执行过程。首先第一步,执行计划输入执行器,第二步,执行器去开始一个事务,第三步,迭代器打开一个表,然后一直迭代,使用迭代操作符Next读出每一条元组,直至Close关闭表对象(如果同一个对象被同时多次打开,则不是关闭表对象而可能是减少表的引用计数),Close之后做释放资源的操作。这里有一个问题:就是迭代器向谁要数据,怎么要数据?第四步,数据库引擎有一个内部的访问方法通常叫做Heap/Access Method,因为这个方法是在内存中操作,所以无法从外存中直接获取页面。这里需要的是一个逻辑操作,因为内存中数据不存在,所以接着向下走,第五步进入到Buffer中找数据(如图),Buffer中发现需要的数据不存在,执行第六、七、八步,再接着走向资源管理、文件系统和物理设备,向它们索要数据并得到数据,然后执行第九、十步、数据逐层返回。第十一步这个访问方法就是要把物理页面解析成逻辑记录,第十二步事务管理器如果实现了MVCC并发控制方式,将判断所得到的元组是否可以被用户看到(取决于并发控制技术和隔离级别)。之后执行第十三、十四步就得到了查询结果并输出。最后,第十五步表示事物结束,这时事物管理器将执行提交或回滚操作。可以看出,一条SQL的执行,经历了一个复杂的过程,需要执行器、事务管理、并发控制、缓存管理、存储管理、日志管理等模块协同工作。



插入语句与查询语句相似,第一步是输入,第二步是开始事务,第三步是经过迭代器对新的元组执行插入,与查询语句不同的是,查询语句是从下层要数据,而这里是从上层产生数据输入到下层存储。 第五步当它产生元组,存入缓冲区中的页面上。第六步,在插入语句执行过程要不断的产生日志,产生的日志通过日志管理器提前刷出到存储上,它要优先于数据落盘。日志刷出去之后,消息返回,告诉用户执行成功,直到第十一步事务结束。当数据库引擎发现需要做Checkpoint的时候,可以如第十二步,直接把数据从缓存区刷出到物理存储设备。


通过这两个例子,我们来简单的了解了数据库各组件是如何协同完成操作的,但实际的过程远比我们刚才讲的要复杂。我们可以来简单的总结一下数据库的整体架构主要考虑的是ACID特性保证的事务机制以及数据可被高效并发访问。



今天要和大家说的第三节的内容是扩展架构,扩展架构是指什么呢?有的人比喻说是封闭小区对外开放,对外开放要做的是功能扩展,但是其实数据库本身就有一些对外扩展,比如大家所熟悉的自定义函数,创建存储的过程,创建储放器等等,就允许大家输入一些数据然后进行操作,尤其在数据库进行某些控制。


实际上数据库内部不仅仅是我们刚才所说的这些函数,触发器。如果我们做一个主题,那么它的扩展顺序应该是这样的:优化器、执行器、数据处理、存储。不同的数据库会提供不同的可扩展性,用户可以进行不同的操作。


数据库中扩展性比较强的是PG,支持替换整个存储引擎,而MySQL可以通过handler可以把整个存储引擎替换掉,MySQL粒度比较粗。但替换掉存储引擎,这里的存储引擎是一个广义的概念,包括事务管理、存储等等。


对于PG来说,它提供很细的粒度。PG可以在最底层的存储层把存储引擎换掉,其实这是物理I/O层,里面是有接口存在的;第二它允许我们自己自定义存储类型、自定义优化器、执行器等功能。优化器在PG里是可以被替换掉的,它提供自己默认的优化器,但同时也提供接口允许我们替换掉默认优化器,同时它也允许把执行器替换掉。在数据访问方面,PG允许用户自定义索引、操作符、外部数据源,甚至是数据采样方法。不同的数据库体系不同,PG和Informix使用的是共享缓存,所以它们允许用户进程附加到服务器共享内存中,DBA可以利用这一功能分析文件的存储结构。


Informix最早有个技术叫做数据刀片,它允许各种类型的数据插入其中,同时也支持用户自定义数据类型。


总的来说,PG的扩展粒度较粗,层次很多,但这些功能都是鸡肋功能,真正使用的人不多;MySQL虽然粒度不是很细,但还是提供一定的扩展功能;Informix主要是支持很多数据类型完成数据存储、计算等等。


这张表,详细对比了PG、MySQL、Informix的扩展能力。



前面我们谈到的,都是单机系统的架构技术,接下来我们来分享一下集群的架构技术。


早期单机系统存在一个很大问题就是单点故障,一个机器或内存坏掉了,整个系统就无法使用了。



很多数据库都有复制技术,这里以MySQL为例,MySQL通过主从复制达到高可用目的,但是这个做法的缺点是资源利用率低,一主一备,主机工作,备份机器还是闲置状态,不对外提供服务。



之后,基于MySQL主从复制衍生出了很多高可用技术:一主多从复制技术,但是它需要用户定制开发,同时还需借助第三方组件。



读写分离架构虽然是高可用的,但是它的主备之间出现网络故障时,集群脑裂,会导致数据双写、VIP来回切换。它的缺点是failover依赖于第三方组件;读写分离依赖于MyCat/Atlas等分布式中间件;数据需要人工/自动分片。



对于高可靠高可用集群,我们以Informix两地三中心解决方案为例来说明。,首先,用户通过CM连接管理器向数据库发起数据请求,然后到达SDS共享存储集群,这里的主备结构共享的是一个磁盘,像Oracle的RAC一样。这样做有哪些好处呢?第一个是A和B它们都可以对外提供服务,第二是A和B两个节点都可以同时提供读和写功能。除此之外,它可以通过HDR通信将数据同步到同城,完成同城灾备。另外,可以通过RSS通信,将数据远程通讯备份到异地,完成数千公里之外的远程备份。



当系统中A机器出现宕机,B节点立刻接管。当B节点宕机,同城的HDR节点立刻接管服务。如果HDR节点也宕机 (概率很小很小了),千里之外的RSS系统下的节点可以接管服务。在这样的系统里面,首先提供了两地三中心的架构,避免了系统宕机对用户的影响;其次极大地减少了用户对外提供服务的停机可能和停机时间。再次,在SDS系统之间,类RAC的系统还能提供主备节点同时提供读写的功能,这比读写分离的模式先进。



最后,我们来讲一下分布式NewSQL的三条路,用户的需求是多种多样的,如开发需求、海量存储、高性能计算、多种数据类型、自动增容、减容、几乎无failover、事务特性、提供SQL接口等等。面对如此多的需求,我们如何来解决呢?



第一条路是从NoSQL走向NewSQL,现在有很多NoSQL系统在逐步的向NewSQL靠拢,它有分布式计算、分布式存储,满足了基本需求。如HBASE这样的系统,初始建立的时候,比较容易,原型能快速推出。但是,这条路走起来,将越来越困难。从KV系统向关系型数据库演化的最大困难,在于架构,这是因为KV系统简单,构建好后在定型的系统架构上再考虑增加关系型架构,就相当于在一个简易地基上要搭出一个复杂的大厦,异常困难,难点在于简易地基根本不会考虑到构造复杂大楼对地基的复杂要求,之后硬塞一些基础设施进入简易地基,原型已定,困难重重。所以我认为这条路很难走下去,多数这样走路的,都要推翻旧的基建重新构建。



第二条路是从传统数据库走向NewSQL,上图是一个PG数据库搭的框架,通过协调器提供多读多写功能。这条路,个人认为,先天缺乏分布式特性,需要一点一点增加分布式特性和对非结构化数据存储、计算的支持。但在一个复杂的系统内部增加新的组件,是否能够简单易行,考验着宿主系统的架构。



第三条路是混搭架构如Trafodion。Trafodion是一个开源数据库,它是怎么做的呢?第一提供了ODBC/JDBC驱动程序,这样简化开发,不用嫁接很多中间件;第二,多Master节点,能够做到物理级并行计算;第三,多主协调避免Master的单点故障;第四,分布式事务管理提供了ACID强一致;第五,执行器可以有很多个,提供了并行计算的能力;第六,分布式存储如HBase,提供了巨量数据存储的能力。这些,都是混搭架构通常具有的优点。但是它的缺点是如果多个组件融合做得不好的话,系统的效率会低下。



关于第三条路,谷歌也提出了一个解决方案就是如上图所示的Spanner。其核心部分有2点,一是提供了分布式事务管理,这个功能位于多副本数据之上局部的leader当做事务的管理器,所以很灵活不用担心单点。二是在复制层面,使用了Paxos协议复制出多副本为系统的可用可靠提供了保障。



简单来说,集群架构需要考虑以下问题:满足海量数据存储和处理的需求,保证数据不丢失;支持分布式事务特性实现ACID特性;多点同时提供读和写,提高了高资源利用率;满足多种类计算需求同时提供事务和分析的功能;无单点故障提供了极高的高可用;另外还可以处理多种数据类型存储。


关于SACC

中国系统架构师大会(SACC)是目前国内最受欢迎的技术盛宴之一,于每年秋季召开,迄今已成功举办了八届。大会云集了国内外顶尖专家,共同探讨云计算和大数据等技术背景下,如何通过架构创新及各种IT新技术来带动企业转型增效等前瞻性热点话题与技术,吸引4000余名系统运维、架构师、及各种企业的IT决策人士参会,为他们提供最具价值的交流平台。



举报 | 1楼 回复

友情链接