当前位置: 首页 > news >正文

高效协同: 打造分布式系统的三种模式

在构建分布式系统时,分布式协调是否总是必要选项?本文通过一些实际的例子讨论了这一问题,并通过把问题区分为是否具有单调性做为是否需要分布式协调的标准。原文: Avoiding Coordination Cost: Three Patterns for Building Efficient Distributed Systems

在这篇文章中,我们将讨论一个在分布式系统经常会遇到的问题(需要协调协议实现程序一致性),探讨为什么这会成为一个问题(其对可伸缩性、性能和可用性的影响),什么样的系统不需要考虑这一问题,其背后简单的直观属性(单调性),以及三个可以用来构建更高效分布式系统的简单模式。本文是基于我从Joseph M. Hellerstein和Peter Alvaro撰写的一篇题为"Keeping CALM: When Distributed Consistency is Easy"的论文中得出的结论。

准备好开始这段旅程了吗?在正文之前,我们先从一个现实世界的类比开始。

现实世界的类比: 在旅行中为了对徒步路线达成"一致"而进行的协调

有一次,我和家人预定了一块露营地。就在旅行的前一天,我的两个朋友想带着家人和我们一起旅行。我预定的露营地已经被订满了,但他们在附近的两个露营地订到了位置。所以,到了旅行的那天,我们到达了各自的露营地(相隔几英里)。

到目前为止一切顺利。第二天早上,我们意识到有个问题: 我们还没有讨论/同意当天的计划

我们需要协调当天的计划,这需要系统中所有参与者的投入。
我们需要协调当天的计划,这需要系统中所有参与者的投入。

我们需要决定去附近的哪个地方徒步。

要进行任何协调,首先需要一个协调协议(co-ordination protocol) 。分布式系统需要协调协议的原因是为了实现程序的一致性(program consistency) 。在上述情况中,我们使用的协调协议是通过电话提出并讨论徒步选项,这里的程序一致性目标是对我们当天要进行哪一次徒步达成一致。

听起来很简单,彼此打个电话决定地点,对吧?幸运的是,我的露营地有很好的网络连接,我的一个朋友(朋友#1)似乎在他的露营地也有很好的网络连接,所以我打电话给他,提出了"徒步A"的想法,而他说服我,应该去"徒步B"。但是我们都联系不上2号朋友,也没有他的消息,他的营地没有网络连接,造成了"网络分区"。因此,我们还不能决定"徒步B"作为最终计划,因为来自朋友#2的输入可能会改变最终计划。

好吧,欢迎来到"非单调(non-monotonic)"系统。

问题在于需要协调

以上就是需要协调的情况的一个例子,而且是在关键路径(critical path) 上!在这个例子中,如果我们提前约定上午9点在"徒步B"的入口见面,可能就没有问题了。

正如本文所描述的,协调协议使自治、松散耦合的机器能够共同决定如何控制基本行为,许多分布式系统利用这种协调协议来实现预期的程序结果,有许多流行的协议,如Paxos和两阶段提交。

然而,这可能会带来很高的成本,从而影响系统的可伸缩性(假设我们的朋友是10个而不是3个)、可用性(我们在等待朋友#2的时候被耽搁了)和性能(我们本可以把时间花在探索风景上)。

什么时候真正需要协调?

CALM论文提出了一个基本问题:

哪些问题可以在不需要协调的情况下以分布式方式被一致的计算,哪些问题位于该问题家族之外?

"需要"和"想要"之间是有区别的,系统真的需要使用协调协议吗,还是可以在设计时就不使用协调协议?

本文描述了系统的一个非常简单和直观的性质: **单调性(monotonicity)**,它决定了是否需要协调。下面让我们看看这是什么意思。

关键思想: 逻辑单调性(Logical Monotonicity)

为了理解单调性,让我们从反论开始: 什么时候一个系统不是单调的?

我们已经在上面的例子中看到了一个: 即使我和朋友#1已经同意了,我们还是不能继续选择徒步路线,因为来自朋友#2的输入可能会改变最终结果。这是一个非单调系统的例子,其中系统不能基于部分或不完整的信息做出最终决策

分布式垃圾收集: 非单调系统的另一个例子

CALM论文将分布式垃圾收集作为一个非单调系统的例子。每个节点上都有一组对象,节点中有一个根对象,根对象可以引用其他对象,对象可以引用其他节点中的对象。在这样的系统中,多个"本地垃圾收集器"应该如何协同工作以确定哪些对象不可访问?

论文中的图2: 具有远程引用的分布式对象引用图(虚线箭头)。可以在没有来自机器3的任何信息的情况下建立对象O3可从Root访问的事实。只有在获得全局信息是才能知道对象O5和O6是垃圾。
论文中的图2: 具有远程引用的分布式对象引用图(虚线箭头)。可以在没有来自机器3的任何信息的情况下建立对象O3可从Root访问的事实。只有在获得全局信息是才能知道对象O5和O6是垃圾。

节点需要交换关于"边"的信息。但是本地垃圾收集器不能自主做出决定,必须进行协调!最初,机器3可能确定对象O4不可达。但稍后可以从机器1接收到新的信息,证明其可达性: 通往O4的路径(Root -> O1 -> O3 -> O4)。和上面露营的例子类似,在做决定之前需要听取每个人的意见,这是一个需要协调的例子。

该论文提出了非单调系统的另一个含义: 因为这样的系统基于新的信息"改变他们的想法/决定",他们对信息的顺序敏感,也就是说,接收信息的顺序很重要。

分布式死锁检测: 单调系统的一个例子

现在让我们看看单调是什么意思,可以归结为:

基于部分或不完整信息做出的决定是否仍然稳定?基于部分信息得出的结论是否仍然具有偶然性?

论文以单调系统为例介绍了分布式死锁检测。假设在分布式数据库的不同节点上运行事务,希望检测死锁: 例如,在一个循环中,事务T1持有锁L1,正在等待另一个节点上事务T2持有的锁,而该节点又在等待L1被释放。

论文中的图1: 具有复制节点和分区边界的分布式等待图。这里有两个循环:一个只在机器1局部({T1,T2}),另一个跨越机器1和机器2({T1,T3})。
论文中的图1: 具有复制节点和分区边界的分布式等待图。这里有两个循环:一个只在机器1局部({T1,T2}),另一个跨越机器1和机器2({T1,T3})。

与垃圾收集示例类似,这里的节点必须不断交换信息。但是,一旦机器接收到帮助它确定有一个循环的信息,即使还没有从其他节点接收到任何信息,也可以自信的确定有一个循环,这里就不需要协调!如果它从更多节点接收到新的信息,可以了解更多的循环,但不会改变存在一个循环的事实。换句话说,输出随输入单调增长。

这种单调系统的另一个重要好处是,顺序并不重要,每个参与者可以以任何顺序接收信息,输出只取决于输入的内容。

单调性给我们提供了一种不需要协调实现一致性的方法

CALM论文的关键洞见在于,如果一个系统在逻辑上是单调的,我们可以通过不需要协调的方式实现一致性。论文将其描述为:

定理1。逻辑单调的一致性(Consistency As Logical Monotonicity, CALM)。当且仅当程序是单调的时,它才具有一致的、无协调的分布式实现。

论文介绍了单调程序在信息缺失的情况下是如何"安全"的,并且可以在没有任何协调的情况下继续执行。但在非单调程序中,当接收到新信息时,结果可能会发生变化,这需要引入协调,并导致参与者在等待此类信息时"停机"。

但是"一致性"在这里到底是什么意思呢?让我们看看CALM论文是如何定义一致性的。

"程序一致性" = 我们得到了期望的系统结果吗?

CALM论文没有局限于存储级别一致性,而是缩小了范围,并关注程序一致性: 程序是否产生了期望的结果?它提出了一个很实际的问题:

尽管系统在运行时存在不确定性,但程序是否产生了确定性的结果?

它把这种程序一致性称为"合流(Confluence)"。在上面旅行的例子中,这意味着所有朋友都对当天要去哪里徒步得出了相同的结论,不管通过不可靠的电话网络交换信息的顺序和时间是否确定。

收获: 如何基于上述内容构建高效分布式系统?

就构建系统的实际模式而言,上述内容有什么意义?

1. 尽可能使用单调编程模式

单调模式并不是构建高效分布式系统的唯一方法,但如果可以将系统建模为单调模式,那么就可以在不需要协调的情况下获得程序一致性的好处。

论文中提到的一个简单例子是使用tombstone来删除存储系统中的数据项(直接删除将是非单调结构)。相反,将一个项标记为已删除(tombstoning)将使其成为一个单调结构,具有tombstone的数据项单调的从未定义转换为已定义值,并最终被删除。

论文中介绍的另一个例子是Dynamo论文中的Amazon购物车。为了获得逻辑单调性,将购物车状态建模为两个不同的集: 一个集是添加到购物车的商品集,另一个集是从购物车中删除的商品集,这使得"购物"部分是单调的,而"结帐"部分是非单调的。

2. 能否在关键路径上保持协调

如果应用程序不能以单调的方式构建,那么就需要协调。但是评估一下是否能让其远离关键路径。

例子: 在上面的徒步旅行例子中,我们可以避免在关键路径上的协调(例如,在前一天晚上协调好)。对于分布式垃圾收集器示例,由于它可以在后台执行,因此所需的协调不在关键路径中。在Amazon Dynamo论文中的购物车场景中,协调仅限于"结账"(与向购物车中添加和删除物品相比,"结账"具有不同的用户期望)。

3. 是否可以对不一致进行补偿("道歉")

能容忍系统不一致吗? 如果可以的话,就可以避免协调成本。

论文中的一个例子是关于在电商网站上订购商品: 当进行购买时,库存中的商品数量应该立即减少,从而确保显示为可购买的商品确实可用。但这需要各种系统之间的协调和集成,如库存、供应链和购物。如果没有做到这一点,购买可能就会失败。然而,可以通过一封道歉电子邮件和优惠券进行补偿。这个建议也让我想起了Gregor Hohpe的著名文章"星巴克不使用两阶段提交"。

总结

CALM(Consistency As Logical Monotonicity)方法介绍了构建高效分布式系统的不同方法。通过利用单调性属性,可以以不需要协调的方式实现程序一致性。此外还提出了一个很好的问题,即一致性是否在所有情况下都是必须的目标(例如,是否可以使用补偿行动),或者是否可以从关键路径上移除。

所以,当下次我和朋友去露营的时候,相信我会探索以上所有选择:)


你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。
微信公众号:DeepNoMind

- END -

本文由 mdnice 多平台发布

相关文章:

高效协同: 打造分布式系统的三种模式

在构建分布式系统时,分布式协调是否总是必要选项?本文通过一些实际的例子讨论了这一问题,并通过把问题区分为是否具有单调性做为是否需要分布式协调的标准。原文: Avoiding Coordination Cost: Three Patterns for Building Efficient Distri…...

机器学习-无监督学习之聚类

文章目录 K均值聚类密度聚类(DBSCAN)层次聚类AGNES 算法DIANA算法 高斯混合模型聚类聚类效果的衡量指标小结 K均值聚类 步骤: Step1:随机选取样本作为初始均值向量。 Step2:计算样本点到各均值向量的距离,…...

智能垃圾桶丨悦享便捷生活

垃圾桶是人们日常生活所必不可少的必需品,它让生活中所产生的垃圾有了一个正确的存放地方。随着生产技术的迅速发展,垃圾桶也得以更新换代。由最初的简单式的圆筒式垃圾桶,到现在出现的感应式垃圾桶、智能语音控制垃圾桶,垃圾桶也…...

【数据结构】线性表(一)线性表的定义及其基本操作(顺序表插入、删除、查找、修改)

目录 一、线性表 1. 线性表的定义 2. 线性表的要素 二、线性表的基本操作 三、线性表的顺序存储结构 1. 定义 2. 顺序表的操作 a. 插入操作 b. 删除操作 c. 查找操作 d. 修改操作 e. 代码实例 一、线性表 1. 线性表的定义 一个线性表是由零个或多个具有相同…...

MyBatis的自定义插件

MyBatis的自定义插件 前置知识 MyBatis 可以拦截的四大组件 Executor - 执行器StatementHandler - SQL 语句构造器ParameterHandler - 参数处理器ResultSetHandler - 结果集处理器 自定义 MyBatis 插件 /*** 打印 sql 执行的时间插件*/ Intercepts(// 指定拦截器拦截的对象…...

生物制剂\化工\化妆品等质检损耗、制造误差处理作业流程图(ODOO15/16)

生物制剂、化工、化妆品等行业,因为产品为液体,产品形态和质量容易在各个业务环节发生变化,常常导致实物和账面数据不一致,如果企业业务流程不清晰,会导致系统大量的库存差异,以及财务难以核算的问题&#…...

vbv介绍

VBV模型 VBV即Video Buffer Verifier(视频缓冲区校验器)。 本质是encoder端的一个虚拟buffer,可以将VBV当做一个容量受限的管道,有一个上限容量值和下限容量值,在经过此管道的调节之后能限制编码码率在上限容量值和下限容量值之间。VBV对标NetEq中的那几个buffer(decoder b…...

Linux CentOS 8(网卡的配置与管理)

Linux CentOS 8(网卡的配置与管理) 目录 一、项目介绍二、命令行三、配置文件四、图形画界面的网卡IP配置4.1 方法一4.2 方法二 一、项目介绍 Linux服务器的网络配置是Linux系统管理的底层建筑,没有网络配置,服务器之间就不能相互…...

python -m pip install 和 pip install 的区别解析

python -m pip install 和 pip install 的区别解析 python -m pip install 使用了 -m 参数来确保以 Python 模块的形式运行 pip,适用于确保在不同的环境中正确使用 pip,这篇文章主要介绍了python -m pip install 和 pip install 的区别,需要的朋友可以参…...

深度解读js中数组的findIndex方法

js中数组有一个findIndex方法,这个方法是一个让人感到很困惑的方法。 首先来看看MDN对这个方法的解释:Array.prototype.findIndex() - JavaScript | MDN The findIndex() method of Array instances returns the index of the first element in an arra…...

ICML2021 | RSD: 一种基于几何距离的可迁移回归表征学习方法

目录 引言动机分析主角(Principal Angle)表征子空间距离正交基错配惩罚可迁移表征学习实验数据集介绍 实验结果总结与展望 论文链接 相关代码已经开源 引言 深度学习的成功依赖大规模的标记数据,然而人工标注数据的代价巨大。域自适应&…...

中国人民大学与加拿大女王大学金融硕士:在该奋斗的岁月里,对得起每一寸光阴

在这个快速变化的世界中,金融行业面临不断更新的挑战和机遇。为了应对这些挑战,中国人民大学与加拿大女王大学合作举办金融硕士项目,旨在培养具有国际视野、扎实的金融理论基础和实战经验的专业人才。 中国人民大学和加拿大女王大学金融硕士…...

Python基础教程:装饰器的详细教程

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 一、什么是装饰器 目的:给func()方法,增加一个功能,在fun()执行期间,同时把fun()执行速率机算出来 import time def func():print(嘻嘻哈哈)start_time time.time() ti…...

Apache poi xwpf word转PDF中文显示问题解决

原问题解决方法&#xff1a;https://github.com/opensagres/xdocreport/issues/161 POM依赖 <properties><java.version>1.8</java.version><poi.version>3.14</poi.version></properties><dependencies><dependency><gro…...

Gartner发布2024年十大战略技术趋势

今日&#xff0c;Gartner发布了2024年企业机构需要探索的十大战略技术趋势。这十大趋势包括&#xff1a;全民化的生成式&#xff1b;AI 信任、风险和安全管理&#xff1b;AI 增强开发&#xff1b;智能应用&#xff1b;增强型互联员工队伍&#xff1b;持续威胁暴露管理&#xff…...

在UniApp中使用uni.makePhoneCall方法调起电话拨打功能

目录 1.在manifest.json文件中添加权限 2. 组件中如何定义 3.如何授权 4.相关知识点总结 1.在manifest.json文件中添加权限 {"permissions": {"makePhoneCall": {"desc": "用于拨打电话"}} }2. 组件中如何定义 <template>…...

苹果手机怎么刷机?掌握好这个方法!

苹果手机以其优秀的性能与高颜值的设计赢得了一大批用户的喜爱。但是&#xff0c;当手机使用久了以后&#xff0c;难免会出现一些系统问题。在遇到运行不稳定、忘记锁屏密码、软件故障、频繁死机等情况时&#xff0c;我们可能需要对手机进行刷机来解决问题。那么&#xff0c;苹…...

最新ai创作系统CHATGPT系统源码+支持GPT4.0+支持ai绘画(Midjourney)

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…...

代码随想录算法训练营Day56|动态规划14

代码随想录算法训练营Day56|动态规划14 文章目录 代码随想录算法训练营Day56|动态规划14一、1143.最长公共子序列二、 1035.不相交的线三、53. 最大子序和 动态规划 一、1143.最长公共子序列 class Solution {public int longestCommonSubsequence(String text1, String text2…...

VsCode通过Git History插件查看某个页面的版本修改记录

首先需要安装插件Git History 方式一&#xff1a;通过 点击File History 查看某个文件变更&#xff1b;即通过commit的提交记录去查看某个文件的修改 方式二&#xff1a;通过点击选择toggle File Blame 查看当前页面每一行所有提交修改记录...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...