隔离设计Bulkheads

隔离设计(Bulkheads)

隔离设计其目的在于减少故障发生的概率,或者说是和整个系统解耦合,有点这个意思。隔离设计是针对整个系统来说的,隔离服务,隔离用户,隔离数据,隔离等等,应该还是会有其他的,大佬只写了这三个核心,根据自我需求的,感觉挺灵活的。。。

隔离的是可能发生故障的点,我觉得格局小点,我自己的app,不是各系统,也可以使用,这个设计太灵活了。。。。。。

大佬写的是以服务,用户,数据为核,隔离用户,隔离服务,这两个隔离融合这三个方面,隔离服务,看了个评论,评论大佬说他做的是健身的app,我觉得太合适了,vip,普通用户,各种卡用户,你想要什么服务,给你就是,enmmm….

目前的疑问,是如果只在自己的独立项目上做隔离设计,不是个系统的话,都是用于那些情况呢?欢迎各位大佬评论下。。。。。。。

下面来正文喽

首先,这个起源得说下,来自船体设计,隔离设计对应的单词是 Bulkheads,中文翻译为隔板。但其实,这个术语是用在造船上的,也就是船舱里防漏水的隔板。一般的船无论大小都会有这个东西,大一点的船都会把船舱隔成若干个空间。这样,如果船舱漏水,只会进到一个小空间里,不会让整个船舱都进水而导致整艘船都沉了,如下图所示。

此图以及本文中的大多数文字来自左耳听风专栏,在此缅怀一下,是个大佬啊。。。。。。

我们的软件设计当然也“漏水”,所以为了不让“故障”蔓延开来,需要使用“隔板”技术,来将架构分隔成多个“船舱”来隔离故障。(隔离设计作用就显而易见了)

按服务的种类来做分离

下图表示作用很明确。

 

我们将系统分成了用户、商品、社区三个板块。

这三个块分别使用不同的域名、服务器和数据库,做到从接入层到应用层再到数据层三层完全隔离。

这样一来,在物理上来说,一个板块的故障就不会影响到另一板块。(这是它的优势。)

不足在于如果我们需要同时获得多个板块的数据,那么就需要调用多个服务,这会降低性能。注意,这里性能降低指的是响应时间,而不是吞吐量(相反,在这种架构下,吞吐量可以得到提高)。

也即是多个模块的互相调用接口获取数据的时候,因为数据库都是独立的,因此响应时间会有影响,至少读写数据的时候不是访问同一个数据库就能搞定的,数据读写速度应该是看各个数据库的读写数据速度,应该是和模块耦合关系不是很大吧。

对于这样的问题,一般来说,我们需要小心地设计用户交互,最好不要让用户在一个页面上获得所有的数据。

(这一点至关重要,我现在遇到这个问题,还没想好怎么解决,如果让用户在一个界面获取所有数据势必界面卡死,CPU负荷率直冲100%,我听这个现在都晕,哈哈哈哈哈哈。)

这个问题的解决方案,如下,

  1. 如果有大数据平台,就需要把这些数据都抽取到一个数据仓库中进行计算,这也增加了数据合并的复杂度。对于这个问题,我们需要一个框架或是一个中间件来对数据进行相应的抽取。
  2. 另外,如果我们的业务逻辑或是业务流程需要跨板块的话,那么一个板块的故障也会导致整个流程走不下去,同样会导致整体业务故障。对于这个问题,一方面,我们需要保证这个业务流程中各个子系统的高可用性,并且在业务流程上做成 Step-by-Step 的方式,这样用户交互的每一步都可以保存,以便故障恢复后可以继续执行,而不是从头执行。

(这个就有点像火车,一节故障,但是火车照跑,很稳啊。。。故障处理完,那节火车在接上,emmm,不必要从头开始,挺妙的,如果按照容器的思维,这就是个链表,问题在于查找不便,100节的火车,第一节就出现故障,那需要遍历这个链表-1,有点问题)

  1. 还有,如果需要有跨板块的交互也会变得有点复杂。对此我们需要一个类似于 Pub/Sub 的高可用、且可以持久化的消息订阅通知中间件来打通各个板块的数据和信息交换。
  2. 最后还会有在多个板块中分布式事务的问题。对此,我们需要“二阶段提交”这样的方案。在亚马逊中,使用的是 Plan – Reserve – Commit/Cancel 模式。

(也就是说,先做一个 plan 的 API 调用,然后各个子系统 reserve 住相应的资源,如果成功,则 Commit;如果有一个失败,则整体 Cancel。这其实很像阿里的 TCC – try confirm/cancel。感觉高大上,但是问题就是,各个环节不能出错,否则应该是很浪费时间吧)

可见,隔离了的系统在具体的业务场景中还是有很多问题的,是需要我们小心和处理的。对此,我们不可掉以轻心。根据我的经验,这样的系统通常会引入大量的异步处理模型。

按用户的请求来做分离

下图也很明显的表明主题,哈哈哈哈哈哈。。。。。。。。。。

在这个图中,可以看到,我们将用户分成不同的组,并把后端的同一个服务根据这些不同的组分成不同的实例。让同一个服务对于不同的用户进行冗余和隔离,这样一来,当服务实例挂掉时,只会影响其中一部分用户,而不会导致所有的用户无法访问。

(冗余设计的典型处理方式)

这种分离和上面按功能的分离可以融合。说白了,这就是所谓的“多租户”模式。对于一些比较大的客户,我们可以为他们设置专门独立的服务实例,或是服务集群与其他客户隔离开来,对于一些比较小的用户来说,可以让他们共享一个服务实例,这样可以节省相关的资源

对于“多租户”的架构来说,会引入一些系统设计的复杂度。一方面,如果完全隔离,资源使用上会比较浪费,如果共享,又会导致程序设计的一些复杂度。

通常来说多租户的做法有三种。

  1. 完全独立的设计。每个租户有自己完全独立的服务和数据。
  2. 独立的数据分区,共享的服务。多租户的服务是共享的,但数据是分开隔离的。
  3. 共享的服务,共享的数据分区。每个租户的数据和服务都是共享的。

这三种方案各有优缺点,如图所示。

  1. 如果使用完全独立的方案,在开发实现上和资源隔离度方面会非常好,然而,成本会比较高,计算资源也会有一定的浪费。VIP需要耗很多资源)
  2. 如果使用完全共享的方案,在资源利用和成本上会非常好,然而,开发难度非常大,而且数据和资源隔离非常不好。

(资源共享,目前我现在维护的这个系统应该就是,就是一种完全共享的状态吧,emmmmm,复杂度很高。。。)

所以,一般来说,技术方案会使用折中方案,也就是中间方案,服务是共享的,数据通过分区来隔离,而对于一些比较重要的租户(需要好的隔离性),则使用完全独立的方式。

然而,在虚拟化技术非常成熟的今天,我们完全可以使用“完全独立”(完全隔离)的方案,通过底层的虚拟化技术(Hypervisor 的技术,如 KVM,或是 Linux Container 的技术,如 Docker)来实现物理资源的共享和成本的节约。

隔离设计的重点:

要能做好隔离设计,我们需要有如下的一些设计考量。

  1. 我们需要定义好隔离业务的大小和粒度,过大和过小都不好。这需要认真地做业务上的需求和系统分析。(干啥啊)
  2. 无论是做系统板块还是多租户的隔离,你都需要考虑系统的复杂度、成本、性能、资源使用的问题,找到一个合适的均衡方案,或是分布实施的方案尤其重要,这其中需要你定义好要什么和不要什么。因为,我们不可能做出一个什么都能满足的系统。(鱼和熊掌不可兼得)
  3. 隔离模式需要配置一些高可用、重试、异步、消息中间件,流控、熔断等设计模式的方式配套使用。(招式套路)
  4. 不要忘记了分布式系统中的运维的复杂度的提升,要能驾驭得好的话,还需要很多自动化运维的工具,尤其是使用像容器或是虚拟机这样的虚拟化技术可以帮助我们更方便地管理,和对比资源更好地利用。否则做出来了也管理不好。(好维护)
  5. 最后,你需要一个非常完整的能够看得到所有服务的监控系统,这点非常重要。(监控什么呢?数据还是资源使用状态?这个还没涉及到。。。)

总的来说隔离设计是个很灵活的设计模式,不光是对系统,一个小应用也是可以用的。。。。。。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值