你的生产环境上奔跑的应用们是否容易监控?很多应用的监控体系做得不错,然而有些应用则很明显在设计初期完全没考虑到监控这回事儿。这样准备不足就匆匆上马会带来一系列的恶性后果,比如:
原本很容易就能实现的监控变得代价高昂。
一些市面上现成的监控系统用不成了,你不得不自己开发一套定制的监控系统。
因为缺乏一些通用的监控维度,你的应用无法跟其他的监控系统相互兼容。
当你想要增加这些监控维度的时候,你发现实现不了,于是你的应用总有一些监控不到的阴暗角落。
跟监控相关的人员、流程与系统变成了组织的瓶颈。
对于大规模运行的应用而言,监控就如同备份、安全、审计等因素一样重要,最好提前做好规划。如此,系统管理者可以有意识的针对不同指标进行取舍,而不是遇到意外后忙着救火。
『聊聊监控』系列文章翻译自 Baron 的博客,如作者所说,希望你在阅读该系列文章之后,可以在系统中应用这些最佳实践,并为你的应用构建一个高度可监控的架构,用小成本实现极佳的系统能见度。
Baron 是性能和可扩展性方面的专家, 他参与了多个数据库开源社 区与分布式系统社区,协助过很多财富 1000 强的公司构建大型高流 量服务,还撰写过数本书籍,其中包括 O’Reilly 畅销书 High Performance MySQL。Baron 拥有 Virginia 大学的计算机学位。
本文是系列文章的第一篇。
监控是应用的功能之一。就像应用的其他功能一样,它是一系列的权衡取舍,涉及到高维空间中的优先级排列问题。本章将讨论这样一些取舍问题,希望能帮你做出更好的选择。
以下是我经常见到的一些取舍点:
“我该监控什么?”这是很多同学在搭建配置一个监控系统之初常问的问题。要构建一个高度可监控的应用,这个问题是一个非常好的向导。
我在这个话题上做过一些现场分享,这些分享介绍了我针对监控的一个整体思维框架,包括指标系统对外展示的含义,这每一个指标具体是什么意思,以及为什么我们最好不要在早期就过度关注具体的指标。(点击阅读原文链接查看,Youtube 视频)
上述资料的核心思想是:不要被次要的小细节拽着鼻子走。先决定你所需要的信息,并为其分类:它们是有关工作负载?系统资源?还是事件?确定了这些之后,再制定相关的采集计划(具体来说就是建立可被观测、测量的能力)。
对于数据库而言,最重要的测量对象就是查询 (queries)(在不同的语境下也被称作语句 (statements) 或者请求 (requests))。数据库负载的基本单元就是查询。对于用户来说,其查询需要被正确而快速的完成,至于其他方面则无关紧要。如果你对于查询没有做到一定细粒度的监控,那么数据库在你看来就跟黑盒子差不多。而从运维人员的角度来看,他们还要重点关心数据库的资源使用情况。
事实证明,针对查询的监控不管怎么做都是困难的,而且我们往往会把它变得更困难。我将在本书中花费一些时间讨论我们该如何避免此类不幸。
执行一个进程。这是操作系统的主要工作之一,所以对进程的监控,以及对它们所跑的工作负载以及资源占用情况的监控,无疑是重要的。操作系统同时还负责进程接口的管理,负责进程与外界的通讯,以及进程对资源的访问,所以进程监控也需要考虑到这些方面。“最后要说的是,很多问题经常发生在进程与资源交互的过程中。
到目前为止,我们已经考虑到了数据库和操作系统这两个“罐装”软件,那么接下来要考虑的就是你自己的软件:你自己编写、部署的代码。这方面的监控依然遵循同样的原则。你的代码运行了一些工作负载,这些需要被测量记录。你的代码管理了一些资源,执行了一些查询和交互动作(很多问题都出现在这些环节),这些也需要被测量。
要做的事情很多,基本上你不可能从一开始就全部提前计划好,因此本书的重点主要是提供一些指导方针,而不是像菜谱一样列出所有需要监控的指标。我们会涉及一些案例,它们可能会帮助你在你的项目中应用这些方针。
对开发者友好 vs. 对运维友好
构建应用的时候如果只考虑到了开发者而忽略了其在生产环境中的运行需求,可能会导致该应用的部署、维护、监控遇到问题。这两者如果一开始都考虑到了,则不一定会构成冲突;然而如果一开始没考虑好,那么越往后越可能顾此失彼。
你的进程 vs 他们的软件
所有的软件(包括监控软件)都表达了一种工作流的世界观。两个软件之间如果世界观不匹配,则要么你去匹配它,要么让它来匹配你。“是在你的系统上做修改以匹配监控软件,还是在监控软件上面做修改以匹配你的工作流?
成本 vs 能见度
在很多情况下,系统的可视项越多,监控就越昂贵。监控的成本基本上与你收集的数据数量和细粒度成正比。所以,你收集的越多,付出的就越多,不过你收集到的东西都会对你有好处。我听说在 Netflix,监控系统在整个运维系统里面的预算占比是两位数的百分比,他们在流媒体业内甚至有“监控之公司”之名。据说 Netflix 的人均营收在上市公司里是最高的,这样的成功也许和他们在监控上的投入也有一些关系吧!
我还知道很多从 Oracle 迁移到 PostgreSQL 的公司,因为 Oracle 的许可证卖得贵很多。然而,Oracle 在系统的能见度方面比 PostgreSQL 可高了不是一星半点。到头来,这样的迁移是否值得它剩下来的成本?这是需要你自己做出的决策。
隔离的很多小服务 vs 一个大服务
微服务架构现在很火。在 VividCortex,我们很多人都非常热衷于微服务的一些原则;然而我们也在一些客户那里看到因为过度的微服务而给监控的实施带来巨大麻烦的情况。很多很多小服务就意味着很多很多需要度量的对象,监控系统不可避免会变得非常复杂。而正如之前所说的,监控项越多,成本越高。
这一点还涉及到最近很火的另一个话题,就是容器化。如果你的生产环境运行着成千上万个 Docker 容器,很显然你需要监控的东西就会非常多。同样的,你是将不同负载分布到很多个数据库上,还是让一个大数据库支持很多个负载,甚至是购买昂贵的一体化数据库方案,也会显著的影响监控的工作量。
监控的成本和工作量是需要仔细考虑的。你可能在工作中发现自己需要换一个可扩展性更强的监控系统,也可能发现自己在不断的往监控系统这个大坑里投入时间、金钱和硬件。无论怎样分割你的系统,监控的成本都很难降下来;如果一个系统架构中的“东西”多了 N 倍,则监控成本也同样的成倍增加。
共享资源是能够减少一些监控成本,但透明度则会降低。如果你不用容器,而是让好几个服务都跑在一个服务器上,那么当这台机器的网络流量或者磁盘 IO 忽然出现一个峰值的时候,该怎么知道到底是哪个服务造成的这个峰值?我们在 VividCortex 倒是可以做到进程级别的 CPU、IO 等资源的监控,然而不是所有的监控系统都能够提供到这样细粒度的监控。
内置度量 vs 钩子
很多时候,你的软件没有提供你想要的度量,于是你需要绕着弯去取得它,而这可能会很费事。比如在 VividCortex,我们非常看中 query 级别的能见度,而不是所有的数据库都能提供这个维度的监控,因此我们不惜在操作系统层面采用了 TCP 流量抓取(TCP traffic capture)再解码为 query 的做法。这个做法非常费事,我是不建议我们的读者仿效,而做出来的结果则类似 DTrace,基本上你想要看什么都能看到。总之,你的做法取决于你对该度量的重视程度。
上面这个列表不能算完整,不过应该说还是有一定的代表性。在我看来,最重要的权衡主要是在于你自己的应用代码的调整。我在下面画了个四象限图:
(点击放大图像)
该四象限图中,横轴衡量语句冗余度,左端为大量的重复,右端为不重复;纵轴衡量语句精确度,下端为模糊,上端为精确。很明显,我们的目标是第一象限——简单明确。不过,简单明确也不是万能的,无需过份迷信。
以上是“约定大于配置”原则的两个维度,其中心思想在于让开发者投入最小的精力,同时又能够实现一致的、符合直觉的、灵活的代码监控功能。框架在某些情况下能够帮你实现这个目标。
查看英文原文: What Should I Monitor, And How Should I Do It? - - - - - -
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论