“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

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

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

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

关注

评论

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

奥运“哮喘”运动员为什么越来越多?

脑极体

第一次凡尔赛,字节跳动3面+腾讯6面一次过,谈谈我的大厂面经

编程菌

Java 编程 程序员 面试 计算机

为什么需要数据库连接池

赖猫

MySQL 数据库 后端 连接池

架构实战营 模块四作业

孫影

架构实战营 #架构实战营

「SQL数据分析系列」15. 元数据

数据与智能

sql 脚本 元数据

再见 Jenkins!几行脚本搞定自动化部署,这款神器有点厉害

编程菌

Java 编程 程序员 计算机 技术宅

Linux之watch命令

入门小站

Linux

Elasticsearch VS ClickHouse

Se7en

Windows10下JDK8下载及java环境配置

Bob

8月日更

趁着课余时间学点python(二)缩进 标识符 保留字 注释 输入输出的理解

ベ布小禅

8月日更

【前端 · 面试 】HTTP 总结(三)—— HTTP 请求方法

编程三昧

面试 大前端 HTTP 8月日更 HTTP方法

一个好的产品需要一个好的产品

刘宇

产品经理

JDK 从8升级到11,使用 G1 GC,HBase 性能下降近20%。JDK 到底干了什么?

毕昇JDK社区

缓存数据历险记(一)--被缓存警察上课一天

卢卡多多

redis 缓存 8月日更

Hbase 入门详解

Se7en

体验设计落地的四个原则和十个步骤

石云升

用户体验 关键时刻 体验设计 8月日更

NLP随笔(三)

毛显新

人工智能 自然语言处理 神经网络 深度学习

SpringBoot 中的事务处理

xcbeyond

事务 springboot 8月日更

在线网页快捷方式创建工具

入门小站

工具

声网Agora发布教育信息化解决方案 助力教育公平提效

声网

人工智能 在线教育

Vue3异步数据加载组件:suspense

devpoint

Vue 3 8月日更

【最不佳实践】文件上传并不简单

刘宇

Python Serverless 文件上传

弱口令到底是什么牛马?

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞挖掘

精彩回顾 | 阿里云 Serverless Developer Meetup 杭州站亮点有这些!

阿里巴巴云原生

阿里云 Serverless 云原生 Meetup

架构实战营 毕业设计

竹林七贤

王者并发课-钻石2:分而治之-如何从原理深入理解ForkJoinPool的快与慢

MetaThoughts

Java 多线程 并发

【最不佳实践】函数计算的函数是什么意思

刘宇

Serverless

我测了啊,我真测了!

QualityFocus

测试 质量保障 线上问题 缺陷

从未如此简单:基于Serverless架构的博客

刘宇

Serverless Hexo 博客

各种消息队列设计要点与对比

海明菌

消息队列 消息队列对比 消息队列系统设计

网络攻防学习笔记 Day94

穿过生命散发芬芳

网络攻防 8月日更

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