写点什么

从 Bitly 构建分布式系统中吸取的教训

  • 2014-08-05
  • 本文字数:2091 字

    阅读完需:约 7 分钟

在五月的 Bacon 会议中,bitly 应用开发主管 Sean O’Connor 讲解了bitly 开发人员从构建一个月处理点击量 60 亿的分布式系统中吸取到的相关教训。

什么是分布式系统?

Sean 表示,关于分布式系统的定义很容易在维基百科上找到,一个分布式系统有三个很明显的特征:

  • 组件节点间真正的并发,要有相关的开销和复杂度来协调这些节点。
  • 缺少一个共有的时钟,让不同节点上的事件按时间顺序发生是不可能的。
  • 独立的故障,应该被理解为具有这样的能力:一个节点的失败不会影响到系统中的其他节点。

构建一个分布式系统需要处理好这些特性。Sean 认为这样的一种方法已经过时了。这种方法通过将系统从一开始就抽象成不是分布式的系统,隐藏了一个系统的分布式特性带来的复杂度。Sean 说,由于系统的分布式特性迟早会从抽象中显现出来,这种方法注定会失败。取而代之的,抽象应该建立系统分布式特性的模型,并处理好任何显现出来的特性。

将服务作为积木

Bitly 的架构使用服务的概念进行定义。一个服务是通过 API 明确定义的、专门提供一些功能的抽象。根据 Sean 的描述,服务对应于分布式系统就像函数对应于代码,这就允许站在更高的层次上看问题,而不用知道所有的实现细节。这个想法带来了另一种思考问题的方式。

Sean 提到了通过小型服务构建系统所获得的益处:

  • 代码行数的减少,使得一个服务更容易被理解。
  • 独立的故障,因为如果一个服务停止只意味着系统失去了特定的功能,但整体上系统仍然保持运行。
  • 易于判别系统的哪部分存在问题。

异步消息传递

确保一个系统可扩展的关键点是,在节点之间使用异步消息和消息队列来改进节点的独立性,所以一个节点没有必要等待另一个节点的回应。

这样做的一个好处是,如果一个节点出现了一些问题而暂时不能处理所有到来的消息时,这些消息将被保存在队列中以便尽快处理。此外,一个节点的故障不会直接影响其他节点。

尽管在许多场景中,异步消息传递更自然地用于同步处理某一类操作,但它也有复杂之处。比如 Sean 提到,在 bitly,由于对数据处理有越快越好和一致性的要求,缩短 URL 是一个完全同步的操作。这意味着一个缩短后的 URL 不应该返回给不同的使用者。另一方面,分析有着不同的需求,适合于使用完全异步的操作执行。因此,当 bitly 想要收集处理关于用户在链接上的行为的度量数据时,它只是将数据放进流向下游处理的队列中,而不用关心处理需要花多长时间。根据 Sean 的解释,尝试将一个本质上同步的操作异步化可能非常复杂,因此最好能先了解这个操作的本质。

关于节点间的交互,Sean 最终的评论指出,相比于将消息看成是从一个节点流到另一个节点的命令,把消息当成事件将更有益。一个事件是对某地发生某事的一个描述,并且发送节点不需要知道接收节点的任何信息。另一方面,如果一条消息是一个命令,那么发送节点必须了解接收节点处理这条命令的能力。因此,在生产者节点不知道任何信息的情况下,把消息看待成事件极大地有助于节点隔离、天然地支持多消费者以及消费者的动态增加和删除。

把消息当成事件也会导致另外一种实现:从生产者的角度看,标记消息的方法比过滤消息的方法更好。作为一个例子,Sean 提到了私有和公有链接的处理。生产者可以对私有链接进行过滤,以确保这些链接不会到达对其不感兴趣的下游节点。但这要求生产者能推断出下游需要关心什么样的数据。取而代之地,bitly 对私有链接进行标记,让消息自由地流入下游,确信下游节点能够以适当的方式对消息进行处理。

让服务能良好地运行在一起

Bitly 通过以下方法确保服务良好地运行在一起:

  • 使用排压机制,让发送请求的节点知道一个服务是否繁忙或过载,这样它们就能够调节发送请求的速率。这有助于维持系统的健康,防止连锁错误的发生。作为一个例子,Sean 提到了服务缓存的初始化:如果在缓存初始化过程中不断地接收到请求,就会有导致数据出错的风险。
  • 根据服务的健康状态对请求进行负载均衡。Bitly 使用了自己开发的 hostpool 用于负载均衡,跟踪失败的服务并优先选择更健康的服务。

监控

通过引用Leslie Lamport 的话“一个分布式系统是一个这样的系统,系统中一台机器上未知的故障都可能会导致你自己的计算机无法使用”,Sean 引入了监控这个话题。Bitly 拥有400 多台服务器,所以监控是一个非常必要的任务,因为这是知道系统中某些东西无法正常工作的唯一途径。

Sean 提供了一些关于监控的诀窍:

  • 使用 Nagios 检查服务器状态。
  • 运行完整性检查以确保服务提供正确的数据。
  • 将日志集中在一起,因为集中不同节点的日志有助于分析和诊断系统中发生了什么。
  • 确保相关的人能及时收到相关的信息。Bitly 使用了自己开发的 nsq 消息平台,旨在通过和 Web UI 的结合,能容易地观察到部署期间的一举一动。

Bitly 是一个用于社交网络,短信和电子邮件的缩短URL 服务。除了缩短URL,bitly 也搜集关于引用链接的分析数据,这是bitly 商业模型的核心。

参考英文原文: Lessons Learned Building Distributed Systems at Bitly


感谢郭蕾对本文的审校。

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

2014-08-05 23:222586

评论

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

软件差异化升级——差量包篇

golf

golang 后端 升级 差量包

幸福城市平台:数据库选型与优化实践

TiDB 社区干货传送门

数据库架构选型

三地五中心,TiDB POC最佳姿势探索

TiDB 社区干货传送门

7.x 实践

华为校园公开课|哈尔滨工业大学(威海)圆满收官

最新动态

基于云原生的集群自愈系统 Flink Cluster Inspector

Apache Flink

大数据 flink 实时计算

一场不发手机的发布会,一场沉默且浩瀚的远征

脑极体

手机

Python 中的字符串基础与应用

小万哥

Python 开源 程序员 后端 开发

03. 人工智能核心基础 - 导论(2)

茶桁

人工智能 方法论 问题范式

【运维实操】TIDB v6.1.1:全量备份、全量恢复和增量备份方法解析

TiDB 社区干货传送门

实践案例 安装 & 部署 备份 & 恢复

如何搭建一个专属的认证中心(一)

Kevin_913

spring security OAuth 2.0 java 架构

三力四总线,为智能世界画一张蓝图

脑极体

华为

政务与大模型,在国云上相遇

脑极体

云计算

采用get()和put()读写文件

芯动大师

c++

【AI产品】Podwise:AI助我听播客

无人之路

AI 播客 技术播客

【实践案例】软件差异化升级——吃包篇

golf

golang 后端 升级 吃包 差异化

【中秋国庆不断更】XML在HarmonyOS中的生成,解析与转换(上)

HarmonyOS开发者

专访中欧财富伍春兰:财富管理行业数字化转型升级,数据库如何选型?

TiDB 社区干货传送门

实践案例 数据库架构选型

商业版 Plus '遥遥领先' | 相约10月

开源物联卡管理平台-设备管理

物联网 IoT 国际化 物联网应用 国产开源

自动群发节日祝福,1行Python代码搞定!

程序员晚枫

Python 微信 开源 机器人

【玩转 EdgeOne】边缘行者,速必达

指剑

腾讯云 CDN EdgeOne

零基础Python经验体验代码检查工具

云计算 华为云 代码检查

使用 AI 编程助手 CodeWhisperer,开发如有神助

亚马逊云科技 (Amazon Web Services)

人工智能 亚马逊云科技

【中秋国庆不断更】OpenHarmony定义扩展组件样式:@Extend装饰器

OpenHarmony开发者

OpenHarmony

我来聊聊面向组件的前端开发

欧雷

软件工程 前端开发 前端架构 组件化 前端工程化

从Bitly构建分布式系统中吸取的教训_SOA_Sergio De Simone_InfoQ精选文章