如何实现滚动更新和关系数据库?

时间:2018-07-09 10:17:41

标签: docker kubernetes relational-database continuous-deployment

我有一个使用关系DBMS的现有系统。由于各种内部原因,我无法使用NoSQL数据库。

系统将获得一些将使用Kubernetes和Docker部署的微服务,以进行滚动升级以减少停机时间。后端数据层将使用现有的关系DBMS。微服务将遵循良好实践,并将其数据存储“拥有”在DBMS上。与此相关的一个大问题似乎是如何跨此管理数据库结构。我已经完成研究:

所有讨论似乎都在添加/删除列和数据迁移这一点上停止了。没有讨论如何管理存储过程,视图,触发器等。

应用程序使用.NET Full和.NET Core编写,实体框架为ORM。

在使用完整的生产系统的关系型DBMS的情况下,有没有人对如何进行连续交付有任何见解?回到这里了吗?使用关系型DBMS进行滚动更新“太难了”吗?

PS。即使这是一个持续的交付问题,我也用Kubernetes和Docker进行了标记,因为这将成为业务流程/容器方面的基础技术。

2 个答案:

答案 0 :(得分:2)

假设我正确理解“滚动更新”的含义及其后果,以下所有内容。

它与“关系DBMS”几乎没有关系(如:一无所有)。持有XML的Flatfile将使您面临完全相同的问题。您的“滚动更新”将不可避免地导致(希望是短暂的)一段时间,在这段时间内服务器端组件(例如db)必须与(客户端组件的“版本0”以及“版本-1”)进行交互的系统。

这里引入了“兼容性理论”(*)。“工作系统”是这样一种系统,其中所提供的服务集是所需服务集的超集(也许是适当的超集)。因此,如果从不减少“提供的服务”并且从不扩展“需要的服务”,则可以保证向后兼容。但是,后者通常是将当前的“版本0”移到“ -1”并将新的“当前版本0”添加到混合时总是发生的情况。因此,结论是,只要在服务器端提供的“服务”仅被扩展且始终以成为(并始终保留)(上)所需服务的超集的方式进行,“滚动更新”在理论上是可行的客户端上当前使用的任何版本。

这里的“服务”将被解释为非常抽象的东西。它可能表示一种保证,例如,如果此表此行中的X列的值为Y,则我 将使用这样计算的键在该其他表中查找另一行。因此,可以保证其他行的列值满足此条件。

如果在(新版本的)客户端上作为“期望”(即要求)引入了“担保” (即要求),则必须在服务器端执行某些操作以符合要求。如果当前提供的是“担保”,但是作为对(新版本的)客户端的期望引入了有矛盾的担保,那么根据定义,您的滚动更新方案就无法实现

(*)http://davidbau.com/archives/2003/12/01/theory_of_compatibility_part_1.html

还有第2部分和第3部分。

答案 1 :(得分:1)

我在一个可以连续交付的环境中工作。我们使用MySQL。

我们通过使用pt-online-schema-change来应用模式更改,并且中断最少。一个人也可以使用gh-ost

如果应用程序代码可以使用额外的列,则可以随时添加列。例如,避免诸如SELECT *INSERT之类的隐式列而没有columns-list子句是一个好规则。在应用程序代码不再引用该列之后,可以删除该列。在不协调应用程序发行版的情况下,重命名列是比较棘手的事情,在这种情况下,您可能必须进行两次架构更改,一次更改为添加新列,另一次更改为删除旧列,因为已知该应用程序未引用该列。旧列。

我们通过使用冗余对数据库服务器进行升级和维护。每个数据库主数据库都有一个副本,并且这两个实例是在主数据库-主数据库(循环)复制中配置的。因此,一个是主动的,另一个是被动的。应用程序只能连接到活动实例。被动实例可以重新启动,升级等。

我们可以通过更改内部CNAME并在每个MySQL实例中更新read_only选项,在1秒内切换活动实例。

数据库连接在此切换期间终止。需要应用才能检测到断开的连接并重新连接到CNAME。这样,应用程序始终连接到主动MySQL实例,从而释放了被动实例进行维护。

MySQL复制是异步的,因此可以关闭和备份实例,并且它可以恢复复制更改,并且通常可以快速进行追赶。只要其主控保留所需的二进制日志。如果副本副本的关闭时间比二进制日志过期的时间长,那么它将丢失其位置,必须从活动实例的备份中对其进行重新初始化。


评论:

  

数据访问代码的版本如何?即与数据库的v2交谈的应用程序v1?

这取决于每个应用程序开发人员团队。我相信大多数人都在不断发布而不是版本。

  

SP,UDF,触发器等如何处理?

没有应用程序正在使用其中任何一个。

MySQL中存储的例程实际上是责任而非功能。不支持例程的程序包或库,没有编译器,没有调试器,可伸缩性差,并且SP语言不熟悉且文档记录不充分。即使在Oracle / Microsoft数据库开发实践中很常见,我也不建议在MySQL中使用存储例程。

在我们的环境中不允许触发,因为pt-online-schema-change需要创建自己的触发器。

MySQL UDFs是已编译的C / C ++代码,必须作为共享库安装在数据库服务器上。我从未听说过在MySQL生产中使用UDF的任何公司。 C代码中的错误可能会使整个MySQL服务器进程崩溃,这是一个很高的风险。在我们的环境中,出于SOX合规性的原因,不允许应用程序开发人员访问数据库服务器,因此他们无论如何都无法安装UDF。