分布式学习最佳实践:从分布式系统的特征开始

news2024/11/28 4:28:45

正文  

        

  在延伸feature(分布式系统需要考虑的特性)的时候,我逐渐明白,这是因为要满足这些feature,才设计了很多协议与算法,也提出了一些理论。比如说,这是因为要解决去中心化副本的一致性问题,才引入了Paxos(raft)协议。而每一个分布式系统,如分布式存储、分布式计算、分布式消息队列、分布式RPC框架,根据业务的不同,会使用不同的方法来满足这些feature,对这些feature的支持也可能会有权衡,比如一致性与可用性的权衡。

  所有,我觉得从分布式的特性出发,来一步步学习分布式是一种可行的方式。

从分布式系统的特征出发

分布式的世界中涉及到大量的协议(raft、2pc、lease、quorum等)、大量的理论(FLP, CAP等)、大量的系统(GFS、MongoDB、MapReduce、Spark、RabbitMQ等)。这些大量的知识总是让我们无从下手,任何一个东西都需要花费大量的时间,特别是在没有项目、任务驱动的时候,没有一个明确的目标,真的很难坚持下去。

  所以,我一直在思考,能有什么办法能把这些东西串起来?当我掌握了知识点A的时候,能够自然地想到接下来要学习B知识,A和B的关系,也许是递进的,也许是并列的。我也这样尝试了,那就是《什么是分布式系统,如何学习分布式系统》一文中我提到的,思考一个大型网站的架构,然后把这些协议、理论串起来。按照这个想法,我的计划就是去逐个学习这些组件。

  但是,其实在这里有一个误区,我认为一个大型网站就是一个分布式系统,包含诸多组件,这些组件是分布式系统的组成部分;而我现在认为,一个大型网站包含诸多组件,每一个组件都是一个分布式系统,比如分布式存储就是一个分布式系统,消息队列就是一个分布式系统。

  为什么说从思考分布式的特征出发,是一个可行的、系统的、循序渐进的学习方式呢,因为:

  (1)先有问题,才会去思考解决问题的办法

  由于我们要提高可用性,所以我们才需要冗余;由于需要扩展性,所以我们才需要分片

  (2)解决一个问题,常常会引入新的问题

  比如,为了提高可用性,引入了冗余;而冗余又带来了副本之间的一致性问题,所以引入了中心化副本协议(primary/secondary);那么接下来就要考虑primary(节点)故障时候的选举问题。。。

  (3)这是一个金字塔结构,或者说,也是一个深度优先遍历的过程。

  在这个过程中,我们始终知道自己已经掌握了哪些知识;还有哪些是已经知道,但未了解的知识;也能知道,哪些是空白,即我们知道这里可能有很多问题,但是具体是什么,还不知道。

  

  那么,各个分布式系统如何与这些特征相关联呢?不难发现,每个分布式系统都会或多或少的体现出这些特征,只是使用的方法、算法可能不大一样。所以,我们应该思考,某一个问题,在某个特定系统中是如何解决的。比如元数据管理的强一致性,在MongoDB中是如何实现的,在HDFS中是如何实现的。这也指导了我们如何去学习一个具体的分布式系统:带着问题,只关注关心的部分,而不是从头到尾看一遍。

  下面是,到目前为止,我对分布式特征的思维导图

   

  对于上图,需要声明的是,第一:不一定完全正确,第二:不完整。这是因为,我自己也在学习中,可以看到,很多分支很短(比如去中心化副本协议),不是因为这一块没有内容,而是我压根儿还没去了解,还没去学习。

  我会持续跟新这幅脑图的

  

  下一章,介绍一下分布式系统的各个特征。

分布式系统的一般特征

任何介绍分布式系统的文章或者书籍都会提到分布式系统的几个特性:可扩展性、高性能、高可用、一致性。这几个特性也是分布式系统的衡量指标,正是为了在不同的程度上满足这些特性(或者说达到这些指标),才会设计出各种各样的算法、协议,然后根据业务的需求在这些特性间平衡。

  那么本章节简单说明,为什么要满足这些特性,要满足这些特性需要解决什么问题,有什么好的解决方案。

可扩展性

  

Scalability is the capability of a system, network, or process to handle a growing amount of work, or its potential to be enlarged to accommodate that growth.

  可扩展性是指当系统的任务(work)增加的时候,通过增加资源来应对任务增长的能力。可扩展性是任何分布式系统必备的特性,这是由分布式系统的概念决定的:

分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统

  分布式系统的出现是为了解决单个计算机无法完成的计算、存储任务。那么当任务规模增加的时候,必然就需要添加更多的节点,这就是可扩展性。

  扩展性的目标是使得系统中的节点都在一个较为稳定的负载下工作,这就是负载均衡,当然,在动态增加节点的时候,需要进行任务(可能是计算,可能是数据存储)的迁移,以达到动态均衡。

  那么首先要考虑的问题就是,如何对任务进行拆分,将任务的子集分配到每一个节点,我们称这个过程问题Partition(Sharding)

第一:分片分式,即按照什么算法对任务进行拆分

  常见的算法包括:哈希(hash),一致性哈希(consistency hash),基于数据范围(range based)。每一种算法有各自的优缺点,也就有各自的适用场景。

第二:分片的键,partition key

  partition key是数据的特征值,上面提到的任何分片方式都依赖于这个partition key,那么该如何选择呢

 based on what you think the primary access pattern will be

  partition key会影响到任务在分片之间的均衡,而且一些系统中(mongodb)几乎是不能重新选择partition key的,因此在设计的时候就得想清楚

第三:分片的额外好处

  提升性能和并发:不同的请求分发到不同的分片

  提高可用性:一个分片挂了不影响其他的分片

第四:分片带来的问题

  如果一个操作需要跨越多个分片,那么效率就会很低下,比如数据中的join操作

第五:元数据管理

  元数据记录了分片与节点的映射关系、节点状态等核心信息,分布式系统中,有专门的节点(节点集群)来管理元数据,我们称之为元数据服务器。元数据服务器有以下特点:

  高性能:cache

  高可用:冗余 加 快速failover

  强一致性(同时只有一个节点对外提供服务)

第六:任务的动态均衡

  为了达到动态均衡,需要进行数据的迁移,如何保证在迁移的过程中保持对外提供服务,这也是一个需要精心设计的复杂问题。

可用性

  

  可用性(Availability)是系统不间断对外提供服务的能力,可用性是一个度的问题,最高目标就是7 * 24,即永远在线。但事实上做不到的,一般是用几个9来衡量系统的可用性,如下如所示:

  

  也就是如果要达到4个9的可用度(99.99%),那么一年之中只能有52.6分钟不可用,这是个巨大的挑战

  为什么分布式系统中必须要考虑可用性呢,这是因为分布式系统中故障的概率很高。分布式系统由大量异构的节点和网络组成,节点可能会crash、断电、磁盘损坏,网络可能丢包、延迟、网络分割。系统的规模放大了出故障的概率,因此分布式系统中,故障是常态。那么分布式系统的其中一个设计目标就是容错,在部分故障的情况下仍然对外提供服务,这就是可用性。

  冗余是提高可用性、可靠性的法宝

  冗余就是说多个节点负责相同的任务,在需要状态维护的场景,比如分布式存储中使用非常广泛。在分布式计算,如MapReduce中,当一个worker运行异常缓慢时,master会将这个worker上的任务重新调度到其它worker,以提高系统的吞吐,这也算一种冗余。但存储的冗余相比计算而言要复杂许多,因此主要考虑存储的冗余。

  维护同一份数据的多个节点称之为多个副本。我们考虑一个问题,当向这个副本集写入数据的时候,怎么保证并发情况下数据的一致性,是否有一个节点有决定更新的顺序,这就是中心化、去中心话副本协议的区别。

中心化与去中心化

  中心化就是有一个主节点(primary master)负责调度数据的更新,其优点是协议简单,将并发操作转变为顺序操作,缺点是primar可能成为瓶颈,且在primary故障的时候重新选举会有一段时间的不可用。

  去中心化就是所有节点地位平等,都能够发起数据的更新,优点是高可用,缺点是协议复杂,要保证一致性很难。

  提到去中心化,比较有名的是dynamo,cassandra,使用了quorum、vector clock等算法来尽量保证去中心化环境下的一致性。对于去中心化这一块,目前还没怎么学习,所以下面主要讨论中心化副本集。

节点更新策略

  primary节点到secondary节点的数据时同步还是异步,即客户端是否需要等待数据落地到副本集中的所有节点。

  同步的优点在于强一致性,但是可用性和性能(响应延迟)比较差;异步则相反。

数据流向

  即数据是如何从Primary节点到secondary节点的,有链式和主从模式。

  链式的优点时充分利用网络带宽,减轻primary压力,但缺点是写入延迟会大一些。GFS,MongoDB(默认情况下)都是链式。

部分节点写入异常

  理论上,副本集中的多个节点的数据应该保持一致,因此多个数据的写入理论上应该是一个事务:要么都发生,要么都不发生。但是分布式事务(如2pc)是一个复杂的、低效的过程,因此副本集的更新一般都是best effort 1pc,如果失败,则重试,或者告诉应用自行处理。

primary的选举

  在中心化副本协议中,primary节点是如何选举出来的,当primary节点挂掉之后,又是如何选择出新的primary节点呢,有两种方式:自治系统,依赖其他组件的系统。(ps,这两个名字是我杜撰的 。。。)

  所谓的自治系统,就是节点内部自行投票选择,比如mongodb,tfs,zookeeper

  依赖其他组件的系统,是指primary由副本集之后的组件来任命,比如GFS中的primary由master(GFS的元数据服务器)任命,hdfs的元数据namenode由zookeeper心跳选出。

secondary是否对外提供服务(读服务)

   中心化复制集中,secondary是否对外提供读服务,取决于系统对一致性的要求。

  比如前面介绍到节点更新策略时,可能是异步的,那么secondary上的数据相比primary会有一定延迟,从secondary上读数据的话无法满足强一致性要求。

  比如元数据,需要强一致性保证,所以一般都只会从primary读数据。而且,一般称主节点为active(master),从节点为standby(slave)。在这种情况下,是通过冗余 加上 快速的failover来保证可用性。

一致性

  

  从上面可以看到,为了高可用性,引入了冗余(副本)机制,而副本机制就带来了一致性问题。当然,如果没有冗余机制,或者不是数据(状态)的冗余,那么不会出现一致性问题,比如MapReduce。

  一致性与可用性在分布式系统中的关系,已经有足够的研究,形成了CAP理论。CAP理论就是说分布式数据存储,最多只能同时满足一致性(C,Consistency)、可用性(A, Availability)、分区容错性(P,Partition Tolerance)中的两者。但一致性和可用性都是一个度的问题,是0到1,而不是只有0和1两个极端。详细可以参考之前的文章《CAP理论与MongoDB一致性,可用性的一些思考》

  一致性从系统的角度和用户的角度有不同的等级。

系统角度的一致性

   强一致性、若一致性、最终一致性

用户角度的一致性

   单调读一致性,单调写一致性,读后写一致性,写后读一致性

高性能

  

   正式因为单个节点的scale up不能完成任务,因此我们才需要scale out,用大量的节点来完成任务,分布式系统的理想目标是任务与节点按一定的比例线性增长。

衡量指标

  高并发

  高吞吐

  低延迟

  不同的系统关注的核心指标不一样,比如MapReduce,本身就是离线计算,无需低延迟

可行的办法

  单个节点的scaleup

  分片(partition)

  缓存:比如元数据

     短事务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/866814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SCAU操作系统知识点之(六)并发:死锁和饥饿

1、死锁原因:竞争资源、进程推进顺序不当 2、资源分配图(若死锁,则资源分配图中必有环路,但有环路时不一定死锁) 3、死锁的四个必要条件 ①互斥 ②占有且等待 ③不可抢占 ④循环等待 在死锁的四个必要条件中&#xff…

jupyter默认工作目录的更改

1、生成配置文件:打开Anaconda Prompt,输入如下命令 jupyter notebook --generate-config询问[y/N]时输入y 2、配置文件修改:根据打印路径打开配置文件jupyter_notebook_config.py,全文搜索找到notebook_dir所在位置。在单引号中…

Vue组件库

Vue组件库 ViteVue3TypescriptTSX 1、项目搭建 1.1、创建项目(yarn) D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh pa…

python使用matplot库绘图颜色表

matlpot的color参数可以是十六进制,也可以是颜色描述的字符串。 下面是字符串描述的颜色表。为了颜色间要有区分度。同时要求颜色比较明显,特意选择一些比较有代表性的颜色,以供使用(颜色由于个人需要,除去了红色和绿…

SpringBoot启动图标替换-banner文件

1.banner.txt文件内容如下 ${AnsiColor.BRIGHT_YELLOW}${AnsiStyle.BOLD}_________ .__ __________ __ / _____/____________|__| ____ ____\______ \ ____ _____/ |_ \_____ \\____ \_ __ \ |/ \ / ___\| | _//…

实践|Linux 中查找和删除重复文件

动动发财的小手,点个赞吧! 如果您习惯使用下载管理器从互联网上下载各种内容,那么组织您的主目录甚至系统可能会特别困难。 通常,您可能会发现您下载了相同的 mp3、pdf 和 epub(以及各种其他文件扩展名)并将…

tkinter文件对话框

文章目录 文件对话框文件对象文件类型其他参数 tkinter系列: GUI初步💎布局💎绑定变量💎绑定事件💎消息框扫雷小游戏💎强行表白神器 文件对话框 filedialog提供了多种与文件交互相关的对话框&#xff0c…

Linux:Shell编辑之文本处理器(awk)

目录 绪论 1、用法 1.1 格式选项 1.2 awk 常用内置变量 1.3 awk的打印功能 1.4 奇偶打印 1.5 awk运算 1.6 awk的内置函数:getline 1.7 文本过滤打印 1.8 awk条件判断打印 1.9 三元表达式,类似于java 1.10 awk的精确筛选 1.11 awk和tr比较改变…

【Django】无法从“django.utils.encoding”导入名称“force_text”

整晚处理 Django 的导入错误。 我将把它作为提醒,希望处于相同情况的人数会减少。 原因 某些软件包版本不支持Django 4 请看下表并决定Django和Python的版本 方案 如果出现难以响应,或者更改环境麻烦,请尝试以下操作 例如出现以下错误 …

【Github】SourceTree技巧汇总

sourceTree登录github账户 会跳转到浏览器端 按照Git Flow 初始化仓库分支 克隆远程仓库到本地 推送变更到远程仓库 合并分支 可以看到目前的本地分支(main、iOS_JS)和远程分支(origin/main、origin/HEAD、origin/iOS_JS)目前所处…

时间序列预测任务下探索深度学习参数对模型预测性能的影响

时间序列相关的项目在我之前的很多博文中都有涉及,覆盖的数据领域也是比较广泛的,很多任务或者是项目中往往是搭建出来指定的模型之后就基本完成任务了,比较少去通过实验的维度去探索分析不同参数对模型性能的影响,这两天正好有时…

【Minecraft】Fabric Mod开发完整流程2 - 创造模式物品栏与第一个方块

创造模式物品栏 添加到当前已有物品栏 再添加自定义的创造模式物品栏之前,请确保你的确有这个需求!否则建议直接添加到当前已有的物品栏内部 创建新文件:com/example/item/ModItemGroup.java package com.example.item;import net.fabricmc.…

web-vue

<html><head><title>永远朋友</title><script src"../js/vue.js"></script></head><body><div id "app"><input type"text" v-model"message">{{ message }}</div&g…

IntelliJ IDEA快捷键大全

文章目录 1、构建/编译2、文本编辑3、光标操作4、文本选择5、代码折叠6、辅助编码7、上下文导航8、查找操作9、符号导航10、代码分析11、运行和调试12、代码重构13、全局 CVS 操作14、差异查看器15、工具窗口 本文参考了 IntelliJ IDEA 的官网&#xff0c;列举了IntelliJ IDEA&…

VM虚拟机搭建详细步骤

一、安装好VMware&#xff0c;双击exe程序&#xff0c;启动软件 二、新建虚拟机 三、选择“典型”&#xff0c;点击“下一步” 四、先择“稍后安装操作系统”&#xff0c;点击“下一步” 五、选择操作系统&#xff0c;以windows server 2008 为例&#xff0c;上方选择“Microso…

KeePass CVE-2023-32784:进程内存转储检测

KeePass CVE-2023-32784&#xff1a;进程内存转储检测 KeePass 是一种流行的开源密码管理器&#xff0c;可以在 Windows、Mac 或 Linux 上运行。该漏洞允许从正在运行的进程的内存中以明文形式提取主密钥。主密钥将允许攻击者访问所有存储的凭据 强烈建议更新到KeePass 2.54以…

LC-环形链表

LC-环形链表 链接&#xff1a;https://leetcode.cn/problems/linked-list-cycle/ 描述&#xff1a;给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 思路&#xff1a;如果一个链表有环&#xff0c;当它进入环之后&#xff0c;就会沿着环一直走&#xff0c;这时…

断路器分合闸速度试验

试验目的 高压断路器的分、 合闸速度是断路器的重要特性参数, 反映出断路器的操动机构 与传动机构在分、 合闸过程中的运动特征。 断路器分、 合闸速度超出或者低于规定值 均会影响断路器的运行状态和使用寿命。 断路器合闸速度不足, 将会引起触头合闸振颤, 预击穿时间过长。 断…

SCAU操作系统知识点之(十)多处理器、多核和实时调度

1、多处理器系统中&#xff0c;采用简单的FCFS或“静态优先级FCFS”调度算法就足够了 2、实时任务分类&#xff1a;硬、软&#xff0c;周期性、非周期性 _例&#xff1a;__A_____优先权是在创建进程时确定&#xff0c;之后不再改变。 A. 静态 B. 短作业 C. 先来先服务 D. 时间片…

未来混合动力汽车的发展:技术探索与前景展望

随着环境保护意识的增强和对能源消耗的关注&#xff0c;混合动力汽车成为了汽车行业的研发热点。混合动力汽车融合了传统燃油动力和电力动力系统&#xff0c;通过优化能源利用效率&#xff0c;既降低了燃油消耗和排放&#xff0c;又提供了更长的续航里程。本文将探讨混合动力汽…