从服务化到云原生-配置

配置(Configguration)对于每个工程师来说都不陌生,相信没有哪个系统是不提供配置参数的。

本文讲解由单机应用的本地配置向分布式应用的配置中心演进过程,以及配置中心的一些核心概念

1 本地配置

在集中式系统架构的单机应用时代,配置大多数通过属性文件的形式存储以Key=Value的形态出现。当然也有使用XML或YAML等更加复杂的方式进行配置(比如Spring的配置文件application.xml)但开发工程师更倾向于将他们归类为代码部分,真正可以动态修改的配置应该是简单、易于理解的、易于修改的。

在单机时代,配置文件就够用了。运维工程师如果想修改配置,登录生产机器,用VIM本文编辑,然后重启应用,或者用定时任务从新加载配置文件就可以生效。

2 配置集中化

服务器增加导致运维工作量增加,分布式系统很难使用本地配置。采用集中化的方式,也就是散落在每台服务器上运维操作集中于一点统一处理,然后程序通过远程通信或异步消息分发到各个服务器。对系统配置进行修改是运维工程师的重要工作之一,所以对配置进行统一管理是大势所趋。

本地配置存在的问题:

  •  配置工作量大;
  •  配置修改遗漏,导致各个节点配置环境不一致;
  •  各个节点配置不一致的时间差长(各个服务器操作时间不同);
  •  配置修改无法动态生效(定时重新加载或重启应用);
  •  直接修改配置文本信息产生错误难于校验;

配置中心能解决上述问题,还能提供额外的便利:

  •  配置工作量少,单点修改,全局生效;
  •  配置修改不容易遗漏;
  •  各个节点配置不一致的时间差比较短;
  •  配置信息可以像业务数据一样被持久化保存,方便恢复,方便搭建环境,方便最终修改历史;
  • 多个系统上线时,配置检查、沟通协调容易;
  •  配置信息放置于应用程序之外,更容易保持应用的无状态化,为容器化和微服务化部署方案提供了强有力的支持。

3 配置值中心和注册中心

很多人认为配置中心和注册中心是可以相互替换的两个同义词,因为他们的使用场景非相似。另外,当前很多开源产品,如zookeeper、etcd等,都同时支持这两种场景,这也更加容易让人误以为他们就是同一事物。但事实上,他们还是有着本质区别的。

注册中心与配置中心的关注点不完全相同。注册中心用于分布式系统的服务质量,多用于管理运行在当前集群中的服务的状态,需要随时进行动态更新。而配置中心则不然,它关注的是配置本身,相比于状态,配置是更加静态和具象的事物。配置的三个要素是快速传播、变更稀疏、环境相关

快速传播:分布式场景下,各个服务节点都需要得到一致的数据,无论是配置还是状态,一旦发生改变往往要求集群中的所有节点同时感知变更

变更稀疏:配置发生变更的情况非常少,因此配置中心对读性能进行优化,而对写要求稍低

环境相关:一般耳熟能详的系统环境有开发环境、测试环境、线上环境,不同的环境对应着不同的配置,但注册中心所关注的应用程序的运行状态和环境是没有任何关系

3.1 读性能

采用配置中心方案后,就必须要考虑远程调用导致的性能下降和配置中心本身的单节点访问压力的问题

解决方案:缓存。

因为配置信息是可穷举的,不可能是海量的,所以一次性杯加载进本地缓存是非常方便的

缓存分为位于配置中心的集中式缓存和位于应用端的本地缓存

  • 集中式缓存:配置信息读远大于写。每次读取磁盘影响性能,缓存到内存。

    • 优点:能访问最新的数据,数据一致性好,提升访问效率;
    • 缺点:没有缓解配置中心的访问压力。
  • 本地缓存:客户端缓存,尽量访问本地,只有在配置发生变化的时候才读配置中心,更新缓存。

    • 优点:减少远程调用,提升访问效率,缓解了配置中心压力。
    • 缺点:数据存在多份,可能不一致。

补充:

缓存击穿:缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞,缓存还有可能降低效率;

3.2 变更实时性

如果使用本地缓存,数据就会存在多个副本,配置中心数据发生变更时,如何将配置信息实时通知给应用客户端。

一般有两种方式:监听实时同步

  • 监听:配置中心的客户端都需要与配置中心建立长连接。配置变化时,配置变化了,主动推送各个客户端,客户端更新缓存。
    • 优点:实时性高;
    • 缺点: 长连接比较消耗系统资源。并且长连接一旦断了,还要从新连接,容错等。

保持长连接有效的方法是:心跳监听服务,一旦发现连接不可用则销毁连接建立新连接。为了保证应用客户端能正确接收到信息变更请求,也需要让客户端给予反馈,不反馈就一直发。客户端要实现幂等性(在应答式通信系统中,可能存存在多发请求的情况; 比如kafka重复消费数据)。 

  • 实时同步:客户端主动定时去询问配置中心。如果发现缓存和配置中心不一致,就更新缓存。这样使用短连接就可以。
  • 优点:节省连接资源,降低服务中心的压力。
  • 缺点:间隔时间长,则配置更新不及时;间隔时间短,则配置中心压力过大,并且做很多无用功。

其他方法;设置缓存失效时间。 

3.3 可用性

配置中心是整个分布式系统的核心,一旦配置中心不可用,整个系统将会受到极大影响

那么如何提升配置中心的可用性呢?服务冗余、缓存

  • 服务冗余:做服务集群,数据备份

    • 1 基于主节点提供服务:主从模式,主节点提供服务,从节点冗余数据备份
    • 2 基于对等节点提供服务:节点对等,在访问量非常大的情况下可以有效分流(但对于配置中心,有点小题大做)
  • 缓存:也是服务冗余的一种,但只是冗余数据,而不是整个服务

    • 优点:提升读取配置信息的性能,可以在配置中心节点全失效时提供应急使用,也叫离线模式。
    • 缺点:缓存更新不了了。

 

3.4 数据一致性

分布式架构下,数据一致性如何保证

一致性三种方案

  • ACID(强一致性)

  • BASE:BASE是Basically Available(基本可用,响应时间上有损失,功能有损失Soft state(软状态,软状态是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同的数据副本之间进行数据同步的过程存在延时Eventually consistent(最终一致性,最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状三个短语的简写。 其核心思 想是即使无法做到强一致性,但每个应用都可以根据自身的业务特点,采用适当的方法来使系统达到最终一致性。最终一致性是一种特殊的弱一致性:系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问都能够获取到最新的值。同时,在没有发生故障的前提下,数据到达一致状态的时间延迟,取决于网络延迟、系统负载和数据复制方案设计等因素。

  • 状态机:状态机是表示实体的状态根据条件转移的数学模型。通过状态机模型,系统可以判断当前不一致状态,以及如何校正不一致状态到一致状态;

  • 基于状态机的数据一致性算法是:ZAB和Raft

  • 成熟的产品有zookeeper(基于ZAB算法);etcd(基于Raft算法)和Consul(基于Raft算法)

那么配置中心选择哪种方案更加合适呢?

配置中心并不需要ACID的事物,也不会有类似于关系型数据库那一复杂跨表的关联操作;对于BASE的最终一致性的柔性事物场景而言,一致性状态没有时间的保证,因此也不适合用于处理相对敏感的配置信息;通过状态机保证数据一致性的处理方式,无论是在一致性还是性能上,都更加适合配置中心。