写点什么

设计全球级的分布式、任务关键型应用——从实际项目中得来的教训(上)

  • 2015-11-26
  • 本文字数:3648 字

    阅读完需:约 12 分钟

此篇为设计下一代智能 DNS 和流量管理平台的 NSONE 公司的创建者和 CEO Kris Beevers 的客座文章的第一部分。点此阅读第二部分

【编者的话】随着越来越多初创科技公司的出现,如何设计全球级的分布式、任务关键性应用成为很多人关注的问题。如何在企业发展之初就考虑到系统的可扩展性?哪些才是在初期应该关注的重点呢?NSONE 创始人和CEO Kris Beevers 在博客中分享了自己进行大规模应用程序的开发经验,希望读者可以从中有所借鉴。

关于Kris Beevers

Kris Beevers 一直以来都在进行全球级的分布式大规模应用程序的设计工作。当年,他曾经逃课一年来为一个文件共享的初创项目来设计后端框架。而且,项目用户很快增加到了数百万。然而,RIAA 律师的出现,导致了项目流产。Kris 也不得不回学校继续学习。但是,通过这件事,Kris 开始在扩展系统方面积累了一定的经验。

之后,Kris 又曾在一家被 Internap 在 2011 年收购的互联网框架提供商——Voxel 公司工作。当时,他负责构建供很多大型网络公司使用的全球互联网框架。具体来说,他负责构建全球级的分布式公有云、裸机即服务以及内容传输网络等等。从中,Kris 遇到了系统扩展中可能碰到的许多问题,收获了很多经验和教训。

现在,作为 NSONE 的创始人和 CEO,Kris 在 NSONE 负责设计下一代智能 DNS 和流量管理平台。该平台服务于一些最大的互联网公司,其中很多是任务关键服务的提供商。因此,该平台是一个真正全球级的分布式、任务关键框架。随着 NSONE 平台的扩展,Kris 以往的工作经历为完成在 NSONE 的工作提供了很多帮助。

接下来,Kris 分享了一些自己的经验,希望读者可以把这些经验应用到其他项目应用中,避免走很多弯路。

每一个科技公司都会思考一个问题——随着公司业务的增长,如何应对应用程序或者系统在扩展时所不可避免遇到的各种挑战?由此,在设计任务关键技术时,一系列的基本问题就包括:如何从一开始就把可扩展性放入到考虑范围内,从而使得公司以后可以稳步、健康的发展呢?哪些才是值得现在密切关注的关键性挑战呢?而当建立一个分布式的框架时,无论是以可靠性为目标还是性能为目标,这些问题都很难回答。

使用正确的架构和流程可以使得系统和公司能够经受得住分布式、高流量应用程序所带来的冲击。由此,初创人员就可以进行不受约束的应用扩展、有效管理网络和系统失效、实时解决产品遇到的问题,从而引导公司和产品稳步成长。

从架构开始

当编写代码时,如果你总是试图使其尽可能的高效,同时又尽可能的少占用计算和存储资源。那么,停止这么干吧。

在现代分布式系统中,限制系统可扩展性的基本上不是系统的垂直深度或者特定角色内代码的效率,而是不同交互系统之间通信的效率和架构中每个角色的水平可扩展性。因此,不要优化你的代码,优化你的架构

微服务是一个好想法。它们可以把应用中相互独立的角色进行解耦合,从而可以单独扩展其中的每一个。在担心深度之前,请先计划如何水平扩展角色。服务器速度快、便宜,而且性价比还在不断提高。然而,开发者的工资却在不断提高。因此,尽可能的使用水平扩展。只有当代码真的有问题时,再考虑代码优化。

因此,在写代码之前,请先花时间好好思考一下架构——画一画框图、考虑一下通信和数据约束、形成一份好的计划书。

以角色为单位来考虑系统

一个微服务架构在一定程度上表明你正在设计一个由解耦合的子系统所组成的应用。这些子系统中的每一个都解决一个特定的问题或者担当着特殊的角色。但是,需要重申的是,你应该以角色为单位来考虑你的架构——不仅仅是因为它解耦合了扩展约束,也因为它影响你设计代码、部署系统和建设框架的方式。

一个由解耦合、互相通信的角色所组成的应用可以以进程、VM 或者容器的方式在一个单独的服务器中运行。这就使得你可以把应用部署在本地的开发环境、小的系统或者大的产品框架中。

随着应用的产品框架发展和流量及用户的增加,你可以把那些需要单独的系统或者集群的角色分离出去。但是,在你的 MVP 中,你可以通过组合产品角色来为扩展做好准备。NSONE 的最早 alpha 版本就部署在 AWS 中一个小的单独的单播 t2 实例中。现在,NSONE 的产品框架已经扩展到几百个服务器,并在全球拥有 30 个产品设施。随着系统的增长,Kris 把关键性的子系统分离到单独的服务器或者集群中,并在需要时添加宽度和冗余。

跨越全球级的分布式系统进行通信是十分困难的

去建立并扩展一个初始只部署在一个服务器、后期部署在一个数据中心的应用是一回事。解决多个数据中心间应用程序的数据传输的难题又是另外一回事。当你的子系统需要与本地之外的系统进行通信时,通信的可靠性就变得十分脆弱。这时,你需要应对的就是服务器失效和通信失效这样的双重难题。

通过互联网进行连接是十分脆弱和不可预知的。在 NSONE,Kris 等设计系统时就假设边界 DNS 传输设备会经常性的与核心设备失去连接。在非洲、巴西和印度等市场,这是经常发生的事情。但是,需要保证的是,当通信恢复时,重新聚合一定要快速。慎重考虑命令和控制消息的创建以及排队策略是其中的核心。

考虑不同设备间不同通信模式的通信也十分重要。如果你正在发送延迟敏感的关键命令和控制消息到一个或多个设备,你可能需要考虑鲁棒的消息排队系统;如果发送的是非关键信息,你可能考虑更加轻量和可靠性略差的系统;如果你发送的是需要严格同步的应用数据,带有鲁棒 WAN 响应的现代数据库可能是不错的选择。当在不同设备间通信时,你需要根据任务选择正确的工具。

对于同步和分片而言,一致性哈希是一个杀手锏武器

现在,是时候来考虑水平扩展了。你已经拥有了一些相互之间通过局域网或者互联网进行通信的子系统。为了高效服务前端的请求,系统需要尽可能的把请求发送到本地的后端进行处理。但是,在一个特殊角色中的服务器不可能是万能的。那么,究竟选择一个水平层中的哪个节点来处理跨地域的请求或者任务呢?

直观而言,你可以配置一个静态或动态的路由表——拥有某些特定 ID 的请求发送到特定的服务器。但是,当系统扩展时,路由表的扩展将会十分痛苦。例如,你可以把请求 id 哈希到一个服务器。一旦一个新的服务器添加进来,所有的请求就都需要被重新路由,数据或者缓冲的局部性一下就会被打破,由此可能引起系统崩溃。当然,你也可以设计一个十分复杂的协议来解决这一问题。但是,通常情况下,这些协议都效率低下,且容易出问题。

一致性哈希应对这种情况十分有效。它可以在不进行实际通信的情况下,保证所有节点遵循同样的协议。而且,它易于实现和扩展,子系统资源变化时所引起的代价也很小。在一个拥有很多交互角色的复杂系统中,使用一致性哈希来分配多个节点集合间消息和请求是一个十分明智的选择。

在NSONE, Kris 等采用了各种方式来使用一致性哈希,包括把 DNS 请求路由到特定的 CPU 核来最大化缓存一致性、不进行通信的情况下协商监控节点的任务以及聚合节点跨层大容量数据的分片等等

测量和监控一切东西

这是一个老生常谈,但又不得不再次强调的东西。不测量,你就不可能充分理解。即使当你没有遇到扩展性挑战的时候,充分理解系统行为也能在将来帮助你了解系统扩展时的瓶颈所在。

当然,不要只是收集一些系统度量。要让你的应用能够理解数据库响应时间、消息延迟、缓存命中率、内存碎片以及磁盘 I/O 等。首先,收集这些信息,并理解系统正常运转时的值。这样,系统发生异常时,只要重新检查这些值中有哪些异常,就可以很快定位问题所在。而且,当一个新类型的负载或者额外的流量添加到系统中时,你可以迅速感知,并相应的调整架构或子系统。

在 NSONE,Kris 等就认真研究了度量值,并将其时刻显示在监视屏幕上。当发现异常时,团队人员会问为什么,并深入挖掘。通过这种深入理解,NSONE 团队可以非常清楚平台对新的流量和负载的反应,从而特别自信的服务互联网中最大客户的 DNS 和流量管理需求。

与测量同样重要的是监控。测量和监控是两个不同的东西——测量是为了更好的理解系统行为,而监控则是探测行为中存在的异常。在项目成长过程中,监控和警告可以帮助你理解哪些异常是无害的、哪些是有害的。在项目启动之初,你可能花费很多时间来区分这些异常。但是当项目发展壮大以后,你就可以根据之前的理解,只关注那些可能影响服务的异常,避免重新设计系统的架构。

从多个有利的点来进行监控。不仅仅要从多个物理位置,还要从多个逻辑位置来进行监控。在 NSONE,Kris 等就监控内部异常监测数据,使用 Catchpoint 和 Raintank 等第三方服务进行由外而内的监控,而且利用多个数据源来观察平台和网络事件。

同样重要的是,监控不仅仅是只看到系统的状态。对于一个系统而言,提供好的服务是什么意思?是低延迟的响应时间?还是高的缓存命中率?监视这些度量,当他们超出正常范围时,发出警告。

点此继续阅读文章的第二部分


感谢杜小芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-11-26 17:313168
用户头像

发布了 268 篇内容, 共 121.8 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

Dialpad 的“野心” ,不止于 2 亿美元 ARR

CnosDB

时序数据库 开源社区 CnosDB

【Redis故障排查】「连接失败问题排查和解决」带你深入分析一下Redis阻塞原因以及问题排查方案指南

洛神灬殇

redis 分布式架构 解决方案 技术分析 性能优化分析

一些容易被忽略的测试场景

QE_LAB

移动端测试 测试场景

基于自定义数据源的LangChain的聊天

派大星

#LangChain

【 INFINI Workshop 上海站】7 月 27 日一起动手实验玩转 Easysearch

极限实验室

上海 Workshop 极限科技

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

鳄鱼视界

C++中Stack(栈)的使用方法与基本操作

芯动大师

从互联网到国企、从一线城市到三线省会

WizInfo

考上211,录取到天坑专业。。。

Jackpop

上个大学,竟然被割韭菜了?

Jackpop

直击 | 认识和了解bboss

大河

stream Binlog ETL bboss mysql cdc

语音识别唤醒词:开启智能化的语音交互时代

来自四九城儿

唤醒词

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

BlockChain先知

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

股市老人

手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实体识别、Cypher Cheetsheet详细教学等

汀丶人工智能

人工智能 深度学习 nlp 知识图谱 命名实体识别

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

西柚子

使用 Kind 体验 Kasten K10 备份还原 K8S 集群 (二)

吴威

Kubernetes 容器 k8s veeam 备份 & 恢复

2023-07-08:RabbitMQ如何做到消息不丢失?

福大大架构师每日一题

福大大架构师每日一题

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

大瞿科技

金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)

汀丶人工智能

人工智能 数据挖掘 机器学习 数学建模 LSTM

阿里P6跟P7有什么区别?

程序员小毕

Java 阿里巴巴 程序员 后端 架构师

你可能不知道现在的Java面试有多卷!

程序员小毕

程序员 高并发 架构师 java面试 八股文

某米重新定义了985。。。

Jackpop

985的分数,却毅然选择了普本。

Jackpop

拼多多最新面经出炉:项目+八股+算法+场景全都问了个遍

程序员小毕

程序员 算法 高并发 项目 java面试

具备捕获 Web2 用户能力的 PoseiSwap,治理通证$POSE再度涨超 360%

威廉META

情感语音识别:倾听声音背后的情感

来自四九城儿

情感语音识别

车内语音识别数据:驱动智能出行的新动力

来自四九城儿

车载语音识别

设计全球级的分布式、任务关键型应用——从实际项目中得来的教训(上)_方法论_张天雷_InfoQ精选文章