云计算与大数据进阶 | 25、可扩展系统构建

在进入这个进阶版系列之前,让我们先回顾一下云计算与大数据系统的基本设计原则,总结起来有如下几条:

(1)基础架构:更多采用商品现货硬件(如PC架构)​,而很少使用定制化高端(如小型主机)硬件。

(2)扩展性:追求动态扩展、横向扩展,而非静态扩展、垂直扩展。需要指出的是,系统扩展性不能是以牺牲性能为前提的,如我们在前面的文章中讨论过的,横向扩展的系统在简单、浅层查询的高并发场景中有优势,但是在复杂、深层查询的场景中,垂直扩展的系统更具优势,因此,系统扩展过程中通常是纵向扩展与横向扩展兼而有之的。

(3)可用性:追求弹性而非零故障(取决于商品现货硬件)​。

(4)高性能:通过分解与分布而非压迫来实现。

(5)可用性:更多地关注平均故障恢复时间而非平均故障间隔时间,这一点是使用了商品现货硬件后做出的改变。

(6)容量规划:相对于第二平台架构设计中的最差情形规划(即导致大量资源被浪费的最大负载规划)​,第三平台(云计算与大数据)的规划精细度要高得多,多采用细颗粒度。

(7)期望失败:可以容忍部分系统组件的失败,以此来换取整个系统的持续在线。微服务架构与面向灾难(失败或死机)的系统架构、服务与测试设计框架可以说都是在期望失败思路的指导下诞生的。

基于这些基本设计原则,我们来逐一分析可扩展系统构建、开源开发与商业模式,以及从服务驱动的体系架构到微服务架构这3个方面。

构建可扩展系统的目的是实现可扩展的应用与服务。我们首先了解一下可扩展应用与服务的九大误区:

①完全依赖本地资源:数据没有实现云(网络)存储。

②服务采用强依赖性:服务的强依赖性指的是B服务依赖于A服务,而A服务下线后将直接导致B服务的下线。在第三平台的架构设计中,我们应把B服务设计为当A服务不可用时,采用其他渠道继续提供服务,例如从内容分发服务(Content DeliveryNetwork,CDN)或缓存区中保存的数据继续提供服务,以此来提高用户体验,同时在后台通知DevOps团队修复故障服务。

③CDN无用论:CDN的最大价值在于降低服务器和网络的压力,以及提升用户体验。除非自建CDN,否则利用现有CDN服务提供商网络不失为上策(规模经济效应)​。

④缓存无用论:缓存是提供系统整体效能加速的一把双刃剑,好的设计原则会让系统事半功倍,坏的设计原则可能让用户总是得到过期的数据。在后文中我们会介绍正确使用缓存的方法。

⑤纵向扩展而非横向扩展:纵向扩展的最大问题是如果系统是单机系统,就会出现因系统升级或硬件故障而下线。此外,还有一个问题是基于纵向扩展设计的系统的瓶颈性显而易见,因此纵向扩展的扩展性能甚为堪忧。

但是,这并不说明纵向扩展不再有价值,实际上,在真正的商业环境中,很多高可用系统的架构都采用主从热备份、多机互为热备份、分布式共识等架构,它们往往比单纯的横向扩展系统有更为简捷的架构逻辑,更易于维护,性价比也更高,甚至有更高的系统算力——是的,你没有看错,很多所谓的“水平分布式系统”的算力都非常糟糕。其中最核心的逻辑在于,在一个实例的CPU并发能力都没有得到充分利用的前提下就贸然地堆叠更多的实例,并不能获得更高的并发算力,因为多实例间的网络通信会让系统性能呈指数级下降。

构建分布式系统的第一原则就是:先纵向扩展,再横向扩展。这个和先学会走再学习跑是一个道理。纵向扩展与横向扩展之间的关系并非是从0到1的关系,它们之间还有0.5、0.25、0.75。打个具体的比方,单机系统可以升级为多机热备份系统,多机热备份可以升级为分布式共识系统,分布式共识系统再继续扩展为多级分布式共识系统,直至在可行的条件下拓展为大规模水平分布式系统。而在真正的商业环境下,大规模水平分布式系统不但极为少见,而且系统效率往往并不高。在全球范围内,只有在极为特殊的情境下,大规模水平分布式系统才能物尽其用。换而言之,为了追求“水平”分布式而部署水平分布式是盲目且没有价值的行为。

⑥单点失效是可以容忍的:可扩展系统构建中应避免任何可能出现的单点故障。从存储、网络、计算的IaaS层一直到应用层,应当尽可能全部实现高可用性。

⑦无状态与解耦合无关紧要:无状态是架构与服务解耦的先决条件。典型的有状态服务是传统的数据库服务,每一笔交易会有多次操作,前后之间存在状态依赖性,以实现数据的一致性。而无状态服务没有这种强一致性和依赖性要求,因而可以更容易实现分布式处理和并行处理。无状态+解耦合是微服务架构的核心理念——构建云计算或大数据服务的主要原则。

⑧只要关系数据库:与这个观点相对应的一个极端是RDBMS彻底无用论。此二者都是非此即彼,尤其在大数据时代,RDBMS独立难支,但是没有RDBMS也是有失偏颇的。除了少数非常专一的应用与服务只需要某种单一数据库——例如键值数据库NoSQL,多数系统需要两种或多种数据库来丰富数据处理能力。

⑨数据复制无用论:这个误区呼应第一个误区。可扩展应用及基础架构中解决的最核心的问题是数据的高可用性和可扩展性,这两者主要是通过数据复制来实现的,例如数据库系统中的读复制以及分片处理技术。

要衡量一个系统的可扩展性,通常可以从以下5个维度来进行:

①负载:负载可扩展性是衡量分布式系统能力最主要的指标,它主要关注系统随着负载增/减的可伸缩性(弹性)​。在第一、第二平台时代,分布式系统的主要方式是纵向扩展;在第三平台时代,分布式系统的主要方式是横向扩展。

②功能:系统实现并提供新功能的代价与便捷性。

③跨区域:系统支持广泛区域用户与负载的能力。例如,从一个区域的数据中心延展到另一个或多个区域的数据中心,以更好就近支持本地负载的这种能力。

④管理:系统管理的安全性与便捷性,以及支持新客户的能力。例如,对多租户环境的支持,如何在同一物理架构上实现良好的数据安全性与一致性支持等。

⑤异构:异构可扩展性主要是指对不同硬件配置的支持性,其中包括系统硬件升级、对不同供应商硬件的无缝继承等。

如果从数学(算法)角度来衡量可扩展系统,那么我们通常采用的是时间复杂度。如果一个系统对资源(计算、网络、存储等)的需求与输入(服务的节点、用户数等)的关系符合O(lgN),则我们认为该系统具有可扩展性;反之如果是O(N^2)或更高阶的关系,则该系统不具有可扩展性。

在网络领域(如路由协议)​,当路由器节点增加时,路由列表长度(内存资源)与路由节点之间的关系是O(lgN),即随着路由节点的增加,路由列表增长趋缓(增长曲线趋平)​,则该路由协议具有可扩展性。

以点对点文件分享网络(服务)的发展为例,最早的内容分享系统Napster的设计架构是一台中央索引服务器,该服务器负责收集每个加入节点的可分享文件列表,这样的设计导致系统存在单一故障点,也容易被黑客攻击或招来法律诉讼。有鉴于Napster的法律诉讼败诉,随后出现的Gnutella解决了Napster的单点失效问题,推出了纯分布式点对点文件分享服务。在早期阶段,Gnutella的在线文件查询设计采用泛洪查询模式,即一个节点发出的文件搜索请求会分发给网络内其他所有节点,从而导致在整个网络规模超过一定规模后多数查询会因超时而失败(这种扩展性改革虽然避免了单点失效,但系统效率被降低了)​。后来Gnutella采用了分布式哈希表,它的设计原则是网络中每个节点只需要与另外的lgN个节点互动来生成分布式哈希表中的键值,因此系统可扩展到容纳数以百万计的节点的这种方案才解决了文件查询可扩展性的问题。当然,在纯分布式P2P系统中,分布式哈希表所面临的问题是查询关键字只支持完全匹配,不支持模糊匹配、模式查询。这一问题在混合式P2P系统中得到了解决,例如Skype音视频服务系统采用的是两级用户架构——超级节点+普通节点,其中超级节点负责建立查询索引与普通节点间路由,普通节点则是用户终端。图4-1展示的是Skype的混合P2P架构。混合P2P架构在实践中既解决了可扩展性不足(存在单点失效)的问题,也解决了纯分布式系统的信息索引与查询困难的问题。

图1:Skype的混合P2P架构


一套完整的云应用/服务架构通常可以被分为负载均衡层、应用服务层、缓存服务层数据库服务层以及云存储层。云应用/服务的5层架构如图2所示。

图2:云应用/服务的5层架构

下面我们主要介绍负载均衡层、应用服务层和缓存服务层。

(1)负载均衡层

负载均衡层是5层架构中最先面对用户的,也是相对容易实现的。通常为了避免单点失效,至少设置两台负载均衡服务器(通常在两台物理主机之上,以避免单机硬件故障导致的单点失效)​。整个扩展设置过程通常可以完全自动化,例如通过DNS API来配置新增或删除负载均衡节点。常见的负载均衡解决方案有HAProxy和Nginx,它们通常可以支持跨云平台的负载均衡,即服务器及其他层跨云。当然这种架构的设计与实现复杂度会急剧增高,云爆发就是典型的跨云基础架构模式。智能的负载均衡层能做到根据应用服务器层的健康状态和负载状态动态引流,以确保系统真正实现均衡的负载。

云服务提供商通常会提供现成的负载均衡服务,例如AWS的ELB、RackSpace的CLB,还有VMware vCloud Air Gateway Services,它们都提供强大的负载均衡服务。

(2)应用服务层

负载均衡层之下就是应用服务层,它负责处理负载均衡层转发的用户请求,并返回相应的数据集。通常数据集分为静态数据与动态数据,前者大抵可以被保留在缓存服务层,以降低应用服务器及数据库服务器的负载(见图2)​,并加快客户端获得返回数据的速度;后者通常需要数据库服务层的配合来动态生成所需数据集。本层的扩展经常通过对现有服务器的负载进行监控(主要是CPU,其次为内存、网络、存储空间)​,并根据需要进行横向扩展(即水平扩展)或纵向扩展(即垂直扩展)来实现。横向扩展通常是上线同构的服务器(物理机或虚拟机)​,以降低现有服务器或服务器集群负载;纵向扩展则对CPU、内存、网络、存储空间等进行升级。横向扩展通常不需要系统下线,但是纵向扩展要求被升级的主机(可能是虚拟机或容器)重启。

应用服务层涉及应用服务逻辑,因而当多台服务器协同工作时,还需要确保它们之上所运行服务的一致性。DevOps通常作为PaaS层一部分任务或数据中心的管理与编排组件,实现一致化的应用升级和部署。

(3)缓存服务层

缓存服务层既可能存在于应用服务器层与数据库服务器层之间,也可能在应用服务器层之上,前者可以被用来降低数据库服务器的重复计算量与网络负载,后者则被用来降低应用服务器负载与网络带宽消耗。缓存技术的应用范围极广,从Web服务器到中间件再到数据库都大量使用缓存,以降低不必要的重复计算,进而提高系统的综合性能。

缓存服务层的扩展性实现在避免出现单点失效的基础之上,单个节点的缓存服务器/应用服务器共享节点的方式在生产环境中都是不可取的,主要问题是如何实现多缓存节点间的负载均衡。常见的分布式简单缓存实现是Memcached(全球较为繁忙的20个网站中有18个使用了Memcached)​,多台Memcached服务器间形成了一张哈希表,当有新的缓存节点加入或旧的节点被删除(或下线)时,现有节点并不需要全部进行大规模改动来生成新的哈希表(这种方法被称作一致性哈希算法)​。对于哈希表中数据的替换与更新,Memcached采用的是生存时间值(Time to Live,TTL)与最近最少使用(Least Recently Used,LRU)模式。对于更复杂的高扩展性缓存系统的设计来说,属于NoSQL类的CouchBase数据库提供了更为健全的企业级缓存功能的实现方式,例如数据常存、自动负载均衡、多租户支持等。

 (文/Ricky - HPC高性能计算与存储专家、大数据专家、数据库专家及学者)

· END ·

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C——函数递归

在 C 语言里&#xff0c;函数递归是一种函数调用自身的编程技术。下面开始逐一介绍。 一、什么是递归&#xff1f; 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。 写⼀个史上最简单的C语⾔递归代码&#xff1a; #include <st…

IdeaVim配置指南

一、什么是 IdeaVim&#xff1f; IdeaVim 是 JetBrains 系列 IDE&#xff08;如 IntelliJ IDEA, WebStorm, PyCharm 等&#xff09;中的一个插件&#xff0c;让你在 IDE 里使用 Vim 的按键习惯&#xff0c;大大提升效率。 安装方法&#xff1a; 在 IDE 中打开 设置(Settings) →…

Notepad++中XML格式化插件介绍

Notepad++中XML格式化插件介绍 背景安装指南安装步骤验证安装成功安装失败可尝试使用说明XML文件格式正确时格式化错误格式检查XML Tools插件核心功能盘点常见问题格式化后没变化中文显示乱码拯救杂乱XML格式!Notepad++这个神器插件,必须接收!背景 接手别人写的XML,缩进乱成…

自动化创业机器人:现状、挑战与Y Combinator的启示

自动化创业机器人&#xff1a;现状、挑战与Y Combinator的启示 前言 AI驱动的自动化创业机器人&#xff0c;正逐步从科幻走向现实。我们设想的未来是&#xff1a;商业分析、PRD、系统设计、代码实现、测试、运营&#xff0c;全部可以在monorepo中由AI和人类Co-founder协作完成…

第1章 算法设计基础

1-1 什么是算法 见识算法 算法是计算机科学的基石&#xff1a;从古代算术到现代计算机&#xff0c;算法始终是解决问题的核心。 算法的起源 张苍《九章算术》&#xff1a;创立了机械化算法体系&#xff08;如“合分术”分数相加算法&#xff09;。 欧几里得《几何原本》&am…

java中ArrayList扩容机制的解析

本文将系统地介绍 Java 中 ArrayList 的扩容机制&#xff0c;包括其初始容量的设置、触发扩容的时机、容量增长算法、扩容的详细流程以及性能优化建议&#xff0c;帮助读者从源码层面深入理解这一关键特性&#xff0c;并在实际开发中合理预分配容量以提升性能。 一、ArrayList…

【网络服务器】——回声服务器(echo)

作用 实现回声服务器的客户端/服务器程序&#xff0c;客户端通过网络连接到服务器&#xff0c;并发送任意一串英文信息&#xff0c;服务器端接收信息后&#xff0c;执行数据处理函数&#xff1a;将每个字符转换为大写并回送给客户端显示。 客户端&#xff1a;发送字符信息 服…

智能学习空间的范式革新:基于AI驱动的自习室系统架构与应用研究

摘要 在 “互联网 + 教育” 深度融合的背景下,传统自习室面临个性化服务缺失、学习效率低下等瓶颈。本文提出一种基于人工智能技术的 AI 自习室系统架构,通过构建多模态数据感知、个性化学习引擎及智能环境调控模块,实现学习过程的精准化、智能化与沉浸式体验。研究结合计算…

HTML01:HTML基本结构

HTML基本结构 <html> <head><meta charset"UTF-8"><title>我的第一个网页</title> </head> <body>我的第一个网页 </body> </html><body、</body等成对的标签&#xff0c;分别叫开发标签和闭合标签单独…

Spring Boot 实现多种来源的 Zip 多层目录打包下载(本地文件HTTP混合)

需要将一批文件&#xff08;可能分布在不同目录、不同来源&#xff09;打包成Zip格式&#xff0c;按目录结构导出给用户下载。 1. 核心思路 支持将本地服务器上的文件&#xff08;如/data/upload/xxx.jpg&#xff09;打包进Zip&#xff0c;保持原有目录结构。支持通过HTTP下载…

【Elasticsearch】在kibana中能获取已创建的api keys吗?

在 Kibana 中&#xff0c;目前没有直接的界面功能可以列出或查看已创建的 API 密钥&#xff08;API keys&#xff09;。API 密钥的管理和查看主要通过 Elasticsearch 的 REST API 来完成&#xff0c;而不是通过 Kibana 的管理界面。 在 Kibana 中使用 Dev Tools 查看 API 密钥…

公司项目架构搭建者

公司项目架构搭建者分析 项目架构搭建的核心角色 #mermaid-svg-FzOOhBwW3tctx2AR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-FzOOhBwW3tctx2AR .error-icon{fill:#552222;}#mermaid-svg-FzOOhBwW3tctx2AR .err…

《技术驯化情感:AI伴侣、监控与伦理框架的重构挑战》

技术渗透与情感异化机制 情感计算技术正通过多种核心算法和数据处理方法深入人类生活&#xff0c;其在重构人类情感关系的同时也潜藏情感异化风险。本节从生物特征捕捉、行为模式诱导和认知框架重塑三方面解析情感计算的技术机理&#xff0c;并探讨其导致的情感依赖现象。 生物…

32单片机——独立看门狗

1、IWDG的简介 IWDG&#xff1a;Independent watchdog&#xff0c;即独立看门狗 独立看门狗本质上是一个定时器&#xff0c;该定时器是一个12位的递减计数器&#xff0c;当计数器的值减到0的时候&#xff0c;就会产生一个复位信号 如果在计数没减到0之前&#xff0c;重置计数器…

[计算机网络]数据链路层

408考纲(数链层部分): 0 概论&#xff1a;数据链路层都干什么事&#xff0c;提供啥功能 比物理层再高一层就是数据链路层&#xff0c;咱们上一篇讲物理层&#xff0c;物理层直接接触传输介质&#xff0c;现在数据链路层是使用物理层的传输服务&#xff0c;然后实现更多的功能。…

OpenAI大变革!继续与微软等,以非营利模式冲击AGI

今天凌晨2点&#xff0c;OpenAI宣布&#xff0c;将继续由非营利组织控制&#xff1b;现有的营利性实体将转变为一家公共利益公司&#xff1b;非营利组织将控制该公共利益公司&#xff0c;并成为其重要的持股方。 这也就是说OpenAI曾在去年提到的由非营利性转变成营利性公司&am…

库存怎么管?怎样才能做到有效的库存管理?

说到库存管理&#xff0c;估计大多数老板和管理者都有过“烦心事”。一方面&#xff0c;库存过多&#xff0c;货物堆积如山&#xff0c;堆在仓库里也不动&#xff0c;结果占地方还占用资金&#xff1b;另一方面&#xff0c;又有可能遇到客户急着要货&#xff0c;可是库存却紧张…

Kotlin-空值和空类型

变量除了能引用一个具体的值之外,还有一种特殊的值,那就是 null, 它代表空值, 也就是不引用任何对象 在Kotlin中, 对空值的处理是非常严格的,正常情况下,我们的变量是不能直接赋值为 null 的,否则无法编译通过, 这直接在编译阶段就避免了空指针问题 Kotlin中所有的类型默认都是…

[特殊字符]算法次元突破:螺旋矩阵的“能量解码术” vs 超立方体的“维度折叠指南”

&#x1f50d; 引言 如果科幻电影中的能量矩阵是算法的考题&#xff0c;你会用螺旋指针破解它的DNA吗&#xff1f; 如果《星际穿越》的五维空间变成编程题&#xff0c;你敢用动态规划丈量时间的褶皱吗&#xff1f; 今天&#xff0c;我们将化身算法世界的能量解…

高光谱相机赋能烟叶分选:精准、高效与智能化的新突破

烟草产业作为中国重要的经济支柱&#xff0c;烟叶分选的质量与效率直接影响行业效益。传统人工分选存在效率低、主观性强、标准难以统一等问题&#xff0c;而机器视觉技术受限于可见光波段&#xff0c;难以捕捉烟叶深层特征。深圳中达瑞和科技有限公司推出的高光谱相机解决方案…