作者:邹德虎
本文主要谈论的是分布式计算机系统的设计和架构。考虑到本公众号的读者大多数是电力系统专业背景,也更关心电力行业的数字化转型等问题,因此本文在写法上多处采用计算机系统与电力系统对比的方式,这样比较易于理解。说起分布式计算机系统,大家可能以为我要介绍Kubernetes的容器编排机制、Redis的缓存原理、kafka的消息处理机制,等等。但本文不谈论这些技术细节,一方面这些技术在互联网上很容易找到资料,另一方面是本文主要从业务需求的角度分析分布式计算机系统的设计原则。当然,我意思并不是说技术细节不重要。
在很早以前,计算机系统多采用单体架构,这种架构可能会倾向采用高性能的服务器。比如说以前IBM服务器非常流行,运维简单、可靠性高,但是价格真的很贵。10多年前我也运维过IBM服务器,还和IBM的工程师一起解决过故障,但是这10年再也没见过IBM服务器了。随着业务并发量越来越大,人们不得不使用一堆服务器来解决问题。甚至一个数据中心还不够,要多个数据中心一起解决,不同的数据中心可能不在一个城市。另外我们需要加强系统可靠性,关键业务绝对不能因为单个服务器故障而失效。分布式计算机系统的架构如果合理,可以提高系统可靠性。
当然,在高性能计算领域,如果是CPU密集计算且子任务之间的通信实时性要求非常苛刻,很多传统的架构仍然是有用武之地的。大型的计算任务可能交给ccNUMA架构的超级计算机(缓存一致性非均匀内存访问)。比如说中国电科院(国家电网电网仿真中心)的数模混合实时仿真平台,至今仍使用SGI的服务器。当然,科学计算的很多架构市场空间相对越来越小了。即使是人工智能的训练,OpenAI公司也开始尝试Kubernetes,而不是基于传统的MPI实现高性能计算集群。这一段是插话。
下面回到分布式计算机系统,一开始的架构是基于服务的架构(SOA),采用开放标准与软件资源进行交互,服务间并不直接依赖,而是通过中间件的标准协议或通讯框架相互依赖。D5000系统就是典型的基于SOA的架构。平台的各项服务挂载到消息总线和服务总线上,然后各个应用之间是解耦的,它们都基于平台搭建。SOA架构的弱点是中间件非常“重”,比如说不止一次发生过,不那么关键的应用,执行下装实时库或者调试消息总线等工作时出现误操作,导致整个调度系统瘫痪,影响面非常严重;此外,增加应用需要建表、增加告警定义、增加各种消息号、还有很多的配置文件修改,不见得那么“松耦合”,比如说关系库表数量超过1万,这在运维上非常麻烦。所以最近几年,分布式计算机系统架构倾向于更加松耦合,典型的代表技术是微服务,或者容器技术。这些技术使得开发速度变得更快,部署快,隔离性高,系统的扩展度也很好,但是在集成测试、运维和服务管理等方面就比较麻烦了。对于架构师的要求也在不断提高。
下面讨论架构师的能力要求。假设接到甲方的系统设计任务,乙方的架构师首先要做的是什么?当然是业务梳理,假定你要设计一个PMS系统(设备管理系统),假定有数千个功能点,这些功能点不可能是同等重要的,总要有轻重缓急。有的功能点是必须实用的,不然会影响关键业务开展;有的功能点是锦上添花,作为亮点的;有的功能点纯属用于宣传或者应付领导检查;还有的功能点只是积累经验,后续才考虑完善。不同的具体需求在设计都需要考虑。还有功能点之间的耦合关系,有的应用需要其它应该提供结果,然后把自己的结果给别的应用。可能会形成极其复杂的有向图。复杂系统架构设计最怕这种剪不断理还乱的耦合关系。举一个假想的例子,PMS系统你着急看某个设备的状态,几十秒的时间都不返回结果,你都急死了。可能是因为通信带宽被你并不着急的应用给占去了(比如说视频图形的传输是很占带宽的),这就是架构设计不合理的表现。
用户领导对于功能点的需求,往往是“多多益善”的态度,越多越好,越炫酷越好,未必可以梳理的清楚。一线的用户操作人员,对于自己的需求,很难用计算机专业的清晰化标准来描述。这就要求乙方的架构师必须非常熟悉甲方业务。合格的架构师应该具备这样的能力:可以无缝平移到甲方企业去做业务专家。
架构设计的难点,还在于故障发生的概率非常高,至少比绝大多数工程师估计的高的多。服务器可以宕机;网卡可以断线;网络可以拥塞甚至完全中断;硬盘也可以损坏;整个数据中心断电然后UPS也故障的例子,其实都有。软件上也可能有各种奇怪的bug,例如内存泄露、多线程锁的不当使用、编译器引起的二进制接口问题,都非常难查。 这一点跟电力系统确实非常像,终端用户觉得电力非常可靠,似乎插座里面总是有电。但实际的电力系统,各种外力破坏和保护动作;新能源低电压穿不过大量脱网;直流闭锁;系统振荡,等等。各种风吹草动和故障真的太多了。 下面列举分布式计算机系统的若干设计原则,在论述时尽量与电力系统对比。
监控是自动化的前提,无论是分布式计算机系统还是电力系统,都非常重要。系统分成多层,各种业务关联耦合,需要监控的东西都特别多。没有一个好的监控系统,我们将无法进行自动化运维和调度。监控系统的主要功能为:全栈监控;对监控数据的关联分析和处理;实时报警和自动处置;系统性能分析;日志等。 对于分布式计算机系统,监控包括如下:主机和底层资源,例如:CPU、内存、网络吞吐、硬盘 I/O、硬盘使用等;中间件监控,包括Redis的内存、Kafka的流量等;应用层监控,包括访问的吞吐量、响应时间、性能瓶颈、用户使用情况等等。
对于电力系统的监控,包括变电站的各种互感器和测控装置;配电网的各种终端设备;用电侧的各种智能电表,等等。还包括二次系统的监控、发电机涉网监控、脱硫脱硝监控,等等。
监控的目标是为了系统调度和控制服务。有的系统收录了非常多的数据和测点,却不知道拿来干什么;或者监控告警太多,没有智能化的综合分析处理,看都看不过来。这些缺陷,无论在计算机系统,还有电力系统都发生过。 计算机系统还可以包括非传统的外部监控,包括机房温度、空调运行、UPS电源监控等。同样,电力系统的非传统监控也越来越多,也越来越重要,比如光伏电站的微气象监控、输电线路的视频监控、线路和杆塔的力学监控等等。 所以说,监控向全场景方向发展,监控是系统运行的底层关键支撑。
分布式计算机系统和电力系统都需要进行资源调度和优化以确保高效的运行。在分布式计算机系统中,这可能涉及负载均衡、任务调度和流量管理等;而在电力系统中,这可能涉及发电调度、负荷管理和电力市场等。 分布式计算机系统的流量调度是比较重要的,依据系统运行的情况,自动地进行流量调度,在无需人工干预的情况下,提升整个系统的稳定性;可以让某个区域流量突增时保护系统平稳运行。实质上,电网调度自动化系统的前置已经有多机负载均衡的概念,但传统变电站的协议和点表毕竟相对固定。以后电力物联网的发展,大量异构数据的接入,会使得流量调度变得复杂。
电力系统的稳态运行控制主要是基于电能不能大规模存储,因此需要各种自动控制装置时刻发挥作用,保持电网频率/电压的稳定。代表控制系统有AGC和AVC。以后虚拟电厂等技术的发展,电力系统的稳态控制能力可能会更加提高;但新能源的大量接入也会使得控制难度同步提高。
分布式计算机系统和电力系统都可能会遇到故障和异常,它们需要在发生故障时能够自动检测并采取措施进行恢复,以确保系统的稳定和连续运行。
电力系统常常有N-1的概念,也就是单个设备退出运行不至于对整体系统有全局影响。电力系统的故障处理,大家都非常熟悉了,对于主网有三道防线的概念;对于地区电网和配电网,主要是故障的识别、隔离和网络重构。 对于分布式计算机系统,出现故障,首先要做的是隔离,不让故障变成连锁反应。常见的隔离方式是:常规数据通过分区来隔离,而对于一些比较重要的应用,则使用完全独立的专属资源,防止被拖累。除此以外,还要有“兜底机制”,也就是错误太多,或是在短时间内得不到修复,就不能让程序反复试错了,否则系统的资源占用会急剧飙升。可以暂时牺牲掉一些东西,以保障整个系统的平稳运行。具体而言,可以停止次要的功能,或者提供粗糙但勉强能用的服务。但是在架构设计的时候,就必须确保哪些是必须要死保的,哪些是可以牺牲的。(有没有注意到,这段分布式计算机系统的设计思路与电力系统几乎完全类似)。
刚才说的都是相似性,但是分布式计算机系统和电力系统是有本质不同的,主要体现在前者是用电磁波实现信息的传输和生产;后者用电磁波实现能源的传输。电力系统不存在一致性问题,只要满足电能质量和涉网调度需求,不同的发电都会在电网汇聚成整体,终端用户并不能区分自己用的电是水电还是风电。但是对于计算机来说,每一个字节都是异质的。根据信息论只有异质才能带来信息。分布式系统容易出现数据一致性问题。
比如说,为了提高系统性能,需要缓存。缓存的引入必然存在一致性问题,哪怕是CPU内部的多核缓存都有一致性问题,更不用说分布式系统了。对于不同城市服务中心的多活来说,情形更为复杂。最简单的例子是为了提高系统的可靠性和容错能力,数据通常会在存储于多个数据中心。然而,当一个节点对数据进行修改时,其他节点需要同步更新,以保持一致性。这种同步可能导致延迟和性能下降。数据一致性处理需要一系列复杂协议和技术,本文就不展开了。
分布式计算机系统和电力系统是完全不同的两个领域,但它们的相似程度如此之多(其实我都还没有写完,还有静态拓扑的相似性,还有资源管理的某些相似做法),这可能让很多人出乎预料。对于技术人员,需要有系统观念、全局观念,才能事半功倍的学习新技术,更好更有效去解决实际问题。有了系统性视角,不同的领域还可以更好的互相借鉴,取长补短。前段时间我看了制造业数字化的一本书,也看了机场塔台指挥系统的一个PPT,感觉不同行业的很多解决方案实在太相似了,也有很多面临的共性问题。我以前也看过很多电力系统信息化系统的的设计,洋洋洒洒数千页,只有技术堆砌,却没有系统,很难相信能在架构层面应对实际业务的各种复杂事件。