高可用系统怎么来设计呢

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 《高可用》系列

什么是高可用?可用性的判断标准是啥?

高可用描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的。

一般情况下,我们使用多少个 9 来评判一个系统的可用性,比如 99.9999% 就是代表该系统在所有的运行时间中只有 0.0001% 的时间是不可用的,这样的系统就是非常非常高可用的了!当然,也会有系统如果可用性不太好的话,可能连 9 都上不了。

除此之外,系统的可用性还可以用某功能的失败次数与总的请求次数之比来衡量,比如对网站请求 1000 次,其中有 10 次请求失败,那么可用性就是 99%。

哪些情况会导致系统不可用?

  1. 黑客攻击;
  2. 硬件故障,比如服务器坏掉。
  3. 并发量/用户请求量激增导致整个服务宕掉或者部分服务不可用。
  4. 代码中的坏味道导致内存泄漏或者其他问题导致程序挂掉。
  5. 网站架构某个重要的角色比如 Nginx 或者数据库突然不可用。
  6. 自然灾害或者人为破坏。
  7. ......

有哪些提高系统可用性的方法?

注重代码质量,测试严格把关

我觉得这个是最最最重要的,代码质量有问题比如比较常见的内存泄漏、循环依赖都是对系统可用性极大的损害。大家都喜欢谈限流、降级、熔断,但是我觉得从代码质量这个源头把关是首先要做好的一件很重要的事情。如何提高代码质量?比较实际可用的就是 CodeReview,不要在乎每天多花的那 1 个小时左右的时间,作用可大着呢!

另外,安利几个对提高代码质量有实际效果的神器:

使用集群,减少单点故障

先拿常用的 Redis 举个例子!我们如何保证我们的 Redis 缓存高可用呢?答案就是使用集群,避免单点故障。当我们使用一个 Redis 实例作为缓存的时候,这个 Redis 实例挂了之后,整个缓存服务可能就挂了。使用了集群之后,即使一台 Redis 实例挂了,不到一秒就会有另外一台 Redis 实例顶上。

限流

流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。——来自 alibaba-Sentinelopen in new window 的 wiki。

超时和重试机制设置

一旦用户请求超过某个时间的得不到响应,就抛出异常。这个是非常重要的,很多线上系统故障都是因为没有进行超时设置或者超时设置的方式不对导致的。我们在读取第三方服务的时候,尤其适合设置超时和重试机制。一般我们使用一些 RPC 框架的时候,这些框架都自带的超时重试的配置。如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法再处理请求。重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。

熔断机制

超时和重试机制设置之外,熔断机制也是很重要的。 熔断机制说的是系统自动收集所依赖服务的资源使用情况和性能指标,当所依赖的服务恶化或者调用失败次数达到某个阈值的时候就迅速失败,让当前系统立即切换依赖其他备用服务。 比较常用的流量控制和熔断降级框架是 Netflix 的 Hystrix 和 alibaba 的 Sentinel。

异步调用

异步调用的话我们不需要关心最后的结果,这样我们就可以用户请求完成之后就立即返回结果,具体处理我们可以后续再做,秒杀场景用这个还是蛮多的。但是,使用异步之后我们可能需要 适当修改业务流程进行配合,比如用户在提交订单之后,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功。除了可以在程序中实现异步之外,我们常常还使用消息队列,消息队列可以通过异步处理提高系统性能(削峰、减少响应所需时间)并且可以降低系统耦合性。

使用缓存

如果我们的系统属于并发量比较高的话,如果我们单纯使用数据库的话,当大量请求直接落到数据库可能数据库就会直接挂掉。使用缓存缓存热点数据,因为缓存存储在内存中,所以速度相当地快!

其他

  • 核心应用和服务优先使用更好的硬件
  • 监控系统资源使用情况增加报警设置。
  • 注意备份,必要时候回滚。
  • 灰度发布: 将服务器集群分成若干部分,每天只发布一部分机器,观察运行稳定没有故障,第二天继续发布一部分机器,持续几天才把整个集群全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可
  • 定期检查/更换硬件: 如果不是购买的云服务的话,定期还是需要对硬件进行一波检查的,对于一些需要更换或者升级的硬件,要及时更换或者升级。
  • .....

冗余

冗余设计是保证系统和数据高可用的最常的手段


对于服务来说,冗余的思想就是相同的服务部署多份,如果正在使用的服务突然挂掉的话,系统可以很快切换到备份服务上,大大减少系统的不可用时间,提高系统的可用性。

对于数据来说,冗余的思想就是相同的数据备份多份,这样就可以很简单地提高数据的安全性。

实际上,日常生活中就有非常多的冗余思想的应用。

拿我自己来说,我对于重要文件的保存方法就是冗余思想的应用。我日常所使用的重要文件都会同步一份在 Github 以及个人云盘上,这样就可以保证即使电脑硬盘损坏,我也可以通过 Github 或者个人云盘找回自己的重要文件。

高可用集群(High Availability Cluster,简称 HA Cluster)、同城灾备、异地灾备、同城多活和异地多活是冗余思想在高可用系统设计中最典型的应用。

  • 高可用集群 : 同一份服务部署两份或者多份,当正在使用的服务突然挂掉的话,可以切换到另外一台服务,从而保证服务的高可用。
  • 同城灾备 :一整个集群可以部署在同一个机房,而同城灾备中相同服务部署在同一个城市的不同机房中。并且,备用服务不处理请求。这样可以避免机房出现意外情况比如停电、火灾。
  • 异地灾备 :类似于同城灾备,不同的是,相同服务部署在异地(通常距离较远,甚至是在不同的城市或者国家)的不同机房中
  • 同城多活 :类似于同城灾备,但备用服务可以处理请求,这样可以充分利用系统资源,提高系统的并发。
  • 异地多活 : 将服务部署在异地的不同机房中,并且,它们可以同时对外提供服务。

高可用集群单纯是服务的冗余,并没有强调地域。同城灾备、异地灾备、同城多活和异地多活实现了地域上的冗余。

同城和异地的主要区别在于机房之间的距离。异地通常距离较远,甚至是在不同的城市或者国家。

和传统的灾备设计相比,同城多活和异地多活最明显的改变在于“多活”,即所有站点都是同时在对外提供服务的。异地多活是为了应对突发状况比如火灾、地震等自然或者人为灾害。

光做好冗余还不够,必须要配合上 故障转移 才可以! 所谓故障转移,简单来说就是实现不可用服务快速且自动地切换到可用服务,整个过程不需要人为干涉。

举个例子:哨兵模式的 Redis 集群中,如果 Sentinel(哨兵) 检测到 master 节点出现故障的话, 它就会帮助我们实现故障转移,自动将某一台 slave 升级为 master,确保整个 Redis 系统的可用性。整个过程完全自动,不需要人工介入。我在《Java 面试指北》open in new window的「技术面试题篇」中的数据库部分详细介绍了 Redis 集群相关的知识点&面试题,感兴趣的小伙伴可以看看。

再举个例子:Nginx 可以结合 Keepalived 来实现高可用。如果 Nginx 主服务器宕机的话,Keepalived 可以自动进行故障转移,备用 Nginx 主服务器升级为主服务。并且,这个切换对外是透明的,因为使用的虚拟 IP,虚拟 IP 不会改变。我在《Java 面试指北》open in new window的「技术面试题篇」中的「服务器」部分详细介绍了 Nginx 相关的知识点&面试题,感兴趣的小伙伴可以看看。

异地多活架构实施起来非常难,需要考虑的因素非常多。本人不才,实际项目中并没有实践过异地多活架构,我对其了解还停留在书本知识。

如果你想要深入学习异地多活相关的知识,我这里推荐几篇我觉得还不错的文章:

不过,这些文章大多也都是在介绍概念知识。目前,网上还缺少真正介绍具体要如何去实践落地异地多活架构的资料。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
10月前
常见系统及架构
常见系统及架构
45 0
|
负载均衡 关系型数据库 RDS
良好架构设计中的可靠性:高可用、容错、灾难恢复
良好架构设计支柱 云计算良好架构设计有五大支柱,分别是:安全性,可靠性,性能效率,成本优化和卓越操作。其中可靠性是指系统从基础设施或者服务故障当中实现恢复、以动态方式获取计算资源以满足需求,以及缓解配置错误或者暂时性网络问题等干扰因素的能力。
4527 0
|
2月前
|
存储 运维 监控
如何设计高可用的分布式系统
【7月更文挑战第29天】设计高可用的分布式系统是一个复杂而细致的过程,需要从架构设计、冗余策略、故障转移与恢复、监控与告警等多个方面综合考虑。通过采用微服务架构、无状态服务、负载均衡、数据冗余、服务冗余、跨地域部署等策略,可以显著提高系统的可用性和可靠性。同时,建立完善的监控和告警体系,确保对系统的任何变化都能及时感知和处理。最终,通过不断的优化和改进,实现系统的高可用性目标。
|
2月前
|
运维 负载均衡 监控
如何设计一个高可用的分布式系统?
如何设计一个高可用的分布式系统?
|
3月前
|
负载均衡 监控 网络协议
高可用架构设计
高可用架构设计
154 1
|
3月前
|
弹性计算 负载均衡 Java
如何设计一个高可用的Java应用架构
如何设计一个高可用的Java应用架构
|
存储 消息中间件 运维
高可用架构和系统设计思想
本文从研发规范层面、应用服务层面、存储层面、产品层面、运维部署层面、异常应急层面这六大层面去剖析一个高可用的系统需要有哪些关键的设计和考虑
|
11月前
|
缓存 监控 容灾
0-1设计高可用、高并发、高伸缩的分布式项目架构
0-1设计高可用、高并发、高伸缩的分布式项目架构
【系统概念】容错、高可用和灾备
容错,高可用、灾备这三个词的使用环境极易被混淆。很多时候以为这三个词的意思是相同的。
265 0
【系统概念】容错、高可用和灾备
|
消息中间件 监控 算法
高可用怎么设计呢
《高可用》系列
169 0
高可用怎么设计呢