如何设计高可用性应用程序


10

当前,我们有一个经典的n层应用程序:DB / Web服务/前端。它具有其他组件,但这是基本布局。

我们要提高应用程序可用性的原因有3个:

  1. 我们的主机有时会遇到中断(就像它们一样),我们希望最大程度地减少对客户的影响,因此,例如,如果数据中心A关闭,他们将打开数据中心B。
  2. 升级版本时,我们会关闭站点进行维护,通常需要几个小时(迁移脚本等)。我们希望用户进行更无缝的过渡,并尽可能减少停机时间(他们在升级服务器A时使用服务器B)。
  3. 可选地,我们的客户遍布世界各地,尽管他们之间的联系不畅,我们希望他们能获得最好的体验(与印度开发人员合作的任何人都应该明白我的意思)。理想情况下,我们希望能够在其办公室中插入服务器(或使用其所在城市附近的数据中心),并将其无缝集成到我们的体系结构中。

我们远程不需要99%的可用性,甚至不需要95%的可用性。这是一个文档管理应用程序。没人在乎。但是,由于迁移可能需要一段时间,并且世界各地都有客户,因此有时我们会阻止客户在一天的大部分时间里工作。

对于SQL部分,即使没有“适当的” DBA,我们也了解SQL的可能性:复制,镜像等。在DB端,为此很容易找到资源。还有什么更困难的了:存储会话,代码等。如果我的Web服务服务器出现故障,我的UI如何知道它必须切换?我的会话如何在服务器之间持久化?

不幸的是,我们都没有这方面的经验,我们甚至都不知道从哪里开始。是否有最佳做法?设计模式?图书馆(应该是免费的,因为我们没有钱)?

我们使用的是ASP.Net和SQL Server,中间是WCF Web服务。我们有很多Windows服务,但它们不是关键任务,我认为处理网站的方法将适用于这些服务。

我知道大多数云平台都为此提供了内置系统,但是由于我们的系统管理员,云托管是行不通的,他想自己管理一切而不依赖任何人。


1
“如果他们突然决定将我们的数据出售给竞争对手,该怎么办?” 真?那是他们最好的论点?1)可以肯定那将是非法的。2)没有信誉好的托管服务提供商会这样做(那会损害他们的整个业务)。3)如果您真的很担心,请确保任何已签署的协议均禁止此类行为,并在违反协议时提起诉讼。4)加密您的数据。5)是什么阻止您当前的主机执行相同的操作?
Becuzz

1
认真地说,避免为您想要的东西使用预先构建的东西只会导致问题。您将必须学习每节课,以了解如何正确托管这些提供商已经学习的高可用性系统。而且您可能将没有足够的资源和专业知识来对问题进行响应。如果您(或系统管理员)仍然坚持这样做,请研究负载平衡,非内存会话存储(如SQL会话存储),自动部署等
。– Becuzz

图书馆费用将是最少的费用
Dan Pichelman

@Becuzz:我在这里有点夸张,但是(在我看来)他们对云托管的看法大多是毫无根据和不合逻辑的。他们几乎认为自己比大多数托管人都更好。我能说什么 第二点,我们不反对使用库,但是它必须是免费的或便宜的,因为我们没有预算。
thomasb

1
高可用性成本(包括资本支出和运营支出)是因为您需要冗余硬件以及大量的dev&devops工作才能使高可用性工作-如果您没有购买某些工具的预算,我怀疑您能否负担得起不断发展和运营高可用性设置的费用。
Frederik

Answers:


5

您需要弄清楚您要寻找哪种高可用性。我运行的高可用性应用程序需要运行95%的时间。还有其他一些需要以99%的速度运行。我可以想到需要100%正常运行时间的生死攸关的场景。只有这三个方法和成本完全不同。

只是根据您的需求和95-99%的正常运行时间服务水平(SLA)进行猜测:

  • 对于大多数更改,数据库迁移应该能够实时进行。实践进化数据库设计。对于确实需要更具侵入性的行为的更改,您有几种选择。一种是停工期。如果可能,以只读模式运行服务可能会起作用。为了获得全部功能,我一直想尝试ScaleArc。在SQL Server世界中,它看起来像是一个用于扩展和恢复弹性的好工具。
  • 除非您拥有世界一流的部署策略(根据您对迁移的描述,还没有),否则将服务器放置在客户站点内是造成灾难的原因。不要在本地部署云服务,因为您会遇到性能问题。立即解决性能问题,然后您就不必再面对成本更高的问题了。
  • 您的状态服务器应该是某种数据库。遵循其HA准则。您可以为此使用SQL Server,因为您已经可以使用它了。
  • 说到数据库,复制不会启用HA。实际上,SQL复制将使您无所适从(从多节点复制方案的经验中得知)。镜像可以工作,但是最后我记得,SQL群集需要1-5分钟才能故障转移到新服务器。我听说过有关AlwaysOn的好消息,但鉴于Microsoft的往绩,我仍然感到怀疑。像ScaleArc之类的东西可能会在这里提供更多帮助。
  • 您的Web服务器应该是无状态的。旋转三到四个,然后将它们放在负载均衡器后面。那解决了您的正常运行时间烦恼。正如Frederik前面提到的,您还可以通过这种方式进行滚动部署。
  • 您的Web服务可能应该是无状态的。如果不是,请查看是否可以将其分解为无状态位和有状态位。再次将它的多个实例放在同一个负载均衡器之后,可以解决正常运行时间的烦恼,并启用更多感兴趣的部署方案(例如,蓝色/绿色部署)。

与Frederik不同,我不会无缘无故地称呼您的云偏执狂。这取决于您的正常运行时间要求。可以想象,出于冗余的考虑,服务必须在不同国家/地区的不同提供商运营的多个数据中心中运行。但是,鉴于您当前的状态,我同意AWS,Azure或类似产品对您的公司来说是安全的选择。


1
关于本地安装:这不是性能问题,而是客户的带宽问题。它们可能位于不稳定或缓慢连接的地方。但这不是一个重要的功能。谢谢您的休息,我会研究一下(他们吗?)
thomasb

5

在您的Web和应用程序层上获得一定程度的HA:

  1. 理想情况下,将任何状态(包括会话状态)排除到共享状态系统(如数据库或内存中的会话状态服务器)中。根据您的应用程序设计,这可能会导致性能问题,因为增加的延迟会导致大量状态。

  2. 您的网站和应用程序层每个都应在其前面具有一个独立的负载平衡器。NGINX可以解决这个问题,但是IIS也可以做到这一点(ARR)。

  3. 如果单个数据库无法处理负载,请利用会话状态分区(或分片或一致性哈希)将特定请求路由到特定数据库框。

如果分解状态太困难,则可以使用服务器关联性来实现负载平衡(即,用户始终被路由到同一框,通常基于cookie)。它的可用性不如无状态循环机制高,因为一次包装中断将影响该包装盒上的所有用户和状态,但是却击败了一次完整的停机(取决于用例)。

在升级方面:

  1. 设计数据库脚本的方式应使数据库可以在系统运行时进行升级,也就是说,保持向后兼容性。一种有效的模式是“扩展,然后收缩”->仅进行累加的,向后兼容的更改,但删除要摆脱的字段(等)上的依赖项;然后将数据库的所有客户端升级到v-latest;然后再执行一次db-upgrade以摆脱数据库中的旧字段(等)。如果您的数据库很大,那么这可能是一个很慢的过程,并且必须注意不要破坏系统的性能。

  2. 升级您的应用程序层:由于您未使用云环境,因此我建议您遵循Canary部署模式:对Web和中间层设备进行滚动升级。如果部署出错,则将盒子从负载均衡器中取出,就像失败一样。

警告:将尚未为HA设计的系统演变为一个系统可能是一个漫长而昂贵的过程。您必须在此过程中做出权衡(为了达到特定级别的可用性而付出的成本与精力)

您的云偏执症是不必要的-AWS等提供商以及您的良好实践可以控制/减轻大多数风险-查看其合规性页面以了解其所遵循的法规:https:// aws .amazon.com / compliance /


1

TL; DR:构建冗余,模块化;测试可用性;密切监视。

意识到尝试挤压任何解释可能会花费很长时间,因此我将写下所有观察结果。

质疑前提

云系统是灵丹妙药

即使您要与顶级云提供商一起完全在云上运行,您仍然需要彻底设计应用程序的弹性。AWS可能会替换您的VM,但是如果将应用程序放在计算的中间,则它应该能够重新启动。

由于x / y / z,我们不想使用云系统

除非您是一个超大型组织,否则使用云系统会更好。排名前三的云系统(AWS,MSFT,Google)聘请了数千名工程师,为您提供承诺的SLA和易于管理的仪表板。使用它们代替在此内部花费一毛钱实际上是一个很好的交易。

范围设计中的问题

与为可用性问题编写解决方案相比,定义,量化然后连续衡量服务的可用性是一个更大的挑战。

定义和衡量“可用性”比预期的要难

多个利益相关者对可用性的看法不同,可能发生的事情是薪水最高的人所喜欢的定义胜过其他定义。有时这是正确的定义,但生态系统通常不是围绕测量同一事物建立的,因为理想的定义很难衡量,更不用说实时监视了。如果您具有无法实时监控的可用性定义,那么您会一次又一次地发现自己做的类似项目具有令人毛骨悚然的相似性。坚持有意义且易于监控的内容。

人们低估了始终可用的系统的复杂性。

为了解决房间里的大象问题,我要这样说:“没有多计算机系统可以100%可用,将来可能会出现,但当前的技术可能无法使用。” 在这里,以当前的技术,我指的是我们无法发送信号的速度快于光速和类似事物的速度。所有精打细算的comp-sci工程师都知道分布式计算的局限性,他们中的大多数人都不会在会议中提及它,因为他们担心自己看起来像菜鸟。为了弥补那些没有提到分布式计算限制的人,我会说,它很复杂但并不总是信任计算机

人们高估了他们/他们的工程师的能力

不幸的是,可用性属于类别,您不知道自己想要什么,但知道自己不想要什么。“了解需求”类别(例如UI)有点棘手。它需要一点经验和大量阅读才能从他人的经验中学习以及更多。

从头开始构建可用系统

确保向每个体系结构和设计团队宣传将可用性作为系统需求的正确优先事项。

系统帮助可用性的属性

已显示以下系统特性有助于系统可用性:

冗余

这样的一些示例是,在VIP后面永远不要只有一个VM,也不要只存储一个数据副本。这些是好的IAAS可以使您更容易解决的问题,但是您仍然必须做出这些决定。

模块化

模块化REST比单片SOA更好。实际上,甚至比常规的HATEOS REST还提供模块化的微服务。可以在下一部分的与收益率相关的讨论中找到其理由。如果要进行批处理,那么与处理1,000,000批处理相比,最好在合理的10s批处理中进行批处理。

弹性

"I am always angry"
                    - Hulk

弹性系统随时可以恢复。这种弹性适用于实例,例如仅在写入RAID磁盘之后(可能至少在两个数据中心上)确认对写入的ACK。另一个最新趋势是使用无冲突的数据结构,其中当出现两种不同版本时,数据结构承担解决冲突的责任。系统不能像事后那样具有弹性,必须对其进行预测和内置。长期保证会发生故障,因此我们应该始终为恢复计划做好准备。

日志记录

从技术上讲,这是弹性的一种子类型,但由于它具有所有功能,因此是一种非常特殊的类型。尽管已尽了最大努力,但我们可能无法预测不可用的模式。如果可能,请保留足够的系统活动日志记录,以便能够回放系统事件。这将花费大量的人工,使您能够从无法预料的情况中恢复。

可用性的属性

“可用性”的非穷尽性的优先考虑属性列表:为了便于讨论,让我们假设用户问的问题是:“我的购物车中有多少个商品?”

正确性

您是否必须提供最准确的答案,还是可以犯错误?仅供参考,当您从ATM取款时,并不能保证它是正确的。如果银行发现做错了,您可能会撤消交易。如果您的系统正在生成质数,那么我想,您可能一直希望得到正确的答案。

产量

如果您对上一个主题的问题回答总是正确,请跳过这一点。有时,对问题的答案不一定是精确的,例如,我现在在Facebook上有几个朋友?但是,答案始终是+/- 1。当您产生预期的结果时,您的收益为100。

一致性

您的答案在某个时间点可能是正确的,但是当光线离开屏幕并进入观察者的视网膜时,情况可能已经改变。它使您的答案错误吗?不,这只会导致不一致。大多数应用程序最终都是一致的,但是诀窍在于定义您的应用程序将要提供什么样的一致性模型。偶然地,您的应用程序可以在单台计算机上运行,​​您可以跳过CAP定理上的这一可爱的读物。

成本

很大程度上取决于短期影响(收入损失)和长期影响(不良声誉,客户保留)的总影响。根据客户类型(付费/免费,重复/唯一,专属)和资源可用性,应内置不同级别的可用性保证。

致力于提高现有系统的可用性

单个机器和网络的运营管理是如此复杂,以至于我认为您已经将它留给了云提供商,或者您已经足够熟练地知道自己在做什么。我将在可用性下讨论其他主题。对于长期策略,“ 定义-度量-分析-控制”是天上的比赛,这是我自己看到的。

  1. 定义什么是利益相关者的“可用性”
  2. 您将如何衡量定义的内容
  3. 根本原因分析以识别瓶颈
  4. 改进任务
  5. 持续监控(控制)系统

无法使用的原因

由于我们同意涵盖所有物理基础设施管理的运营管理应由专业人员进行,因此为了完整性起见,我将探讨其他导致不可用的原因。IMO可用性还应包括缺乏预期的行为,这意味着如果未向用户显示预期的体验,则表示某些内容不可用。考虑到该宽泛的定义,以下内容可能会导致不可用:-代码错误-安全事件-性能问题


有趣但不是很有帮助,有点题外话。不管怎么说,还是要谢谢你。
thomasb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.