以下内容根据演讲视频以及PPT整理而成。
演讲者简介:
喜乐,阿里云数据库技术专家,2010年加入阿里巴巴,最近四年时间一直在数据库技术组,专注于云数据库的业务和架构。
本次分享主要分为以下四个部分:
一、背景
二、云数据库架构选型
三、云数据库的使用经验谈
四、展望未来
一、背景
近几年,DevOps一直都是一个特别火的话题,DevOps旨在将开发、线上部署、运维、质量控制以及技术运营等全部工作都整合在一个团队里,通过团队成员之间的紧密配合实现产品的快速迭代。曾经有的技术团队做到了在一天之内发布产品10次以上,如果技术团队拥有了DevOps的能力之后,这个团队的产品就能够实现在线上进行快速迭代,也就能够适应互联网飞速发展环境下的业务需求。
本次分享的主题主要与数据库相关,将主要为大家介绍作为一名开发人员需要掌握哪些最关键的数据库技术点,希望本次的分享能够为大家在架构的设计、线上运维以及问题的排查等方面提供一些帮助和指导,也希望大家能够通过学习数据库技术进一步提升自己的DevOps能力。
二、云数据库架构选型
如今包括企业级产品在内的互联网产品越来越丰富,传统的数据库产品只有OLTP和OLAP的,但是在未来数据库产品会越来越多样化。目前的阿里云的数据库产品也已经非常丰富了,可以提供比如像传统的MySQL、SQL Server、PG、HBASE、Redis以及MongoDB等数据库产品,而且如果单机无法存储全部数据还会提供数据库分片技术。目前,数据库的形态越来越多,所以大家可能在数据库的选型上会产生一些困惑,本次分享会为大家介绍一些与数据库选型相关的知识,链路的形态、安全性、可靠性、易用性、还有应用的架构和业务的类型,这些方面都会影响大家对于数据库选型的考量。
上图中的第三种形态是一种共享存储的数据库架构,通常情况下只存在一个主数据库,后面存在多个备库,但是中间的存储却只有一份,主备数据库都将数据写到共享存储上。当然对于共享存储而言,一般也会存储三份。这种架构和前面提到的第二种架构的差别在于:在第二种架构方式中,当切换到备库之后,就直接基于备库本地存储的数据对外提供服务,而第三种架构则是使用原来的共享存储,实际上还是原来那份存储提供服务,这就会涉及到对于日志进行应用,所以会需要多花费一些时间,但是上面Master和Slave节点的服务器实际上是无状态的,这样的架构下所能提供的数据可靠性就会更强一些。这三种架构目前已经应用于MySQL、SQL Server、PG、Redis、MongoDB这几种基础的数据库中了。
下图的架构就是Redis Sharding的结构,顾名思义其就是一种分片的结构。大家可以看到图中存在Proxy节点也就是mongos中间节点,其下面则是刚才提到的主备的结构。所有的数据都会按照一种分片的规则路由到下面的某一个分片上来提供服务,而路由的规则则会存储在一个组件上,这就是一种典型的分片结构。这里的结构在前面只加了一个LVS,所以整个Sharding只有一个VIP。
三、云数据库使用经验谈
接下来就为大家分享关于云数据库使用方面的经验之谈。对于云数据库的使用而言,如果想要做到安全,稳定又可靠,其实存在很多关键点,其中比较重要的就如同下图中所列举出来的这些点:应用数据源配置、报警配置、可运维时间选择、慢SQL监控及优化、参数选择、主备数据库之间的同步方式、数据备份、日志备份、账户管理、存储架构、网络安全以及架构安全等,在后面将会为大家进行更加详细的介绍。下图中左边的是整个系统从底层的硬件和操作系统一直到最上面的应用系统的分层结构。今天主要分享的就是数据库的服务,相应的就是红框里这部分,也就是应用架构到数据库服务这两层之间的部分,这里就涉及到设计、优化以及配置。
应用数据源配置
关于应用数据源配置,首先建议所有应用系统在使用云数据库时要使用长连接,这样应用程序就能够使用连接池,使用长连接的消耗最小并且不必每次都建立连接。其次就是应用程序应该能够自动进行重连,也就是说当网络发生变更的时候或者当数据库的主库发生故障发生自动切换的时候,如果应用程序具有自动重连的机制就可以做到在几秒之内自动重新连接到新的数据库上,这样对于应用程序的影响也会是最小的,所以应用程序一定要能够进行自动重连。第三个建议就是对于连接池超时的配置,这部分至少需要连接超时、socket超时这两个配置,链接超时指的是判断首次进行TCP三次握手的时候发出ACK包的回包有没有超时;socket超时是指在建立连接之后,在向云数据库发送数据之后超时了,没有得到任何的回包,这有可能是在数据包发送的途中连接断开了,也有可能是数据包已经到达Server了,但是Server回包时超时了,这两种情况都可能造成socket超时。其实对于像Java这样比较成熟的语言而言,会具有像JDBC这样的驱动,还可能存在SQL Statement超时。SQL Statement超时不是数据库本身提供的,一般情况下是由客户端自己完成的,因为数据库采用的都是停等协议,当客户端给数据库发送一个SQL之后就会阻塞在这里,如果当SQL发出去了,到一定时间还没有返回SQL的查询结果,客户端就会再启动一个线程向数据库发送一个Kill的命令将之前的那个连接杀死,中间的这段时间就需要通过SQL Statement超时来进行设置。
另外,所有应用客户端连接池的最大连接数总和应小于数据库的最大连接数。通常情况下,可能会存在很多个应用连接数据库,这些应用去连接数据库时都会设置自己连接池的最大连接数,如果当所有的应用所设置的链接总数大于数据库所设置的最大连接数,就会发生将数据库的连接撑爆的情况。超过最大连接数之后再请求的连接就会被数据库服务器拒绝,这就会对于应用造成很大的伤害,所以推荐在实现客户端时或者开发同学在配置连接池时一定要保证客户端连接池的最大连接数总和小于数据库最大连接数。有的云数据库可以将连接数作为购买项进行设置的,也有的需要通过对于数据库参数的调整进行设置,大家需要根据自己所使用的数据库进行设置。
除此之外,如果应用能统计业务SQL的执行频率及执行时间的监控数据那就最好不过了。通常情况下按照三层设计的DAO层就是专门负责连接数据库的,希望大家能够对于这一层的代码进行切面,无论使用单个数据源还是多个数据源,都应该对于所有关于数据库的操作都要统计SQL执行频率和执行时间的监控数据,这样当每次进行应用发布的时候,如果增加或者修改了SQL就可以及时得到该条SQL在线上真正运行时的执行效果,这样对于应用问题的排查也会起到非常大的帮助。对于淘宝和天猫而言,都会有非常成熟的数据库执行频率和执行时间的监控,所以建议大家在开发自己的应用时也设计实现这样的模块,并且目前也已经出现了很多比较成熟的第三方库能够实现这些功能。
报警配置
对于报警配置而言,其实云监控已经能够设置很多的报警了,但是通过数据统计发现通常情况下大家都不太关心这部分,这是不应该的。无论使用的是哪一个云数据库都应该在云监控上设置自己的报警,因为有一些阀值是根据应用的压力进行调节的,比如通常情况下,数据库服务器的压力是CPU可以跑到50%,那么可以设置阀值为70%,如果在某一次应用发布之后CPU的占用率一下子就大幅度上升了,此时给开发人员发一条短信或者报警就能够帮助开发人员及时发现线上数据库存在的潜在问题。
报警和监控其实分为两部分,一部分监控的数据采集包括了很多指标,比如CPU、内存、磁盘IO以及各种数据库引擎特殊的属性,这些指标希望大家都能够关注,因为监控已经将这些指标从曲线上拉取出来了,如果在指标的监控曲线上看到存在巨幅波动,一定是出现了应用系统的变更或者数据库的配置有所变更,这样大家就能够对于数据库性能上的指标有所了解。另外一个就是报警,当数据库存在问题的时候,可能最多是性能或者故障问题,大家可以及时收到报警的信息,不至于造成很大的损失。
可维护时间
刚刚接触数据库的同学可能不太了解可维护时间这个概念,其实可维护时间和之前提到的链路是紧密相关的,通常情况下即使自己搭建数据库,也会出现数据库损坏、升级、重启或者网络需要进行变更的时候,这个时候连接一定会断开。后端像阿里云这样的云厂商进行运维性工作的时候往往可能会导致数据库出现闪断,这个闪断的时间不可能是随时的,因为这样对于应用的影响会比较大,所以就需要设置一个可维护时间,当客户设置好可维护时间之后,阿里云就能够保证所有的运维出现对用户造成影响的阶段都发生在可维护时间内,这样就可以尽量降低维护对于应用的影响。
1)内核小版本升级
2)机器损坏迁移
3)主库不可用主备切换
4)网络切割,变更
其实这里面最主要影响到了VIP,也就是LVS到后端的RS也就是物理机的IP之间的对应关系,而且更换VIP时也需要在可维护时间内执行。
慢SQL监控以及优化
对于慢SQL而言,应该如何进行分析和优化呢?其实可以从这样的几个角度进行考虑。
账户管理和链路安全
只要是涉及到链路的内容都是非常重要的,当用户购买完阿里云的数据库服务之后,所有的白名单都是禁止访问的,希望大家能够自定义地设置IP的白名单。只有在设置了白名单之后才能继续使用服务,不建议大家一律都设置成为可通过,因为这样是极其不安全的。
其实最推荐大家使用VPC网络,因为使用了VPC网络就可以与其他的所有用户的服务从网络上隔离开来。第三点建议就是对于账户数量以及数据库的数量进行控制,很多云用户使用了很多的账户和数据库,而这样的做法不是一种很好的做法,因为当账户很多之后,一个数据的权限就会呈指数地向上增长,因为每个账户或者每个DB都能有权限,并且权限还可能各不相同。当执行刷权限操作时就会消耗很长的时间,这样对整个数据库的使用而言是非常不利的,这里推荐大家升级到MySQL 5.6版本,当然目前绝大多数用户也都是使用的MySQL 5.6了,如果还没有升级的话希望大家尽快完成数据库升级,这样就可以享受到超级权限账户的功能了,这样其余的子账户都可以由这个超级账户派生出来,而不需要走API的方式。另外还建议每个业务应用都拥有自己的连接数据库的账户,为什么要有这个限制呢,其实是希望通过这样做,让大家在分析数据库上的连接和SQL的时候能够知道这条SQL来自哪个账户和应用,而不是只能够知道这条SQL来自的IP地址。
数据备份,日志备份
数据和日志的备份都是非常重要的,因为给在线数据库提供服务就是上述提到的与链路相关的事情,而其实在一种比较极端的情况下,比如购买了两节点或者三节点的数据库后,如果真的发生了灾难性故障的时候还会有一份离线的数据,那么通过离线的数据就能够恢复到日志已经上传到OSS上的最近的时间点,所以需要及时检查云数据库上的数据备份和日志备份是否有效,还可以适时地执行一次数据恢复来试一下数据能否正常地恢复回来,这无论是对于一个应用还是对于一家企业而言,都是非常核心的任务。
除了定期查看备份是否正常,还需要关注备份文件的大小。当数据库存储的数据量非常大的时候,比如单机数据量达到几个T之后,进行一次数据备份的时间就会非常的漫长,很有可能出现备份超时或者出现了其他的问题,所以对于数据量特别大的应用一定要经常检查自己的数据备份是否是正常的,而当阿里云发现一些用户的数据备份不正常时也会及时提醒用户。这里的一个关键点就是防止binlog刷新过快,线上的一些binlog刷新是很快的,比如1分钟一个500M的binlog,对于这样的应用就应该反思使用的数据库是否合适了。因为对于OLTP这样的应用而言,不应该存在大量的插入操作,如果存在大量的插入操作而查询和更新操作很少,这样的应用应该使用像HBASE这样的数据库,而不应该使用事务型的数据库。如果存在大量的数据更新就应该考虑是不是应该使用缓存、缓冲或者异步系统等,在应用级别想办法而不是把所有的数据更新都塞到数据库里让数据库承担。因为每个更新都会产生binlog,如果在短时间内产生大量的binlog就会造成应用的不稳定,一旦主库宕掉,就可能有大量的binlog积攒在本地没有得到及时上传,这样在灾难恢复或者主备复制时都会造成障碍,比如主库产生了大量的binlog,备库不能及时消费就会造成延迟,这样当主库故障切换到备库上时等待恢复的时间就会非常长。这一系列都是相关联的,所以大家应该及时检查binlog的运行状况。
对于数据库的参数而言,比如像典型的MySQL、SQL Server往往都有几十个参数,而常用的参数并不多,所以建议开发同学能够检查自己的数据库配置是否正确。
四、云数据库的未来