文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

分布式数据库系统的容错处理 – 100% 成功率, 超时和性能

2024-12-03 03:17

关注

之前写过一篇文章, 介绍"可靠通信三原则". 对于一个分布式数据库, 如果想实现 100% 高可用(也即客户端的请求永远不会返回失败), 同样可以用可靠通信三原则中的重试理论和去重理论来解决. 但在实践上, 需要在成功率, 耗时(速度和性能)各方面进行取舍. 本文分享实际经验, 介绍什么样的选择是普适的, 各位可以参考.

客户端访问数据库服务器, 发起大量的请求, 绝对不可能做到每一个请求都是成功的. 因为网络原因, 请求可能失败. 因为服务器内部处理冲突, 或者分布式节点间协调冲突, 都可能导致请求失败.

所谓容错处理, 就是在遇到错误的时候进行重试. 因为错误必然发生, 只有重试才能消除错误的影响, 就好像 IP 层必然会丢包, 但 TCP 协议通过重传达到某种程度的可靠传输.

某些实现了 Basic Paxos + 日志复制状态机模型的系统, 因为所谓的"Leaderless", 会产生大量冲突. 即使是使用 Raft, 在某些情况下意外发生选举, 也会导致请求冲突.

面对冲突(失败)到底应该由谁来重试呢? 这涉及到工程实践上模块职责划分的问题, 模块职责的划分, 往往比代码实现更重要. 一般来说, 发生重试的位置越底层, 性能会越好; 发生重试的位置越上层, 判断是否应该重试的依据就能更全面.

我们简单把数据库系统(生态)划分为几个大的模块, 从底层(左)到上层(右)是:

  1. replication -> server -> client SDK -> user 

最常见的做法是让 user 自己重试, 例如常见的 Redis SDK, 如果某台 server 宕机导致请求失败, 那么要求用户换一个 IP, 重新创建连接, 再次重复请求.

某些系统会封装专属的 client SDK, 例如, 把官方的 Redis SDK 做一下简单封装, 拦截每一个请求的结果, 如果发现错误, SDK 内部就自动重试. 这样做, user 就不需要有重试逻辑, 代码可以简化. 是这样的, 多个协作的模块, 如果某个模块揽了一些职责, 那它的上层模块就能省些工夫.

如果 user 既不想重试, client SDK 也不想重试, 那怎么办呢? 能不能把职责全推给 server 呢? 绝对不可能, 参见这篇文章的总结. 那么, 为什么 SDK 重试之后, user 就不需要重试呢? 因为 SDK 和 user 是在同一个运行空间内, 它们是一个整体, 两者之间没有可靠传输问题.

那么, 既然 client SDK 必须有重试逻辑, server 是否就不需要有重试逻辑了呢? 理论上可以, 但实践上, server 自身依然要降低自己的故障率, 降低故障率的必要手段就是 重试 . 例如, server 请求 paxos 模块同步一条操作日志, 但因为非预期的 multi-master 出现, 导致和其它节点争抢同一个位置失败, 这时, server 如果直接报错给 client, 那么, server 的故障数量就加一. 但是, server 可以重试, 再次调用 paxos 模块, 去争抢下一个位置, 直到成功. 这样, client 就会很少见到 server 报错.

但是, 无论是 server 还是 client 都不可能无限次重试, 因为每一次重试都会消耗时间, 最极端的情况可能要重试几个小时直到永远, 这当然不行, 所以, 需要引入 超时机制 , 重试一定次数之后即使还是失败, 也必须报错给上层.

重试会增加总的耗时, 这样, 给上层带来的不好效果就是, 上层觉得下层速度慢, 性能差. 所以, 必须有系统思维, 做出判断, 做综合的取舍. 从经验上看, 无论 server 还是 client SDK, 都必须分析细化, 尽可能重试, 以提高成功率. 大部分情况下, 开发者往往过多地放弃重试, 而较少地进行重试, 毕竟, 多一种重试场景, 就多写一段代码, 人总是会想偷懒的.

要设计一个高可靠的系统, 可靠传输三原则是非常有用的基础理论, 但不是银弹. 本质上, 软件开发就是大量的分析细化体力活, 以及对系统复杂度的把控.

重试带来的额外问题就是去重, 这也是可靠传输三原则里的第二项原则. 你可能听过"幂等性"这个词汇, 和去重是一回事. 如果一个操作是非幂等的, 那么, 就不能重试.

但是, 实践上, 我们可以把幂等性的职责向上推, 尽可能推给上层. 毕竟, 至少对于 user 来说, 100% 的成功率, 优先级比对幂等性的疑虑要高得多. 用户同意下层不考虑幂等性, 而大胆地去重试, 但是, 对下层偶然的失败会非常敏感. 简单说就是: 别管什么幂等性, 在超时时间限制以内, 大胆重试!

来源:idea's blog内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯