2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

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

  • 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:313868
用户头像

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

关注

评论

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

双减来了!人工智能如何促进教育领域转型?

京东科技开发者

人工智能 大数据 AI 教育行业

万字长文,一篇吃透WebSocket:概念、原理、易错常识、动手实践

JackJiang

websocket 即时通讯 IM

AUTOSAR基础篇之OS(上)

SOA开发者

实时音频抗弱网技术揭秘

百度开发者中心

最佳实践 经验分享 智能视频

声网 2020 实时大会后的弱网对抗实践

声网

音视频 网络环境 视频编解码 弱网下的极限实时视频通信

RUOYI 框架教程 15|若依框架中 Mysql 操作 | 日期处理

Java_若依框架教程

Java 技术 Ruoyi 框架 若依

再见收费的Navicat!操作所有数据库靠它就够了!

Java 数据库 架构 开源项目

想提高运维效率,那就把MySQL数据库部署到Kubernetes 集群中

华为云开发者联盟

MySQL 运维 测试 MySQL数据库 Kubernetes 集群

还在苦恼网络协议?阿里大佬这份笔记带你从入门到精通!

Java 架构 面试 程序人生 编程语言

OpenCV学习(三):三重境界

轻口味

OpenCV图像处理 10月月更

2021年9月国产数据库大事记

墨天轮

数据库 华为云 国产数据库 达梦 人大金仓

明道云当选“中国电子商会数据资源服务创新专业委员会”理事单位

明道云

解读业界5种主流的深度网络模型

华为云开发者联盟

模型 网络模型 模型优化 模型量化 深度网络

为了让你搞定数据库选型,这些工程师重写了 26 万行代码

SphereEx

数据库 架构 架构设计 ShardingSphere SphereEx

10月活动推荐:2021上汽集团“新四化”技术高峰论坛

SOA开发者

GitHub标星过万!阿里内部流传的JDK源码剖析手册到底有多强?

程序员 jdk 面试 java

我用 10000 张图片合成我们美好的瞬间

荣顶

JavaScript 大前端 canvas 图形处理

用21张图,把Git 工作原理彻底说清楚

git 架构 面试 后端

The Data Way Vol.5|这里有一场资本与开源的 battle

SphereEx

开源 播客 ShardingSphere SphereEx

一个约定让全球数万AI爱好者相聚,它是如何做到的?

硬科技星球

[架构实战营]模块九作业

xyu

#架构实战营

每一个用到canvas的小伙伴都应该了解的fabric.js

荣顶

JavaScript 大前端 canvas 图形处理 画布

Java 面试的“完美圣经”,有了这些还愁面试吗?

Java 程序员 架构 面试 后端

ShardingSphere X Google 编程之夏:同学,开源你怎么看?

SphereEx

开源社区 ShardingSphere 谷歌 编程之夏

嵌入式软件时序(1)— C语言是怎么编译出来的

SOA开发者

MongoDB中文社区 Freetalk,一起来玩快闪!

MongoDB中文社区

mongodb

基于HarmonyOS分布式技术,他们让绘画体验更为出色

Geek_283163

鸿蒙

“828页Java面试手册”在我手,何愁offer不到手!

Java 程序员 架构 面试 后端

Docgeni 1.1.0 正式发布!

PingCode研发中心

标签 Docgeni 文档目录 进度展示 日志展示

车云一体的应用价值

SOA开发者

Python代码阅读(第35篇):完全(深度)展开嵌套列表

Felix

Python 编程 Code Programing 阅读代码

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