高可用

1. 什么是高可用

高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间

假设系统一直能够提供服务,我们说系统的可用性是100%。

如果系统每运行100个单位时间,会有1个单位时间无法提供服务,我们说系统的可用性是99%。

很多公司的高可用目标是4个9,也就是99.99%,这就意味着,系统的年停机时间为8.76个小时。

2. 如何保障系统的高可用

单点是系统高可用的大敌,单点往往是系统高可用最大的风险和敌人,应该尽量在系统设计的过程中避免单点。方法论上,高可用保证的原则是“集群化”,或者叫“冗余”:只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他backup能够顶上。

保证系统高可用,架构设计的核心准则是:冗余;有了冗余之后,还不够,每次出现故障需要人工介入恢复势必会增加系统的不可服务时间,所以,又往往是通过“自动故障转移”来实现系统的高可用。

3. 实践高可用

3.1 客户端层->反向代理层的高可用

客户端层到反向代理层的高可用,是通过反向代理层的冗余来实现的,以nginx为例:有两台nginx,一台对线上提供服务,另一台冗余以保证高可用,常见的时间是keepalived存活探测,相同Virtual IP提供服务。

自动故障转移:当nginx挂了的时候,keepalived能够探测到,会自动的进行故障转移,将流量自动迁移到shadow-nginx,由于使用的是相同的Virtual IP,这个切换过程对调用方是透明的。

3.2 反向代理层->站点层的高可用

反向代理层到站点层的高可用,是通过站点层的冗余来实现的,假设反向代理层是nginx,nginx.conf里能够配置多个web后端,并且nginx能够探测到多个后端的存活性。

自动故障转移:当web-server挂了的时候,nginx能够探测到,会自动的进行故障转移,将流量自动迁移到其他的web-server,整个过程由nginx自动完成,对调用方式透明的。

3.3 站点层->服务层的高可用

站点层到服务层的高可用,是通过服务层的冗余来实现的。“服务连接池”会建立与下游服务多个连接,每次请求会“随机选取连接来访问下游服务”

自动故障转移:当service挂了的是,service-connection-pool能够探测到,会自动的进行故障转移,将流量自动迁移到其他的service,整个过程由连接池自动完成,对调用方是透明的。

3.4 服务层->缓存层的高可用

服务层到缓存层的高可用,是通过缓存数据的冗余来实现的。

缓存层的数据冗余又有几种方式:第一种是利用客户端的封装,service对cache进行双读或双写。

缓存层也可以通过职称主从同步的缓存集群来解决缓存层的高可用问题。

以redis为例,redis天然支持主从同步,redis官方也是sentinel哨兵机制,来做redis的存活性检测。

自动故障转移:当redis-master挂了的时候,sentinel能够探测到,会通知调用方访问新的redis,整个过程由sentinel和redis集群配合完成,对调用方是透明的。

说完缓存的高可用,这里要多说一句,业务对缓存并不一定有“高可用”要求,更多的对缓存的使用场景,是用来“加速数据访问”:把一部分数据放到缓存里,如果缓存挂了或者缓存没有命中,是可以去后端的数据库中再取数据的。

这类允许“cache miss”的业务场景,缓存架构的建议是:

 

将kv缓存封装成服务集群,上游设置一个代理(代理可以用集群冗余的方式保证高可用),代理的后端根据缓存访问的key水平切分成若干个实例,每个实例的访问并不做高可用。

缓存实例挂了屏蔽:当有水平切分的实例挂掉时,代理层直接返回cache miss,此时缓存挂掉对调用方也是透明的。key水平切分实例减少,不建议做re-hash,这样容易引发缓存数据的不一致。

3.5 服务层->数据库层的高可用

大部分互联网技术,数据库层都用了“主从同步,读写分离”架构,所以数据库层的高可用,又分为“读库高可用”与“写库高可用”两类。

服务层->数据库层“读”的高可用

服务层到数据库读的高可用,是通过读库的冗余来实现的。

既然冗余了读库,一般来说就至少有2个从库,“数据库连接池”会建立与读库多个连接,每次请求会路由到这些读库。

自动故障转移:当读库挂了的时候,db-connection-pool能够探测到,会自动的进行故障转移,将流量自动迁移到其他的读库,整个过程由连接池自动完成,对调用方是透明的。

服务层->数据库层“写”的高可用

服务层到数据库写的高可用,是通过写库的冗余来实现的。

以mysql为例,可以设置两个mysql双主同步,一台对线上提供服务,另一台冗余以保证高可用,常见的实践是keepalived存活探测,通过Virtual IP提供服务。

自动故障转移:当写库挂了的是,keepalived能够探测到,会自动的进行故障转移,将流量自动迁移到shadow-db-master,由于使用的是相同的Virtual IP,这个切换过程对调用方是透明的。

 

posted @ 2018-08-22 11:05  小路不懂2  阅读(284)  评论(0编辑  收藏  举报