读构建可扩展分布式系统:方法与实践15可扩展系统的基本要素

news2024/10/1 17:30:07

1. 可扩展系统的基本要素

1.1. 分布式系统在本质上就是复杂的,你必须考虑多种故障模式,并设计应对所有可能发生的情况的处理方式

1.2. 大规模应用程序需要协调大量的硬件和软件组件,共同实现低延迟和高吞吐量的能力

1.3. 面临的挑战是将所有活动部件组合成一个应用程序来运行,使其既能满足需求又不会耗费过多成本

  • 1.3.1. 新的编程抽象、平台模型和硬件让你更容易构建具有更高的性能、更好的可扩展性和更大的弹性的更复杂的系统

2. 自动化

2.1. 在构建大型系统时,工程师是相当昂贵但必不可少的资源

2.2. 需要部署频繁的更改来改善客户体验,并确保可靠和可扩展的操作

2.3. 在不停机的情况下每天有效地将数百个更改推送到已部署系统的能力是系统规模化的关键所在

2.4. 促进自动化的一组工具和实践体现在DevOps文化中

  • 2.4.1. DevOps包含一组面向从开发到部署各个级别过程的自动化实践和工具

  • 2.4.2. DevOps的核心是持续交付(CD)实践,由用于代码配置管理、自动化测试、部署和监控的复杂工具链提供支持

2.5. DevOps实践对于成功的可扩展系统至关重要

  • 2.5.1. 团队有责任设计、开发和运营他们的微服务,微服务通过良好定义的接口与系统的其余部分进行交互

  • 2.5.2. 借助自动化工具链,可以在微服务中独立部署本地更改和新功能,同时不干扰系统操作

  • 2.5.3. 自动化减少了协调开销,提高了生产力,缩短了发布周期

  • 2.5.4. 意味着你的工程投资将获得更大的回报

3. 可观测性

3.1. 你无法管理你无法衡量的东西

3.2. 由于有大量移动部件,所有部件都在可变负载条件下运行,容易出现不可预测的错误

3.3. 需要借助测量系统提供的健康状况和行为来观测系统状态

  • 3.3.1. 提供基础设施不断生成的细粒度指标和日志数据来捕获系统当前状态

  • 3.3.2. 分析聚合实时指标并采取行动,对指示实际或未决故障的警报做出反应

3.4. 可观测性的第一个基本要素是具有一个仪表化系统,它不断以指标和日志条目的形式发出系统遥测数据

  • 3.4.1. 可以来自操作系统、你在应用程序中使用的基础平台(例如,消息传递、数据库)以及你部署的应用程序代码

  • 3.4.2. 指标表示资源利用率以及系统各部分提供的延迟、响应时间和吞吐量

3.5. 代码检测是强制性的,你可以使用开源框架或专有解决方案

  • 3.5.1. 指标和日志条目形成了基于时间序列的连续的数据流,表征了你的应用程序随时间的行为

3.6. 捕获原始指标数据是可观测性系统推断并感知态势的先决条件

  • 3.6.1. 需要快速处理数据流,它才可能让系统及时采取行动

  • 3.6.2. 包括持续监控当前状态、探索历史数据以了解或诊断一些意外的系统行为,以及在超过阈值或发生故障时发送实时警报

3.7. Prometheus、Grafana和Graphite是目前广泛使用的技术,它们提供了适用于可观测性栈各个部分的开箱即用的解决方案

3.8. 可观测性是可扩展分布式系统的必要组成部分

4. 部署平台

4.1. 可扩展系统需要大规模、有弹性且可靠的计算和数据平台

4.2. 可以使用专为操作设计的脚本语言自动调用配置

  • 4.2.1. 基础架构即代码(IaC),也是DevOps的基本要素

4.3. 传统上,虚拟机是应用程序的部署单元

  • 4.3.1. 容器镜像支持将应用程序代码和依赖项打包到单个可部署单元中

  • 4.3.2. 与虚拟机相比,容器消耗的资源更少,因此可以在单个虚拟机上打包多个容器,更有效地利用硬件资源

4.4. 容器通常与集群管理平台(如Kubernetes或Apache Mesos)一起使用

  • 4.4.1. 容器编排平台为你提供API来控制容器的执行方式、时间和位置

  • 4.4.2. 平台允许你自动部署容器并支持使用自动缩放的不同系统负载,简化集群中在多个节点部署多个容器的管理工作

5. 数据湖

5.1. 随着时间的推移,你的系统将生成许多PB级或更多的数据

  • 5.1.1. 数据中的大部分很少被你的用户访问

5.2. 管理、组织和存储历史数据存储库是数据仓库、大数据和数据湖的领域范围所在

  • 5.2.1. 本质是以一种可以检索、查询和分析的形式来存储历史数据

5.3. 数据湖的特征是以异构格式存储和编目数据,从原生blob到JSON再到关系数据库提取数据

  • 5.3.1. 利用Apache Hadoop、Amazon S3或Microsoft Azure Data Lake等低成本对象存储

  • 5.3.2. 灵活的查询引擎支持数据的分析和转换

  • 5.3.3. 可以使用不同的存储类别,以本质上更长的检索时间换取更低的成本,继而优化成本

6. 并发系统

6.1. 分布式系统包括多个独立的代码片段,它们在不同位置的多个处理节点上并行或并发地执行

6.2. 任何分布式系统都是并发系统,即使每个节点一次只处理一个事件也是如此

  • 6.2.1. 在分布式系统中协调节点充满了风险

6.3. 编写软件来并发地执行多个操作,有助于优化单个节点上的处理能力和资源利用率,提高本地和系统范围的处理能力

6.4. 在过去的计算时代,每个CPU在任何时刻都只能执行一条机器指令

  • 6.4.1. 程序试图读取文件或在网络上发送消息时,它必须与CPU外围的硬件子系统(磁盘、网卡)进行交互

  • 6.4.2. 从硬盘读取数据大约需要10ms。在此期间,程序必须等待可供处理的数据

  • 6.4.3. Linux等操作系统可以在单个CPU上运行多个程序的方式

  • 6.4.4. 将软件明确地构造成具有多个可以并行执行的活动,在其他任务等待I/O时,操作系统可以安排有工作要做的任务

6.5. 使用多核芯片,可以在每个内核上并发执行具有多个并行活动的软件系统,最多可达到可用内核的数量

  • 6.5.1. 每种编程语言都有自己的线程机制

  • 6.5.2. 所有并发机制的底层语义都是相似的

  • 6.5.3. 主流使用的主要线程模型只有几个

6.6. 在过去50年里,并发模型一直是计算机科学中研究和探索较多的主题

  • 6.6.1. CSP(通信顺序进程)模型构成了Go并发特性的基础

    • 6.6.1.1. 在Go中,并发的单位是goroutine,goroutine使用无缓冲或缓冲通道发送消息来进行通信
  • 6.6.2. Erlang实现了并发的actor模型

    • 6.6.2.1. actor是没有共享状态的轻量级进程,通过向其他actor发送异步消息来进行通信

    • 6.6.2.2. actor使用邮箱或队列来缓冲消息,可以使用模式匹配来选择要处理的消息

  • 6.6.3. Node.js避开多线程,利用由事件循环管理的单线程非阻塞模型

    • 6.6.3.1. 该模型适用于频繁执行I/O请求的代码

    • 6.6.3.2. 如果你的代码需要执行CPU密集型操作,例如对大型列表进行排序,那么你只有一个线程

      6.6.3.2.1. 这将阻止其他请求,直到排序完成

      6.6.3.2.2. 这并非一种理想的情况

6.7. 在可扩展分布式系统的世界中,并发是无处不在的

6.8. 无论你使用的是C/C++中的pthreads库,还是受CSP启发的经典Go并发模型,需要避免的问题都是相同的

7. 线程

7.1. 默认情况下,每个软件进程都有一个执行线程,即操作系统在安排进程执行时所管理的线程

7.2. 线程本质上是我们构建可扩展分布式系统时用于数据处理和数据库平台的组件

7.3. 在许多情况下,你可能不会显式编写多线程代码

7.4. 许多平台还通过配置参数来调整其并发能力,这意味着要调整系统性能,你需要了解更改各种线程和线程池设置的影响

7.5. 线程执行顺序

  • 7.5.1. 从程序开发者的角度来看,执行顺序是不确定的(nondeterministic)

  • 7.5.2. 不确定性(nondeterminism)这个概念是理解多线程代码的基础

  • 7.5.3. 一旦调度程序允许一个线程在CPU上执行一段时间,它就可以在指定的时间段后中断该线程,并安排另一个线程运行

    • 7.5.3.1. 中断称为抢占
  • 7.5.4. 调度程序根据调度算法决定何时运行哪个线程,线程是独立且异步地运行,直到完成

  • 7.5.5. 无论线程执行的顺序如何(你无法控制)​,你的代码都应该产生正确的结果

7.6. 线程的状态

  • 7.6.1. 多线程系统有一个系统调度程序来决定何时运行哪些线程

    • 7.6.1.1. 执行最高优先级的线程

7.7. 线程池

  • 7.7.1. 许多多线程系统需要创建和管理一组执行相似任务的线程

  • 7.7.2. 线程集合为线程池

    • 7.7.2.1. 线程池包含多个工作线程,它们通常执行相似的任务,并以一个集合进行管理
  • 7.7.3. 如果系统以不受约束的方式创建线程,最终会耗尽内存,导致系统崩溃

7.8. 同步屏障

  • 7.8.1. CountDownLatch是一个简单的同步屏障器

    • 7.8.1.1. 它是一次性工具,初始化值无法重置

8. 线程引入的问题

8.1. 并发编程的基本问题是如何协调多个线程的执行,无论它们以何种顺序执行,都会产生正确的结果

8.2. 鉴于线程可以不确定地被启动和抢占,任何中等复杂的程序本质上都有无数种执行顺序

  • 8.2.1. 这些系统是不容易测试的

8.3. 所有并发程序都需要避免两个基本问题,即竞态条件和死锁

8.4. 竞态条件

  • 8.4.1. 如果每个线程都只做自己的事情并且完全独立,执行顺序就不是问题了

  • 8.4.2. 完全独立的线程并不是大多数多线程系统的行为方式

  • 8.4.3. 线程可以使用共享的数据结构来协调它们的工作并在线程之间传递状态

  • 8.4.4. 竞态条件是隐秘的、狡猾的错误,因为它们通常很少见,而且很难被发现,大多数时候结果都是正确的

    • 8.4.4.1. 相同的代码,偶尔会出现不同的结果

    • 8.4.4.2. 关键是识别和保护临界区

    • 8.4.4.3. 临界区是更新共享数据结构的一段代码,如果它被多个线程访问,则必须以原子方式执行

    • 8.4.4.4. 你应该使临界区代码尽可能少,将序列化代码减到最少

8.5. 死锁

  • 8.5.1. 如果我们不小心编写过多限制不确定性的代码,则又会导致程序停止运行,并且永远不会继续执行,术语称其为死锁

  • 8.5.2. 当两个或多个线程永远被阻塞,没有一个可以继续执行时,就会发生死锁

    • 8.5.2.1. 当线程需要独占共享资源集,以不同的顺序获取锁时,就会发生这种情况
  • 8.5.3. 死锁,也称为致命拥抱,会导致程序停止

  • 8.5.4. 可以在软件的阻塞操作上使用超时来实现

    • 8.5.4.1. 在超时到期后,一个线程释放临界区并重试,让其他被阻塞的线程有机会继续执行

    • 8.5.4.2. 阻塞线程会损害性能,设置超时值也不是精确的做法

  • 8.5.5. 对于循环等待死锁,可以在共享资源上施加资源分配协议来解决,这样线程就不会总是以相同的顺序请求资源了

9. 线程间的协调

9.1. 很多时候,我们需要不同角色的线程来协调它们的活动,继而解决问题

9.2. 打印问题就是典型的生产者-消费者的例子

  • 9.2.1. 与一切现实的资源一样,缓冲区的容量也是有限的

  • 9.2.2. 轮询,或忙等待

  • 9.2.3. 更好的解决方案是让生产者和消费者阻塞,直到其期望的操作(分别为put或get)成功

  • 9.2.4. 阻塞的线程不消耗资源,这是一个有效的解决方案

10. 线程安全集合

10.1. java.util包中的集合并不是线程安全的

  • 10.1.1. 为了加快单线程程序的执行速度,该集合不是线程安全的

10.2. 在多线程代码中使用线程安全集合总是更安全

  • 10.2.1. ConcurrentHashMap的迭代器是弱一致性

  • 10.2.2. 如果你需要一个在被多个线程更新时始终反映当前hashmap状态的迭代器,就要付出性能代价,ConcurrentHashMap不是正确的选择

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

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

相关文章

入门Django

Django Django 简介URL组成部分详解第一个Django项目创建一个Django项目运行Django项目项目结构介绍project和app的关系 URL与视图函数的映射URL的两种传参方式在URL中携带参数 path函数url路由模块化url反转 Django 简介 Django 是一个高级的 Python Web 框架,用于…

书生白嫖A100活动之——OpenCompass

内容来源:Tutorial/opencompass/readme.md at camp2 InternLM/Tutorial GitHub 概览 在 OpenCompass 中评估一个模型通常包括以下几个阶段:配置 -> 推理 -> 评估 -> 可视化。 配置:这是整个工作流的起点。您需要配置整个评估过…

HTML中的表单(超详细)

一、表单 1.语法 <!-- action&#xff1a;提交的地方 method&#xff1a;提交的方式&#xff08;get会显示&#xff0c;post不会&#xff09; --> <form action"#" method"get"><p>名字&#xff1a;<input name"name" ty…

【Geoserver使用】SRS处理选项

文章目录 前言一、Geoserver的三种SRS处理二、对Bounding Boxes计算的影响总结 前言 今天来看看Geoserver中发布图层时的坐标参考处理这一项。根据Geoserver官方文档&#xff0c;坐标参考系统 (CRS) 定义了地理参考空间数据与地球表面实际位置的关系。CRS 是更通用的模型&…

3. 轴指令(omron 机器自动化控制器)——>MC_MoveFeed

机器自动化控制器——第三章 轴指令 8 MC_MoveFeed变量▶输入变量▶输出变量▶输入输出变量 功能说明▶指令详情▶时序图▶重启运动指令▶多重启动运动指令▶异常 示例程序▶参数设定▶动作示例▶梯形图▶结构文本(ST) MC_MoveFeed 指定自外部输入的中断输入发生位置起的移动距…

2024免费录屏软件的宝藏功能与实用技巧

在手机上操作很多时候为了记录方便都直接截图或者录屏&#xff0c;其实电脑也一样。现在面向电脑的录屏工具纷繁复杂&#xff0c;很容易让我们挑花了眼。今天这篇文章我将介绍几款免费的录屏软件为大家提供参考。 1.福昕录屏大师 链接达达&#xff1a;www.foxitsoftware.cn/R…

深入探索 RUM 与全链路追踪:优化数字体验的利器

作者&#xff1a;梅光辉&#xff08;重彦&#xff09; 背景介绍 随着可观测技术的持续演进&#xff0c;多数企业已广泛采用 APM、Tracing 及 Logging 解决方案&#xff0c;以此强化业务监控能力&#xff0c;尤其在互联网行业&#xff0c;产品的体验直接关系着用户的口碑&…

使用Crawler实例进行网页内容抓取

网页内容抓取的背景 随着互联网的快速发展&#xff0c;网页上的信息量日益庞大。如何从海量的网页中快速、准确地抓取所需信息&#xff0c;成为了一个技术挑战。网页内容抓取技术通过自动化的方式&#xff0c;模拟用户浏览网页的过程&#xff0c;获取网页上的文本、图片、链接…

mybatisplus介绍以及使用(上)

目录 一、概念 1、什么是mybatisplus 2、为什么要使用mybatisplus 二、mybatisplus的使用 1、安装 2、常用注解 3、条件构造器 一、概念 1、什么是mybatisplus MyBatis-Plus&#xff08;简称MP&#xff09;是一个基于MyBatis的增强框架&#xff0c;旨在简化开发、提高…

学习C语言(20)

在这段没有更新的时间作者大一开学了&#xff0c;军训期间一直比较忙没时间学习&#xff0c;9月23号结束了为期十四天的军训&#xff0c;今天开始重新更学习C语言的博客 整理今天的学习内容 1.浮点数在内存中的储存 浮点数包括float&#xff0c;double&#xff0c;long doub…

vue实现左侧数据拖拽到右侧区域,且左侧数据保留且左侧数据不能互相拖拽改变顺序

一、案例效果 二、案例代码 封装左侧抽屉 DrawerSearch.vue <template><div><mtd-form :model"formDrawerSearch" ref"formCustom" inline><mtd-form-item><mtd-inputtype"text"v-model"formDrawerSearch.hos…

美团一面:给定两棵二叉树 `A` 和 `B`,判断 `B` 是否是 `A` 的子结构?

目录标题 问题描述思路分析代码解释详细步骤复杂度分析 问题描述 给定两棵二叉树 A 和 B&#xff0c;判断 B 是否是 A 的子结构。所谓子结构是指 B 中任意节点在 A 中存在相同的结构和节点值。 例子1&#xff1a; 输入&#xff1a;tree1 [1,7,5], tree2 [6,1] 输出&#…

LeaferJS 动画、状态、过渡、游戏框架

LeaferJS 现阶段依然专注于绘图、交互和图形编辑场景。我们引入游戏场景&#xff0c;只是希望让 LeaferJS 被更多有需要的人看到&#xff0c;以充分发挥它的价值 LeaferJS 为你带来了全新的游戏、动画、状态和过渡功能&#xff0c;助你实现那些年少时的游戏梦想。我们引入了丰富…

NVIDIA TAO 工具套件5.3.0学习介绍及操作-01

什么是 NVIDIA TAO 工具套件&#xff1f; NVIDIA TAO 工具套件基于 TensorFlow 和 PyTorch 构建&#xff0c;是 NVIDIA TAO 框架的低代码版本&#xff0c;通过抽象出 AI/深度学习框架的复杂性来加速模型训练过程。TAO 工具套件让您利用迁移学习的强大功能和自己的数据对预训练 …

Remotion:使用前端技术开发视频

前言 最近做文章突然想到很多文章其实也可以用视频的方式来展现&#xff0c;以现在短视频的火爆程度&#xff0c;肯定能让更多的人看到。 恰巧最近看了很多关于动画的前端 js 库&#xff0c;那如果将这些动画帧连续起来&#xff0c;岂不是就成了一个视频吗&#xff1f; 而且…

集成Elasticsearch到django restful

文章目录 集成ES到django restful服务端项目安装haystack基本使用安装配置索引模型ORM模型中新增discount_json字段方法全文索引字段模板 索引序列化器全文搜索的索引视图路由手动构建es索引 集成ES到django restful服务端项目 如果直接在Django项目直接编写代码作为ElasticSe…

YOLOv5白皮书-第Y2周:训练自己的数据集(云jupyter运行版 )

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](小团体&#xff5e;第八波) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊](K同学啊-CSDN博客)** 目录 前言 一、.xml文件里保存的是什么 二、准备好自己的数据 三、创建split_tr…

spring boot 3 + 虚拟线程 + MDC traceId

虚拟线程&#xff08;Virtual Thread&#xff09;也称协程或纤程&#xff0c;是一种轻量级的线程实现&#xff0c;与传统的线程以及操作系统级别的线程&#xff08;也称为平台线程&#xff09;相比&#xff0c;它的创建开销更小、资源利用率更高&#xff0c;是 Java 并发编程领…

ChatGPT-4模型镜像站对比和【软件开发人员】提示词

AI如今很强大&#xff0c;聊聊天、写论文、搞翻译、写代码、写文案、审合同等等&#xff0c;ChatGPT 真是无所不能~ 作为一款出色的大语言模型&#xff0c;ChatGPT 实现了人类般的对话交流&#xff0c;最主要是能根据上下文进行互动。 接下来&#xff0c;我将介绍 ChatGPT 在…

活动|华院计算参与《数字生态指数2024》报告发布并受邀主题分享

9月20-21日&#xff0c;“第二届数字生态与治理论坛暨数字生态指数2024发布会”在湖北省武汉市举办。华院计算作为研究团队一员受邀出席论坛&#xff0c;并发表“人工智能赋能基层社会治理”主题演讲。 《数字生态指数2024》报告为国家对外积极调整全球数字治理战略定位&#x…