以下是第一章的摘要 数据库性能在规模上 跟随Joan的高度虚构的冒险与一些过于真实的数据库性能挑战,你会笑,你会哭,你会想知道我们如何将这个“奶酪的故事”转化为一个非常技术的书。 数据库性能在规模上 被“混合云”、“无服务器”和“边缘第一”等令人印象深刻的口语所吸引,Joan迅速加入了一家新公司,并开始抓住他们的技术堆栈。 她的第一项项目最近开始从他们内部的数据库系统的实施中过渡,该系统的规模与客户数量不相同,成为行业标准数据库管理解决方案之一。 在 SQL 世界中已知的保障。 酸 由于目前每年都会出现一些新的数据保护法案,该公司的董事会决定,他们将保持自己的数据中心,而不是使用受欢迎的云供应商之一来存储敏感信息。 在非常高的水平上,该公司的主要产品仅由两个层组成: 前端,用户的入口点,实际上在他们的浏览器中运行,并与系统的其他部分进行通信,以交换和保持信息。 它通常被称为“后端”,但实际上包括负载平衡器,身份验证,授权,多个缓存层,数据库,备份等。 Joan的第一个介绍任务是实施一个非常简单的服务,从数据库中收集和总结各种统计数据,并将该服务与整个生态系统集成,以便它实时从数据库中获取数据,并允许DevOps团队实时检查统计数据。 为了给管理层留下深刻印象,并让他们放心,在本季度雇用Joan是他们绝对最好的决定,Joan决定在她的第一天提供一个概念验证的实施! 该公司的未曾说过的政策是在Rust中编写软件,所以她从短暂的crates.io搜索中抓住了他们的数据库的第一台驱动程序,然后坐下来参加了她自己组织的黑客赛。 这一天过得非常顺利,鲁斯特的精心设计的生态系统为开发人员提供了卓越的体验,但随后,Joan在一个真实的系统上进行了第一次烟雾测试,她意识到每三次请求(平均)都会出现错误,尽管整个数据库集群报告处于健康、可操作的状态。 不幸的是,司机Joan匆匆地选择了她的工作的基础,尽管开源本身只是一个薄薄的包裹,在预编译,遗传的C代码上,没有来源可以找到。 ,她做了一个受过教育的猜测,即 在公司使用的数据库中,密钥被哈希到后来的路由请求到相应的节点. 如果一个哈希值被计算错误,请求可能会被转发到错误的节点,可以拒绝它并返回错误。 威尔斯哈克 错误必须在哈希密钥实现中 由于缺少源代码,Joan无法验证这一说法,所以决定采取一个更简单的途径:放弃最初选择的驱动程序,并将该解决方案重新部署到由数据库供应商支持的官方支持的开源驱动程序之一上,具有坚实的用户基础和定期更新的发布时间表。 约翰的教训日记,第一部分 初级课程包括: 仔细选择驱动程序,它是您的代码性能、可靠性和可靠性的核心。 司机也有错误,避免它们是不可能的. 然而,有好的做法要遵循: 除非有充分的理由,否则最好选择官方支持的司机(如果有); 开源驱动程序有优点:它们不仅被社区验证,还允许对其代码进行深入检查,甚至修改驱动程序代码以获得更多的解调洞察。 最好依靠具有良好的发布时间表的驱动程序,因为他们更有可能在合理的时间内收到错误修复(包括安全漏洞)。 3. Wireshark 是一个伟大的开源工具来解释网络包;如果你想在你的程序的帽子下看一试。 入门任务最终成功完成,让Joan准备好接受她的第一个真正的任务。 《Tuning》 凭借在介绍任务上获得的经验,Joan开始计划如何接近她的新任务:一个不良行为的应用程序.其中一个应用程序臭名昭着地导致了整个系统的稳定性问题,每次遇到任何问题,都会扰乱其他工作负载。 这个特定的服务是负责将旧系统备份的数据注入新数据库的。由于公司没有急于,该应用程序是以低同步性写的,以保持低优先级,而不干扰用户的工作负载。不幸的是,每隔几天一次,有些东西继续触发异常。 通常和平的应用程序似乎试图在其自己的数据库上执行拒绝服务攻击,淹没它与请求,直到后端变得过载足以引起生态系统的其他部分的问题。 当Joan观察了Grafana仪表板中呈现的指标,清楚地表明该应用程序生成的请求率在异常发生时开始增加时,她想知道地球上这种工作负载是如何表现出来的。 由于在与现场教练的登机会议中,合作被广泛宣传为公司“精神和文化基础”之一,她决定最好与同事托尼讨论这个问题。 “你看,托尼,我不能围绕着这件事摇头,”她解释说,“当100个已经在飞行时,这个服务不会发送任何新请求。 “好吧,谢谢托尼,你是一个亲爱的 - 最好的 永远!”她结束了,回到修复代码。 橡胶鸭 导致发现根源的原因的观察非常简单:请求实际上没有 *返回* 时限错误,因为数据库服务器从来没有发回过此类响应。请求只是被驱动程序定时,并被丢弃。 有了这些知识,很容易想象,一旦客户端的一百个请求时间到期,应用程序可能会错误地认为它们不再在进行中,并且很高兴地向数据库提交100个更多请求,将飞行请求的总数增加到200个。 约翰的教训日记,第二部分 教训继续: 客户端时隔对程序员来说是方便的,但它们可能会与服务器端时隔产生不好的相互作用. 拇指规则:使客户端时隔大约是服务器端时隔的两倍,除非你有非常好的理由这样做。 在某些意想不到的条件下,看似固定一致的任务实际上可能会导致峰值。检查日志和仪表板有助于调查此类情况,因此请确保数据库集群和所有客户端应用都可使用可观察性工具。 随着客户端时间的正确修改,该应用程序被窒息的频率较少,而且在较小的程度上,但它仍然不是一个完美的公民在分布式系统中。 它偶尔会选择一个受害者数据库节点,并继续以太多的请求来扰乱它,同时忽略了其他七个节点的负载较少的事实,并可能有助于处理工作负载。 在其他时候,其同步性被报告为确切的200%大于配置预期。 每当两种异常随着时间的推移而融合时,可怜的节点无法处理所有被轰炸的请求,并不得不放弃他们的一部分。 格式和保持合理的最新,帮助约翰缓解了那些痛苦。 微博 第一个问题仅仅是非默认负载平衡策略的错误配置,它试图根据数据库本身偶尔更新的 heuristics 和统计数据,从所有可用的数据库中选择“最少负载”的数据库节点。 不幸的是,这项政策也是“最好的努力”,并依靠来自数据库的统计数据始终是合法的 - 但是受到压力的数据库节点可能会变得如此过载,以至于它没有及时发送更新的统计数据! 这导致司机错误地认为这个特定的服务器根本没有忙碌。 第二个问题(暂时加倍的汇率)是由另一个错误的配置引起的:一个过度的投机重复政策。在等待一个预先配置的时间,而没有从数据库中获得认可后,司机将投机重复请求,以最大限度地提高其成功机会。这个机制非常有用,以增加请求的成功率。然而,如果原来的请求也成功,这意味着投机的请求是徒劳的。为了平衡优点和缺点,投机重复应配置为只重复请求,如果原来的请求非常有可能失败。否则,就像约翰的情况下一样,投机重复可能会很快行动,发送的请求数量翻了一番(从而也翻了一番)而不会改善成功率。 Whew,没有什么会像质量调试会一样同时产生内分子和多巴胺的冲击,最终取得了惊人的成功(除了在一本深度技术性的书中写出一本辛辣的故事之外)。 结局。 如果你做到了这一点,不能得到足够的奶酪数据库性能故事,看看可怜的老帕特里克发生了什么。 “如果你欣赏这种幽默感,看看彼得的作品。 . Editor’s note: 数据库表现的悲伤故事:帕特里克的不幸的绿色费多拉斯 关于写工程博客的新书