定义服务水平目标
在衡量数据库性能之前,得先知道目标是什么,可以用以下问题来引出目标:
-
衡量成功的合理指标是什么?
-
客户和我们的业务需求可以接受这些指标的哪些值?
-
在什么情况下会被视为降级状态?
-
什么时候处于完全失败的状态,需要及时补救?
根据目标来确认是否需要在性能改进或稳定性方面投入更多。
这些关于客户满意度的讨论将使团队在服务水平指标(SLI)、服务水平目标(SLO)、服务水平协议(SLA)方面就什么对业务有益达成一致。
- 服务水平指标(SLI)
SLI 回答了“如何衡量客户是否满意”的问题。根据客户的要求,有着不同的指标。
- 服务水平目标(SLO)
SLO 回答了“为了确保客户满意,能允许 SLI 达到的最低限度是多少”的问题。如果 SLI 的指标是服务正常运行的时间,那么在给定的时间范围内,正常运行时间达到百分之多少就是 SLO。SLO 需要是一个具体的值,以确保每个人对 SLO 的含义保持一致的理解。SLI 加上 SLO 构成了了解客户是否满意的基本方程式。
- 服务水平协议(SLA)
SLA 回答了“我同意的 SLO 会产生什么后果”的问题。SLA 是与客户签订的协议中包含的 SLO,如果为满足该 SLA,将会受到财务或其他处罚。SLA 是可选的。
定义这些SLI、SLO和SLA不仅可以引导业务健康状态,还可以指导工程团队的规划。如果团队没有达到承诺的SLO,则不应该继续进行新特性的工作。当有了数据来解释为什么客户体验不理想时,便可以就团队的优先事项进行更有意义的讨论。
怎样才能让客户满意
根据客户满意的最低标准设定目标,如果客户对于两秒内加载页面感到满意,则无须设置750毫秒内加载页面的目标。
工程时间是有限的资源,所以在选择SLO时不必过于追求完美。
这些指标和目标也是在产品和工程之间达成一致标准的有效方法,以指导在“将工程时间花在新功能上”与“将时间花在可恢复性和修复问题上”之间做出决策。
用什么来度量
定义好的SLI和匹配的SLO是简洁地解释如何为客户提供愉快体验的核心。在MySQL的使用环境中,需要定义三大重要主题:可用性、延迟和关键错误缺失。
以在线商城为例,这种场景下的页面加载速度很快,如果要求在一个月内至少有99.5%的时间是快于几百毫秒的。那么间歇性故障应该允许有1%的时间出现,而不是0.5%,需要留出部分余量。
在SLI和SLO的背景中,查询分析和查询延迟监控都是必要的,当查询响应时间超过商定阈值时,应该能够第一时间发出警报。
监控可用性
间歇性不可用会减低用户的信任。这就是为什么将可用性作为一个独立的指标,以及作为客户体验中如此重要的一部分。
验证可用性的首选方法是从客户端或远程端点来进行访问。可用性的远程验证对于跟踪可用性目标非常有用,但它不能让你在问题出现之前就发现。
MySQL中有一个Threads_running状态计数器可以作为可用性问题的关键指标,这个计数器跟踪的是给定数据库主机上当前正在运行的查询数量。当运行的线程快速增长且没有任何下降迹象时,说明查询完成得不够快,因此正在堆积和消耗资源。
如果允许这个指标增长,通常会导致数据库主机出现完全的CPU锁定或严重的内存负载,从而导致操作系统关闭整个MySQL进程。
首先要检查有多少个CPU核,如果Threads_running超过了CPU核数,则可能表明服务器正处于不稳定状态。与此相结合,还可以监控Thread_running与max_connections的差距,以检查正在进行的工作是否过载。
监控查询延迟
除了内部跟踪的延迟,还需要了解应用程序如何感知延迟,以及当感知到的延迟增加时会发生什么。也就是说,不能只盯着数据库服务器中的查询延迟时间,还要在客户端进行查询,看看从数据库服务器到客户端的延迟时间。
监控报错
*每次报错是否都需要跟踪和提醒?*这要视情况而定。
以下是一些客户端错误的示例,这些错误通常可能只是噪声,但如果报错的频率加快,则是将要出现问题的迹象。
-
Lock wait timeout
如果客户端中该报错急剧增加,可能是主节点上的行级锁争用在不断扩大,即事务不断重试但仍然失败。这可能是无法写入的前兆。
-
Aborted connections
如果客户端中该报错突然激增,可能表明客户端和数据库实例之间的某个访问层出现了问题。不跟踪这一点会导致大量客户端重试,这会消耗资源。
MySQL服务器跟踪的名为**Connection_errors_×××**的服务器变量集很有用,其中的xxx是不同类型的连接错误,这些计数器的突然增加可能会告诉你出现了一些新的问题。
有些问题一旦出现就意味着是需要处理的麻烦,比如的服务器端错误是“too many connections”或操作系统级别的“cannot create new thread”。这些迹象表明,应用程序创建和打开的连接数超过了数据库服务器配置中允许的连接数,这个限制可能来自服务器的max_connections变量或者MySQL进程被允许打开的线程数。这些错误会立即转化为5××错误返回给应用程序。
主动监控
数据库磁盘100%满时的空间告警已经太迟了,因为服务已经停止。但如果太早就报警,可能又不会被当一回事。
磁盘空间使用率增长
在出现问题之前,跟踪磁盘空间使用率的增长可能是一类不太会被考虑的指标。如果监控工具允许,可以尝试跟踪磁盘空间使用率的增长速度。
如果跟踪增长率不可行(并非所有监控工具都提供此功能),则可以设置多个阈值,其中较低的警告可以设置为仅在工作时间触发,而较高的、更严重的值则作为对非工作时间随叫随到的告警。
连接数增长
随着业务的增长,普遍现象是应用程序层的线性增长。一旦与服务器的连接总数达到最大值,数据库将不允许任何新的连接,会给用户带来明显感知。
监控连接数增长是为了确保资源不会耗尽到危及数据库可用性的程度。这种风险可能以两种不同的方式出现:
- 应用程序层打开了大量未使用的连接,导致产生了毫无理由的连接过多的风险。一个明显的迹象是连接的线程数(threads_connected)很高,但运行的线程数(threads_running)仍然很低。
- 应用程序层正在积极地使用大量的连接,并有导致数据库过载的风险。可以通过查看连接的线程数(threads_connected)和运行的线程数(threads_running)都处于高值(成百上千?)并持续增加来识别这种状态。
在设置连接数监控时,要考虑的一个有用的技巧是依赖百分比而不是绝对值。
复制延迟
MySQL有原生的复制功能,可以将数据从源服务器发送到一个或多个副本服务器。数据从写入源服务器到在副本服务器上可读取之间的延迟称为复制延迟。
如果应用程序从副本读取数据,当你向副本发送读取命令,而副本还没有赶上所有更改时,复制延迟可能会使数据看起来不一致。在社交媒体示例中,用户可能会对其他人发布的内容发表评论。此数据写入源节点,然后被复制到所有副本节点。当用户试图查看其回复时,如果应用程序将请求发送到延迟的副本服务器,可能读取不到数据。
I/O使用率
数据库工程师不断努力的目标之一是“尽可能多地在内存中工作,因为这样更快”。但这一点也不可能100%做到,做到了说明数据可以完全被存储在内存中,那这种数据量也没什么好操心的了。
即使在这个几乎所有数据都在固态硬盘上运行的时代,也最好不好用磁盘读取太多数据。随着数据量的增长,查询需要扫描更多的数据来满足请求,你会发现I/O等待可能成为流量增长的瓶颈。
监控磁盘I/O活动有助于在性能下降成为客户面临的问题之前解决问题。如果数据库服务器有很多线程位于IOwait状态,则需要监控发出告警。
自增键空间
在使用MySQL时,一个不太为人所知的“地雷”是,自动递增主键在默认情况下被创建为有符号整数。当插入了足够多的数据行,使自动递增键达到其数据类型的最大可能值时,就无法再插入数据了。
在规划需要长期监控的指标时,为所有使用自增主键的表监控剩余整数空间是一个简单的操作,但几乎可以肯定的一点是,它会在将来为你避免一些重大事故,因为可以提前预测需要更大的键空间。
创建备份/恢复时间
长期规划不仅要在业务正常运行时实现增长,还要在可接受的时间范围内实现灾难恢复。
在规划灾难恢复时,需要考虑以下几点:
- 要非常具体地说明哪些功能属于这个恢复目标,如果需要的话,要查看支持该功能子集的数据是否需要在一个单独的集群中,以实际实现该期望。
- 如果无法按功能将数据划分为多个更小的实例,那么整个数据集都要处于通过备份进行恢复的目标之下。从备份中恢复所需时间最长的数据集将是此恢复过程完成时间的决定因素。
- 确保有自动化的测试方法。监控将备份从文件恢复到运行的数据库需要多长时间,并将该指标存储在具有足够的保留能力的地方,以查看长期(至少一年)趋势。
许多长期指标示例中,几乎总是指出需要对数据进行功能分片【1】或水平分片【2】。这里的目标是明确指出这样一个事实:如果你已经遇到了主要由容量问题导致的事故,这时再考虑分片,可能已经太晚了。将数据分解为可管理的小块,这项工作不是在数据对于一个集群来说太大的时候才开始的,而是在一开始确定目标时确定的。
了解恢复数据所需的时间有助于设定在实际灾难中应该做什么。它还可以让你意识到,什么时候花费的时间可能比业务希望的要长。这是需要分片的前兆。
【1】:功能分片(Functional sharding)是指将服务于特定业务功能的特定表分割到一个专用的集群中,以便单独管理该数据集的正常运行时间、性能甚至访问控制。
【2】:水平分片(Horizontal sharding)是指当数据集的大小超过了可以在单个集群中可靠地提供服务的规模时,将它拆分为多个集群,并从多个节点提供数据,这依赖于某种查找机制来定位所需的数据子集。
度量长期性能
为日常操作选择SLI和SLO只是一个开始。在这一节将介绍可以用来思考系统整体长期健康状况的策略。
了解业务节奏
业务节奏可能意味着峰值流量时间比“平均值”大几个数量级,如果数据库基础架构没有准备好,将产生很多不良结果。
以下是一些业务节奏的例子:
- 电子商务网站 对许多国家来说,11月下旬到年底是最忙的时候,从在网上商店中可以看到呈数量级的销量增长。这意味着更多的购物车订单,更多的并发售卖,以及比一年中任何其他时间相同故障对收入的影响更大。
- 人力资源软件 在美国,11月通常是许多员工进行福利选举的时候,这段时间被称为“开放登记”,这将产生更多的流量。
- 网上鲜花供应商 对网上的鲜花供应商而言,情人节是一年中最忙的时候,因为会有更多的人订购鲜花。
有效地跟踪指标
当涉及业务的长期规划时,有很多事情需要关注,包括但不限于:
- 为未来的容量做规划
- 预见何时需要重大改进,何时增量修改就够了
- 为运行基础架构增加的成本做规划
不仅需要能够在某个时间点度量数据存储基础架构的运行状况,还需要能够长期预测性能的改善或下降趋势。
使用监控工具检查性能
度量性能在即时感知“我们目前是否处于事故中”以及长期跟踪和趋势感知上都很重要。
对平均值说不
许多解决方案在默认情况下将长期数据整合为平均值,这是一个大问题。
如果要查看一个指标在几周以上的时间内的趋势,平均值将使峰值平缓下来,这意味着如果你想查看磁盘I/O使用率是否会在下一年翻一番,那么平均值的数据点图很可能会让你产生错误的安全感。
在对月份数据进行趋势分析时,请始终关注峰值,这样能够在视图中保持偶尔尖刺的逼真度。
与百分位为友
把一段时间内所有的响应时间,从快到慢(从小到大)排好队,比如算 P95,就把最后 5% 最慢的请求直接去掉,剩下 95% 里最慢的那个时间,就是 95 百分位。
用百分位看响应时间,直接就能和 SLO 对标,图表显示 P95 是 80ms 直观地表示95% 的用户请求都在 80ms 内完成。
长保留期和性能
当试图显示长时间跨度时,监控工具的性能非常重要。
不能只看短周期好不好用、能存多久、查得快不快,重点要测长周期下能不能稳定、完整、清晰地给你可用的数据。
使用SLO来指导整体架构
在业务增长的同时保持良好一致的客户体验不是一件容易的事。随着业务规模的增长,保持相同的SLO都将变得越来越困难。使用的SLI和SLO,可以找到需要开始将数据进行分片或分区的增长点。