查看原文
其他

从OneProxy说起,聊聊应用监控的突破点及优化手段

2016-06-07 楼方鑫 DBAplus社群



一般来讲应用程序负责四块功能:

  1. 一个可能同时承担多种业务;

  2. 应用可能会需要复杂的计算;

  3. 应用可能会需要经历网络来调用其他应用提供的服务;

  4. 应用会需要访问或更新包括数据库和缓存在内的数据。


对应用的监控也应当分析这四个点,但要全部做到会比较难,或者实现的代价会很大。


同时承担多种业务的情况不在我们重点讨论的范围内,在现在的互联网相关应用系统中,完全不调用数据的应用极少,相对也比较好监控,去除数据访问后,基本上只有程序语言自身的GC(指内存的回收)、CPU的消耗和网络了,只要优化GC参数、CPU足够并且网络的带宽和响应时间正常,应用不太会有大问题,因此监控的重点和难点在于应用如何处理和访问数据层,尤其是以关系数据库为核心地带。


缓存只需要关注调用的频率,每次的响应时间不会有太大的波动。对关系数据库来讲就不同了,SQL所能表达的逻辑远超缓存类的KV表达能力,比如多表关联、分组汇总、分页、以及多个SQL语句组成的事务。除了受到网络的影响,还受到数据分布、缓存命中率、数据更新冲突、事务一致性等多种因素的复杂影响。


应用程序作为所有数据交互的发起方,可能觉得是最适合来做性能监控的,理论上是如此,比如输出尽可能详细的日志,再将日志收集到专门的日志处理平台上,进行统计分析。但事实上这种方式要求非常高,表现为以下几点:


  • 需要有一套日志分析平台,如果应用规模比较大,所需的日志分析平台也要比较大。

  • 需要修改应用程序以打印足够详细的日志,目前通用的切面注入方式,并不能得到足够详细的信息,无通用的不入侵应用的解决方案。

  • 打印过多的日志本身会影响应用的性能,过多的IO和过多的内存消耗引起的GC问题,会让性能数据失真。

  • 应用规模较大时,极难统一日志的格式,对历史遗留应用基本上没有任何办法。

  • 应用日志的输出内容其他团队比较难以理解。

  • 需要投入比较宝贵的人力资源,也许国内这一点不存在。


除非在应用开发的初期能够有很好的规划,或者有非常统一的基础框架,才能实现较为丰富的日志输出。这个很难做到,公司的初创期或应用的建设期一定程度上是比较粗放式的,并不是万事都俱备了才动手建设应用的。


在数据层,包括KV的关系数据库都提供了非常好的监控功能,包括自身的CPU/内存/网络利用率、每一条SQL语句的处理时间,并且已经非常成熟。问题是从单条的SQL要联想到应用是非常困难的,并不是和开发交流的最好方式,单条的SQL并不是应用与关系数据库的交互方式,交互的基本单元是事务,一条SQL也可以构成一个事务,多条SQL也可以构成事务,在绝大部份场景下,引起问题的关键点在于多条语句构成的事务,其次是复杂的单条SQL语句,最后才是简单的单条SQL语句。可以说没有事务的单条SQL是非常易于优化的,现在的应用开发人员已经基本上完全了解了。


应用研发人员和数据层的维护人员在各自的领域都十分专业,但如果缺少交流的共同语言,将非常难以相互理解,在不同的楼层或办公区一定程度上会妨害相互之间的交流、理解和协作,但根本的问题在于如何轻松地理解对方所做的事情的关键部份。要应用研发人员去完全了解数据库是很难的,数据库也有几十年的历史了;要数据层的维护人员去理解应用也很难,应用涉及开发语言和不同的业务,并且开发人员的数量远超维护人员,不是了解一两个应用就能解决的事情。


◆  ◆  ◆  ◆  ◆  


在回顾了过去多年的工作经验以后,包括在eBay和阿里巴巴与不同的应用研发团队交流的经历后,总结出以下三点:


  • 要和应用开发人员讲事务,不要去讲一条SQL,要去讲有多个SQL构成的一个事务,一个事务基本上表示了应用的一个接口或者一个功能。如果看到一个事务的SQL结构,无论应用开发和维护人员都可以较快地相互理解。

  • 要和不同的应用讲不同的事务。在过去的经历中发现应用开发也面临非常大的业务压力,这也是公司初创阶段和系统开发阶段不可能设计完善的日志输出一样的道理,尽量比较准确和高效地去交流。

  • 对系统的把握是取决于整个团队的,但细节上是取决于团队个人的,帮助个人最终提升的是团队能力。即不要假设开发理所当然地对应用是一清二楚的,考虑到个人的离职、调岗、文档缺失、时间久远等因系,不完全了解细节,或需要较大成本地了解问题可能是常态。如果能帮他更快更好地了解应用,是会非常欢迎的(假设他是想做事的)。


在想到以上这些点以后,发现应用层很难实现这几个目的,而现有的数据层也很难实现这一目的,在仔细思考后发现中间件可以很好地解决这几个问题:第一,中间件必须知道会话的状态,也就是必须知道事务状态,那么就可以判断SQL是否是在事务中执行的,从而可以知到一个事务的SQL构成;第二,中间件层知道SQL和事务的请求来自于哪个IP地址,从而可以对应到哪个应用,可以和不同的应用开发人员做准确的交流;第三,基于通信协议的中间件不需要修改应用打日志,可以处理历史遗留应用;第四,并且不需要复杂的日志分析平台,完全可以在内存中分析、整理和索引这些有用信息。


在OneProxy中间件上,可以透明地获得如下信息:


  • 统计SQL的执行情况,这一功能在数据层也能获得,中间件层获得的时间数据包含了网络,可以更真实地反映网络质量。

  • 统计不同表的访问情况,包括增删改查,这一功能也可在数据层间接或直接获得。

  • 统计不同IP的SQL执行情况,即按IP地址统计Top SQL,或者查看某个SQL在不同IP机器上的执行情况。

  • 统计多表一起使用(出现在同一个语句或同一个事务中)的情况,包括表的组合和调用频率。

  • 根据IP维度统计多表一起使用的情况,也就是可以快速地知道某个应用中,多表一起使用的情况,也可以反查哪些IP中有多表组合使用的情况。

  • 统计事务的执行情况,包括组成事务的SQL语句、事务调用次数、SQL调用次数、事务持续时间、纯SQL处理时间、纯DML处理时间等有用信息。

  • 根据IP维度统计事务的执行情况,也就是可以快速地知道某个应用的事务的具体情况。


当然还有一些信息需要进一步去挖掘,已经发现事务部份的信息,无论是从应用日志角度还是后端数据层角度都非常难以获得,这将使得中间层具有意义非凡的应用监控功能,不管是布在线上生产环境还是线下测试环境,都非常有效。


◆  ◆  ◆  ◆  ◆  


让我们来看一个真实的事务监控的例子,下图是OneProxy中捕捉到的三个事务,第一个来自于sysbench程序的OLTP类型压测,其余两个来自于MySQL客户端工具的输入。

                                              


除了非常有用的SQL语句构成外,还呈现了很多的数字,值得好好看一下。


  • Exec

事务的执行次数,累计值。

  • Call

事务的SQL调用次数(累计值),除事务数就是每次事务调用多少个SQL语句。

  • DML Call

事务中DML类型SQL的调用次数(累计值),除事务数就是每次事务调用多少次DML语句(正在考虑是否按插入/更新/删除做分类统计)。

  • Time

事务执行的累计时间,包括了网络时间,应用在事务中调用其他服务的时间,以及SQL的执行时间(包括数据库锁等待的时间),GC的时间等等。

  • Avg Time

事务的平均执行时间。

  • Busy

纯SQL语句的执行时间统计,这里去除了应用在事务中调用其他服务的时间,及GC的时间等等。

  • DML Busy

纯DML类型SQL语句的执行时间统计,包括数据库锁等待的时间。一般来讲查询语句是不会有锁等待的。

  • Avg Busy

平均SQL执行时间。


后面还有一个记录数的统计,这里就不一个一个讲解了,相信你也能看得懂。可以看到手工执行的两个时间,SQL层的处理时间远远小于整个事务的执行时间,原因是在一条一条地敲命令,整个事务的时间以秒计算,最需要优化的不是SQL语句的性能,而是我应当将命令预先写好放到文件中去执行。而第一个事务中,平均时间只有57ms,SQL时间占了53ms,可以认为整个事务除了SQL处理外基本上没有其他额外的环节,只需要优化SQL处理就可以提升接口性能了。只要维护人员对这个事务所处理的业务有所了解,就可以告诉开发人员到底是SQL需要优化还是应用内部的调用逻辑更需要优化,而应用开发人员在看到这些信息后,估计会很自觉地处理好。


◆  ◆  ◆  ◆  ◆  


接下来让我们看一下WordPress中各个表的访问情况,考虑到应用特征是以读为主,因此我们按查询操作进行倒排。如下表所示:



假设现在因为数据库压力过大,需要进行垂直拆分,从查询操作的执行次数及记录数来看,将表“wp_posts”和“wp_postmeta”两个表拆分出去的效果是最佳的。当然对于WordPress而言中间件自身提供的读写分离功能是最适合的,但我们就讨论拆分了。


当下定决定后,开发人员在接到这样的任务后,第一反应是这两个表拆分出去得有多少工作量?这个拆分是不是会非常困难?搞出点乱子我是不是会被公司解雇?不能要求开发会很高兴地去扫描一遍所有的应用代码,去分析和评估出所有工作量,新业务的压力远大于老业务的改造,绝大多数场景下,新业务带来的个人业绩也远大于老业务的改造,除非是投入产出比很高的项目。


想要推动这件事情,就得先说明这并不是一件麻烦的事情,反而是低投入高产出的事情。比如说,我们已经对应用如何访问数据库做了很深入的分析,这些表都是一个一个的单表,并且没有出现在事务中,只需要开发人员你花点力气做确认,唯一麻烦的事情是“wp_posts”表上有两个复杂的SQL和“wp_comments”及“wp_term_relationships”有关联查询。这样就从全应用代码梳理变成了一两个点人突击检查,从投入巨大的项目变成了投入极少的项目。而这些表之间关系的分析都可以从OneProxy中间件的事务分析功能中直接得到,毫不费力,如下所示:



只需要告诉开发人员,这个统计是你花了很长时间才得到的,并且都是基于线上的真实SQL流量进行的统计,并且是统计了数个月之久,没有理由不打动他的。他不做的话可以放话去找其他的开发人员去配合,谁也不想放弃这样明确超级挣钱的机会。


作者介绍  楼方鑫

  • Oracle ACE,OneSQL&平民科技创始人。


近期热文(点击标题可阅读全文)


近期活动:

Gdevops全球敏捷运维峰会北京站


峰会官网:www.gdevops.com

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存