【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

构建可伸缩的有状态服务

  • 2015-12-09
  • 本文字数:2170 字

    阅读完需:约 7 分钟

来自 Twitter 的分布式系统工程师, Caitie McCaffrey ,在 Strange Loop 会议总结了有状态服务的优点,以及如何扩展它们,有状态的服务相比于无状态的服务,在业界大家知道的要少的多。其中优点包括数据定位(可通过函数传递范例来实现)、高可用、强并发模式。McCaffrey 还给出了有状态的实际案例和少量的踩过的坑。

数据局部性是指每个请求都会被路由到(“运送到”)可以操作数据的机器上。当一个请求做到时第一次命中了数据存储,之后处理数据的请求离开了服务,在将来来自内存中的数据可以让类似的请求更快的找到同样的服务。结果就是低延时的好处,毋需再去访问数据存储。这就是“函数传递范例”,是有状态服务和无状态服务区别的关键所在。

有状态的服务通常会导致强一致性的模式。根据 CAP 理论(一致性、可用性、容忍网络分区),基本上说构建一个满足三种所有属性是几乎不可能的。这里有一个非常容易理解的有关于 CAP 概念的问答。然而没有那个分布式系统能够避免“P”(问答中的#10),现实世界是要么选择可用性胜过一致性,这称之为 AP;要么选择一致性胜过可用性,这称之为 CP。有状态的服务可以构建一种粘性的链接,也就是说客户端的请求总是会被路由到原来为之提供服务的服务器主机上。以此方式实现的服务,可以增加 AP 系统的一致性力度。这些强的模式包括有线性随机访问内存和读你所写(Read your Write)。第一种实现是所有的请求所看到的写入都来自一个有序的请求,由它们自己所发出的。第二种实现是一旦请求要写,它就会读区更新后的值,且永远不会再理会旧的值。Werner Vogels在他的文章中总结了这些内容:

无论是否是读你所写、会话以及单调的一致性,这些的实现通常都依赖于“无粘性”都客户端到服务器,为它们执行分布式的协议。如果这每次都是同一台服务器的话,相对能够容易保证读你所写和 monotonic 读取。这就对负载均衡和容错稍有难度,但是它是一个较简单的解决方案。使用粘性的会话,可以更加明确以及提供抛出的客户推理的水平。

McCaffrey 谈到业界通常聚焦于无状态的服务是为了实现可扩展性而忽略了有状态的服务, Eric Evans 在他的书领域驱动开发中写道:

当在某域中的某个重要的进程或转换不是天生的负责一个实体或值的对象时,为模式增加一操作作为独立的接口来声明一个服务。定义接口是模型预言中的一个术语,还要确保操作的名称是无处不在的语言的一部分。将服务成为无状态的。

无状态的服务很容易的通过给后端添加服务器和前端的负载均衡实现横向的扩展。此类应用拥有叫做“数据运送范例”的方式,就是数据被请求时是来自后端的数据存储为请求提供,在未来的请求中,若相同的数据被请求时,是不会去关心这些请求是从哪个服务实例来的,因为服务实例是无状态的。

此模式会放之四海而皆准吗?McCaffrey 谈到在“通信频繁”的应用中简直是一种浪费,因为这些应用要在服务端与客户端之间频繁的通信,而且在此类应用中有状态的服务显然是一种更好的选择。Kai Wähner同意并列举了有状态服务的优点:

  • 当状态是共享的跨调用时,开发是容易的;
  • 不需要额外的持久存储;
  • 通常,为低延时优化。

粘性连接可以使用持久性的连接来实现,但是会带来负载在后端分布不均的问题,这就会导致客户端捆绑到服务器,而有些服务器不能得到充分利用,而有些服务器却负载过多。其中一个减轻此种后端压力的方法就是一旦达到某个阀值就拒绝再来的请求。非粘性的服务还可以通过路由的逻辑来实现,这可以使得任何的客户端通过获得正确的路由来找到任何的服务器。此实现会带来两个问题,路由到集群成员(谁在我的集群中?)和工作分布(谁来做?)。集群成员可以是静态的也可以是动态的。后者可以通过使用 gossip 协议共识系统来实现。工作分布则有更多的实现机制-随机替代、一致性哈希、以及[分布式哈希表]。

McCaffrey 谈到了三个有状态服务的真实案例:

  • Scuba ,一个 Facebook 所使用的内存数据库,用于代码分析、bug 报告、调试性能等。单个的请求会分散到多个后端服务器,然后将响应收集起来,最后决定如何将经过量化的响应完整的返回。
  • 优步的 Ringpop ,一个应用层的切片库,也提供了请求转发。
  • Orleans ,来自微软研究所的基于行为的分布式系统编程模型

有状态的模式其实在 MMO 的开发世界中是见惯不怪的,近期有很多其它领域的也在大量的采用这些模式,上面的例子就是明证。

在采访快结束的时候,McCaffrey 讨论了通过从进程的生命周期解藕内存的生命周期, Facebook 是如何管理 Scuba 的快速重启的。在 Scuba 所在的机器重启后,会花费很长的时间去从磁盘读入数据。要解决此问题就是将这些基于内存的数据从将要宕机的机器中复制到一个共享的地方,当节点恢复后再复制回来。

McCaffrey 在他的演讲中列出了一些构建有状态服务的陷阱,其中包括没有绑定的数据结构导致的内存问题、类似长期的垃圾回收暂停和重载状态时出现的内存管理问题等。状态重载会在恢复和部署新代码时发生,这两者都会像第一次从数据库中获取数据那样付出高昂的代价。

查看英文原文: Scaling Stateful Services


感谢张龙对本文的审校。

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

2015-12-09 18:0011675
用户头像

发布了 30 篇内容, 共 10.6 次阅读, 收获喜欢 0 次。

关注

评论

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

数智未来,因你而来,2022鲲鹏应用创新大赛正式启动

科技热闻

什么是127.0.0.1,如何使用这个IP地址

郑州埃文科技

IP地址 localhost

云原生训练营毕业总结

hcyycb

5种高大上的yml文件读取方式,你知道吗?

码农参上

springboot 配置文件 4月月更

线程和进程有什么区别?

InfoQ IT百科

C语言总结_函数知识

DS小龙哥

4月月更

ScheduleMaster分布式任务调度中心基本使用和原理

神农写代码

为什么计算机启动最开始的时候执行的是BIOS代码而不是操作系统自身的 代码?

InfoQ IT百科

一个完整的计算机系统是由什么组成的?

InfoQ IT百科

一文搞懂SPI通信协议

不脱发的程序猿

spi 嵌入式 通信协议

乙巳篇 天、地、人三才立 《「內元宇宙」聯載》

因田木

中庸

如何为数据库选择最佳加密方法

郑州埃文科技

数据库 加密算法

10 个使用 SQL 的 AWS 服务

郑州埃文科技

AWS sql

WEB PC 管理端打包详细教程

CRMEB

Go 语言入门很简单:时间包

宇宙之一粟

时间 Go 语言 4月月更

修改,编译,GDB调试openjdk8源码(docker环境下)

程序员欣宸

Java JVM 4月月更

正确的文档排版方式

源字节1号

java培训Redis的库存扣减操作

@零度

redis JAVA开发

web前端培训react面试题分享

@零度

前端开发 React

FlyFishV2.1更新,更好用的数据可视化编排平台

云智慧AIOps社区

开源 前端 数据可视化 大屏可视化

IP 地理定位:通过地理围栏改善虚拟环境中的数据丢失防护

郑州埃文科技

数据安全 地理围栏 ip地理定位

「面向信仰编程」Draven 专访:像写代码一样,用树形的结构写文章

Shopee技术团队

Go 语言 技术播客

搭建帮助中心,推动SaaS行业业务增长

小炮

SaaS 帮助中心

从IPv4到IPv6为什么这么久?IPv5哪里去了?

郑州埃文科技

ipv6 ipv4 ipv5

大数据培训flink中核心设计、抽象和线程模型

@零度

flink Netty 大数据开发

自己动手写Docker系列 -- 6.3 手动配置容器网络(下)

Go Docker 4月月更

明道云+百度云,自动识别填写抗原二维码

明道云

Authing 正式加入 W3C 组织,将参与相关国际标准制定

Authing

开发者 云原生 API Idaas W3C

线程的定义是什么?

InfoQ IT百科

瑞萨IDE:CS+ for CC进行BootLoader升级时开发环境配置

不脱发的程序猿

嵌入式 汽车电子 MCU 瑞萨 CS+ for CC

Robot OS添加开机启动服务

轻口味

android 4月月更 AOSP

构建可伸缩的有状态服务_DevOps & 平台工程_Hrishikesh Barua_InfoQ精选文章