12

一致性是最终目标

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzAwOTU4NzM5Ng%3D%3D&%3Bmid=2455771970&%3Bidx=1&%3Bsn=bfbd72e8078433a17883cb258c6b879b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

分布式系统、数据库、缓存都要追求一致性,但基础设施实际上也同样如此,最近看到一个专栏,里面提到 一致是最终的目标

如果不同的环境出现不一致的情况,就会出现各种问题,影响开发、测试、部署、扩展,所以需要通过技术手段保障一致性。

有三种模型,分别是发散、收敛、一致。

1:发散,如果你在维护基础设施的时候,有了新的想法,也就是我们想更新什么就更新什么,最终就形成一种发散的状态,这是罪恶的根源。

目前我们处于这个状态,但通过阿里云镜像缓解了这种情况。

2:收敛,Puppet和Chef遵循的设计原则。随着时间推移,目标和实际需求汇聚,达到一致,这个还是非常不错的状态,比如通过Puppet维护集群,保障它们的一致性。

3:一致, 指的是整个基础设施始终把每一天当成是与第一天相同的模型,这是终极的状态。

不管是发散还是收敛,都会存在一些问题:

1:顺序问题,如果在配置基础设施的时候,顺序出现问题,那结果可能就不一致。

2:频率问题,如果天天变更,即使是收敛模型,也会陷入巨大的陷阱。

3:蝴蝶效应,你不断追求收敛,无限接近,但如果出现任何小偏差,最终就会出现问题。

那么如何保障一致性呢?这就要提到 不可变基础设施 的概念,什么意思呢?任何基础设施的实例(包括服务器、容器等各种软硬件)一旦创建之后便成为一种只读状态,不可对其进行任何更改。如果需要修改或升级某些实例,唯一的方式就是创建一批新的实例来替换它。

不可变基础设施的概念来源于不可变模型,对任何的包、配置文件、软件应用和数据,都不做 CRUD(创建、替换、更新、删除)操作。从而推导出的方法论:

  • 构建一个新的基础设施
  • 测试新的基础设施是否符合需求
  • 将引用指向这个新的基础设施
  • 保留原有基础设施以备回滚。

k8s就完美实践了这些理论。docker也同样是如此操作的,每一次变更都重新打镜像然后重新运行。甚至部署代码也不是git拉取,而是通过镜像更新(对于PHP程序员来说不可理解)。

可如果没有k8s和docker呢?那就按照不可变模型的原则来操作,至少要做到收敛模型,在考虑技术问题的时候,尽量用这个理论去武装自己。

延伸出来的两个概念,也是我们目前在实践的。

1:阿里云镜像,任何系统级变更都生成一个镜像,然后基于镜像生成一台新的服务器。

2:基础设施即代码,指的是把基础设施的构建以代码的方式组织起来,从而通过运行代码可以完全构建出你想要的全部基础设施。

镜像容器是死的,里面很多内容(比如源代码,各种变更的cron)是动态变化的,这些可以写成一些shell,启动容器的时候动态运行,这样也能解决部分问题,但实际上代码部署本身也要成为一种容器。

后续一个月,不管采用什么手段,至少要保障QA环境、仿真环境、线上环境的配置是一致的。比如不能线上用SLB而QA没用,这样会带来潜在的问题,这是测试最忌惮的;环境是完全独立的,但代码也要做到,比如通过环境变量、配置化来对接不同的环境,不能有任何的硬编码。隔离的彻底,比如线上不要和QA混用,这样方便扩展,也能保证各个单元之间是松耦合的,单元本身是内聚的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK