Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 高可用性环境中的应用程序升级_Design Patterns_Web Applications_High Availability - Fatal编程技术网

Design patterns 高可用性环境中的应用程序升级

Design patterns 高可用性环境中的应用程序升级,design-patterns,web-applications,high-availability,Design Patterns,Web Applications,High Availability,我正在编写一个NoSQL数据库引擎,我想提供一些功能,帮助开发人员在不停止网站操作的情况下将其应用程序升级到一个新版本,即在升级期间0%的停机时间。所以我的问题是,当web应用程序全天候运行并且经常更改其数据库结构时,它的一般设计方法是什么?任何例子或成功案例都将不胜感激。数据库结构与业务规则密切相关,因此我能想到的唯一数据库经常变化的场景是在项目的开发阶段 在生产环境中,假定应用程序在业务规则方面已经是稳定的,因此假定很少对数据库结构进行更改。因此,我认为很难为这一案件找到详尽的解决办法 当然

我正在编写一个NoSQL数据库引擎,我想提供一些功能,帮助开发人员在不停止网站操作的情况下将其应用程序升级到一个新版本,即在升级期间0%的停机时间。所以我的问题是,当web应用程序全天候运行并且经常更改其数据库结构时,它的一般设计方法是什么?任何例子或成功案例都将不胜感激。

数据库结构与业务规则密切相关,因此我能想到的唯一数据库经常变化的场景是在项目的开发阶段

在生产环境中,假定应用程序在业务规则方面已经是稳定的,因此假定很少对数据库结构进行更改。因此,我认为很难为这一案件找到详尽的解决办法

当然也有一些幼稚的方法,比如在升级之前创建数据库的精确副本,将应用程序切换到副本上运行,升级然后切换回数据库


除此之外,我想不出其他任何事情

使用NoSQL,特别是面向文档的数据库,您可以通过版本控制来实现这一点

以MongoDB为例,它将所有内容存储为文档

MongoDB允许您拥有一个集合(一组文档),其中每个文档的模式可以不同

假设您为用户准备了此文档:


{
“_id”:100,
“名字”:“约翰”,
“姓氏”:“史密斯”
}

您也可以将其作为同一集合中的文档:


{
“_id”:123,
“名字”:“约翰”,
“姓氏”:“史密斯”,
“hasFoo”:错误
}

不同的架构,但都在同一个集合中。显然,这与传统的关系数据库非常不同

然后,解决方案是为具有模式版本的每个文档添加一个字段。然后让应用程序在每个查询中查找该版本

MongoDB查询可能如下所示:


查找({“版本”:3}).limit(10);


它只返回使用模式版本“3”的所有用户。您可以在不影响现有站点的情况下插入较新的架构,并慢慢删除不再有用的旧架构版本。

您将要构建一个分布式系统。这是没有办法的,因为你需要多台机器来处理重启之类的事情

构建分布式系统意味着您正在做出一些选择。从中选出2项:

  • 耐久性
  • 可用性
  • 强一致性
  • 像S3这样的系统选择了1和2,并付出了代价,牺牲了#3来支持“最终一致性”。有一本你可以读的书。其他数据库解决方案,如DynamoDB,选择了不同的折衷方案

    您将需要负载平衡器。否则,您将无法与客户直接连接到您的服务,因为各种原因,这很难做到。负载平衡器允许您重新启动机队中的机器,而不会导致停机时间。我们都知道,重新启动是生活中的一个事实

    做你所描述的是非常困难的。事实上,我想说,对于单个开发人员来说,这几乎是一个不可能解决的问题


    如果企业能够投资数据库的地理分布,那么使用现有的NoSQL数据库并将所有的时间都花在产品上,您就更有可能获得更好的结果。比如容错;这听起来很传统,但数据复制(或数据存储复制)不会成为路由流量的问题

    选项2:-使用缓存(自定义开发)和循环。 例如:-凌晨1点到凌晨2点使用数据库的快照1(比如服务器1/数据中心1) 1:59am服务器2/数据中心2由新的数据库体系结构(新字段、新表等)和@2am通过数据中心2的所有流量路由组成


    基于快照的循环可能是一个需要考虑的解决方案。

    < P>当生产环境中的许多Web服务器访问该数据库时,代码更改不兼容(删除字段并添加新字段),那么我建议多步解决方案。这是一点工作,但当一些细节出了问题时,你不需要risc停机时间

    第一步扩展应用程序,以便编写旧版本和新版本,然后部署该版本

    第二步尽可能将旧数据字段值转换为新数据字段(可能需要一些时间)

    第三步将应用程序更改为只读新字段,然后部署它

    第四步删除旧字段值


    第五步从代码中删除旧字段值的写入,并将其部署。

    实现这一点的唯一可能的情况是,如果您有一个完全无状态的应用程序。术语无状态包括应用程序数据和应用程序结构。请记住,除了数据,升级还可能涉及更改业务对象的定义。由于明显的原因,这种无状态应用程序是不实用的,因此没有实用的方法来实现一般升级的零停机时间。 任何非无状态的应用程序都将具有实时用户缓存(在中间层)业务对象定义和业务数据。升级可能不仅需要新的业务数据,还需要新的业务对象定义。实时用户缓存的数据总是可能导致与新模式的潜在不一致。因此,除非您可以迁移中间层中缓存的数据和元数据(业务定义),否则无法迁移实时用户。如果您将中端缓存吹走,实时用户将受到影响。 您可以考虑允许现场用户继续在旧数据库下继续工作,并将任何数据更改迁移/合并到新的数据库中。但那是一个公司