Spark-核心常见面试题集锦(RDD、shuffle类型、数据倾斜优化、小文件问题、性能调优、streaming流程、checkpoint机制)

news2024/11/15 17:31:21

1 Spark的任务执行流程

第一种standalone模式

在这里插入图片描述

  1. 整体:driver中有sparkcontext,RDD DAG和DAGScheduler和taskscheduler,master是资源管理,worker中executor,executor中有多个task

  2. 构建一个application环境,driver创建sparkcontext

  3. sparkcontext中的taskcheduler连接到集群管理器master申请资源,此时worker也会向master定期发送心跳信息以及executor的状态

  4. master根据sparkcontext的资源申请和worker的心跳信息决定在哪一个worker分配资源,被选中的worker启动standaloneexecutorbackend并向sparkcontext反向注册,这样driver就知道哪些excutor是可以进行服务的

  5. sparkcontext开始执行代码,spark RDD通过transaction操作,形成了RDD血缘关系,构建DAG有向无环图,最后遇到action算子调用,触发job并调度,生成两个调度器DAGschedule和taskscheduler。

  6. DAGschedule负责分解stage,主要将job切分为若干个stage,具体划分:窄依赖RDD会被划分到一个stage中,宽依赖会被划分多个stage,为并为每一个stage组装一批task组成taskset

  • 宽依赖:指的是多个子RDD的分区会依赖同一个父RDD的分区
  • 窄依赖:每一个父RDD的分区最多被一个子RDD的分区使用
  • job,stage,task的关系:一个job含有多个stage,一个stage含有多个task,stage的数量=宽依赖数量+1
  1. 然后将taskset交给taskscheduler,taskscheduler会将taskset封装成tasksetmanager加入到调度队列中,调度过程中schedulerbackend负责提供可用资源,schedulerbackend也会定期询问taskscheduler是否有任务要运行。最后taskscheduler将taskset分配给到worker。

  2. worker中的excutor执行进行反序列化,会将driver发送过来的taskset封装进去一个taskrunner的线程,放到本地线程池,调度我们的作业

  3. 资源注销

第二种yarn cluster模式

  1. yarn集群中,driver是运行在applicationmaster上的,applicationmaster进程同时负责驱动application和从yarn申请资源。
    在这里插入图片描述

  2. client向yarn中提交应用程序,

  3. resourcemanager在某一个nodemanager中启动container,并将applicationmaster分配到该nodemanager上

  4. nodemanager收到resourcemanager分配后,启动application master进行sparkcontext的初始化,这个时候nodemanager相当于driver

  5. applicationmaster向resourcemanager注册,用户可以直接通过applicationmaster查看应用程序的与运行状态,然后它将采用的轮询的方式通过RPC协议为各个任务申请资源,并监控它们的运行状态直到结束

  6. 申请到资源的applicationmaster向nodemanager进行通信,要求nodemanager启动coarsegrainedexecutorbackend并向applicationmaster中sparkcontext注册并申请

  7. applicationmaster中sparkcontext分配task给coarsegrainedexecutorbackend执行

  8. excutor向nodemanager上的applicationmaster注册汇报并完成相应的任务。

  9. applicationmaster和resourcemanager申请注销并关闭自己

作业调度

  1. driver的主要是初始化sparkcontext对象,准备运行所需要的上下文
  2. 一方面和applicationmaster的RPC连接,通过applicationmaster申请资源
  3. 另一方面根据业务逻辑调度任务,将任务下放到空闲的excutor上

第三种 yarn-client和yarn-cluster的区别

  1. yarn-cluster模式下,driver在applicationmaster中负责资源申请以及监督作业。用户提交作业,可以关闭client,作业会继续在yarn运行,但是不适合运行交互类型的作业
  2. yarn-client模式下,applicationmaster仅仅向yarn请求executor,client会和container通信,yarn不能离开

2 spark的特点

  • spark实现了DAG执行引擎,可以基于内存处理数据流。与MR基于磁盘比快了很多
  • 计算的中间结果是存在于内存中的,减少低效磁盘io。和hadoop中间写入磁盘比快
  • jvm优化,MR是一个task启动一个jvm,spark是一个executor启动jvm,task是在线程复用的
  • 基于DAG高效的调度算法
  • 缓存方式:cache
  1. 易用
  • shell/python/scala/java都可以使用
  1. 通用
  • sparksql,spark streaming,spark core等,还有spark mllib和图计算
  1. 兼容性
  • 和yarn和mesos作为资源管理和调度,和其他开源产品融合使用

3 spark源码的任务调度

  1. DAG产生:叫做有向无环图,原始的RDD通过一系列的转换就形成了DAG,根据依赖关系将DAG划分为不同的stage,对于宽依赖来说,由于存在shuffle,因此只能在parent RDD处理后完成。
  • 宽依赖:指的是多个子RDD的分区会依赖同一个父RDD的分区
  • 窄依赖:每一个父RDD的分区最多被一个子RDD的分区使用

4 spark的yarn-cluster涉及的参数有哪些

在这里插入图片描述

5 spark处理数据的具体流程/如何从kafka读数据/双流join/怎么保证数据不丢失/数据持久化/exactly once

spark streaming 处理数据流程

待补充

6 spark的join分类

  1. broadcast hash join:使用小表很小的
  • broadcast阶段:将小表广播分发到大表的分区,先给到driver,driver再统一给到executor
  • hash join阶段:大表的分区在内存中和executor上的小表join
  1. shuffle hash join:按照相同join key进行分区,将大表划分为小表的join,再利用集群并行化处理。
  • shuffle阶段:分别将两张表按照join key进行分区,相同的分布到同一个节点。默认分区200
  • hash join:在分区节点执行单机hash join
  1. sort-merge join:适用于两个表都特别大
  • shuffle阶段:按照相同join key进行分区,散布到集群,利用分布式处理
  • sort阶段:对单个分区节点的两张表,进行排序
  • merge阶段:对排好序的两张分区表进行join操作

7 map join 原理

  1. 将小份RDD直接通过collect算子拉取到driver加载到内存中,对其创建一个broadcast变量。

  2. 对另一个RDD执行map类算子,并从broadcast变量获取较少的RDD全量数据,与当前RDDkey值相同的话,就直接进行join

  3. 常用场景:

  • 小表建立索引,然后建立map表,用rdd.collectAsMap算子,但是value不可重复,需要另算。

  • 还得注意driver的节点内存充足。可以在任务提交的时候参数写大一些。

  • executor需要处理广播过来的数据,因此也需要确保executor内存足够。

8 什么时候会产生spark shuffle?

  1. repartition类的操作:repartition、coalesce、repartitionAndSortWithinPartitions(分组然后排序)
  2. bykey:reducebykey、groupbykey、sortbykey
  3. join:join、cogroup(计算区内元素个数)

9 spark shuffle以及优缺点

  1. hash shuffle
  • 取余操作
  1. 优化过后的hashshuffle
  • 合并机制是使用复用butter,相同的key值的放在同一个butter缓冲中,然后写入封装成core为单位的本地磁盘文件,对应参数:spark.shuffle.consolidateFiles
  • 优点:和sort的优化比是省略不必要的排序开销以及排序内存开销
  • 缺点:写到磁盘本地文件的话,会带来一定的磁盘以及文件系统的开销,以及和内存交互,对内存也是有压力的。
  1. sort shuffle
  • 数据写入内存缓冲,并对key值进行排序,内存满了后分批溢写入磁盘
    • 合并操作,最后的task合并刚刚的磁盘文件并写道最终文件磁盘,并创建单独的索引文件
  1. bypass sortshuffle
  • 条件:小于默认分区200+不是聚合类的算子
  • 优化过后的hashshuffle+最终的合并
  • 合并:最后的task合并刚刚的磁盘文件并写道最终文件磁盘,并创建单独的索引文件。
  1. tungsten sort shuffle
  • 条件:没有聚合操作+PartitionId<2的24次方+Serializer序列化器支持relocation序列化值重定向
  • 排序+内存溢写磁盘
  • 优点:使用UnSafe API不用进行序列化以及反序列化
  • 缺点:map端以及记录本身的排序耗性能

10 spark数据倾斜

  1. 表现:不同key值数量导致不同task的数据量处理问题,有的task显示很慢或者直接表现为内存溢出OOM
  2. 避免shuffle过程:map join的办法,使join在map段解决
  3. 增大key值粒度
  4. 过滤倾斜的key值或者单独处理倾斜的key值后续放回去
  5. 提高reduce的并行度,增加reducetask的数量,使每一个task处理的数据量少了,shuffle的算子中可以传入一个并行度的设置参数,例如reducebykey(500)
  • 并行度:各个stage的task数量,可以说是等于RDD的一个分区
  1. 使用随机key实现双重聚合
  • 给每个key值添加上随机数前缀,进行第一次聚合
  • 去掉key值得随机数前缀再次聚合
  • 适用:join的shuffle操作

11 spark的stage的划分

  1. stage的产生:job按照RDD之间的依赖关系分为宽依赖,由DAGscheduler划分为一个stage
  2. result stage:使action操作后得到的计算结果
  3. shuffle map stage:在shuffle之前出现

12 spark的内存模型

  1. 堆内内存:默认堆内内存
  • executor内存:用户存放shuffle,sort等计算过程中的中间临时文件
  • storage内存:存放spark的cache的数据,例如RDD的缓存,broadcast的数据
  • 用户内存:主要存储RDD转换操作所需要的数据,RDD依赖
  • 预留内存:系统预留内存,用来存储spark的内部对象
  1. 堆外内存:
  • 表示分配在java虚拟机的堆以外的内存,表示spark是可以直接操作操作系统的内存的,减少了不必要的开销体现在可以精确的申请和释放,而不是jvm内存清理的不明确时间点。

13 spark的RDD、DataFrame、DateSet和DateStream区别

  1. RDD:分布式弹性数据集
  2. DateFrame:
  • 与RDD的区别是,前者带有schema元信息,即二位数据集的每一列都带有名称以及类型。
  • 允许不用必须去注册临时表或者生成sql表达式
  • 拥有内存管理[二进制存储]和查询优化器
  • 创建:使用toDF/createdataframe创建DateFrame
  1. DataSet:
  • 是DateFrame的拓展,由更好的lambda函数能力以及sparksql的优化执行引擎
  • 比DateFrame比,是可以知道字段以及字段类型的
  • 类型和比DateFrame比是安全的,是强类型Dataset[Car]
  1. spark SQL
  • SQL查询和spark程序无缝连接使用
  • sql进行语法解释器、分析器以及优化器都可以定义

14 spark的容错机制

  1. spark是记录更新的方式,即血缘容错

  2. 血缘容错记录了较粗粒度的操作:例如filter、map、join,当rdd的部分分区数据丢失的时候,可以通过血缘来重新运算以及恢复丢失的分区。

  3. 如果是窄依赖:只要把丢失的父依赖的分区重新计算即可;但是是宽依赖:需要恢复父依赖的分区并且重新计算,开销会大。

  4. 因此有了checkpoint机制:将内存的变化持久化到磁盘持久存储,可以把RDD保存在hdfs的namenode中元数据edit log中并刷新到磁盘fsimage,斩断所需的依赖链,如果没有才往前追溯。

  5. 一般可以通过冗余数据和日志记录更新操作。

  6. cache机制:将RDD的结果写入内存,运行后缓存自动消失

  7. persist机制:将结果写入磁盘

15 sparkbatchsize中小文件问题

  1. 窄依赖计算结果会出现大量小文件,因此采用coalese方法和repartition方法最后返回一个特定分区的RDD。
  2. 降低spark的并行度,生成的文件就会少一些
  3. 新增一个任务专门合并小文件
  • 将原来任务写道一个临时分区,在其一个并行度为1的文件
  • 要用group by的原因是利用宽依赖形成一个分区
insert overwrite 目标表 select * from 临时分区 group by *

16 spark参数(性能)调优

  1. 常规性能调优:在写submit提交的时候
  • 设置executor的个数:50~100
  • 配置driver的内存(1-5G)和executor的内存(6-10)
  • 配置executor的cpu core的数量:3核
  1. RDD优化
  • 减少RDD的重复使用:例如使用完全多次窄依赖后再划分宽依赖

  • RDD持久化:

    • 当多次对同一个RDD执行算子操作的时候,需要对RDD之前的父RDD重新计算一次,因此会对多次使用的RDD进行持久化,存入内存或者磁盘中(采用序列化方式减少空间),下次计算直接取数据
  • RDD尽早的filter操作:尽早的使用filter算子过滤掉不需要的数据,减少对内存的占用

  1. 并行度调节
  • spark官方推荐,task的数量应该设置为spark作业总CPU数量的2~3倍。一般没有将task的个数和cpu核数一样是因为有的task执行的快,就会出现cpu的空闲情况
  1. 调节本地化等待时常
  • 适当调节本地化等级,调长时间的目的是希望task能够运行在它要计算数据的节点上,减少数据的网络传输。
  1. 算子调优
  • 使用mappartition代替map算子,优势是是对每一个分区进行操作,而不是对每条数据进行操作,function并且一次接收所有partition的数据,只执行一次,但是要防止mappartition内存溢出
  • foreachpartition代替foreach优化数据库操作,也是对RDD的每个分区进行操作,只需要和分区的数据建立数据库连接而不是和每条数据
  • filter和coalesce的配合使用:filter之后每个数据量不同程度的变少了,后续的task计算资源可能浪费,因此进行重新分区合并或者拆分分区(确保个分区均衡),使用coalesce算子
  • repartition解决sparkSQL的低并行度问题:前面的并行度调节对sparksql不生效,因此使用repartition重新分区为多个partition提高并行度
  • reducebykey预聚合替代其他聚合:reduceby的特点是会在map端进行预聚合,替代例如groupbykey
  1. shuffle优化
  • 调节map/reduce端的缓冲区大小,以防溢写到磁盘,增加磁盘io
  • 调节reduce端拉取数据重试次数以及重试后等待间隙:增加重试次数防止jvm的full gc或者网络不稳定的情况,增加等待时间保证shuffle的平稳,省的重启
  1. jvm调优
  • 堆内内存:storage内存主要缓存RDD数据和broadcast数据,降低storage中的内存比例,方便executor内存避免不必要的频繁的full gc
  • executor内存主要缓存shuffle的中间数据,不用考虑,如果shuffle的过程过大,会自动占用storage的内存区域
  • 堆外内存:提高对外内存的大小,可以从300调到1G以上,在submit的时候提交

17 完整介绍一下RDD

  1. 含义:弹性分布式数据集
  2. 特点:
  • RDD间存在依赖关系,宽依赖窄依赖
  • 分区:是RDD的基本组成单位,切分成partition
  • 底层存储:每个RDD的数据都以block的形式存储与多台机器上,executor会存储启动一个blockmanagerslave并管理部分block,block而元数据是放在driver的blockmanagermaster保存。blockmanagerslave生成之后是向blockmanagermaster注册该block,blockmanagermaster是负责管理block与RDD的关系,如果RDD不需要这个block,则由blockmanagermaster发送指令删除对应的block。

在这里插入图片描述

18 广播变量

  1. 条件:当任务跨多个stage并且需要同样的数据+以反序列化的形式缓存数据时候
  2. 特征:会在每一个worker节点保留一份副本,以供task使用
  3. 步骤:把普通变量转换成广播变量
  4. 原理:
  • 在driver的sparcontext创建后,会分成多个数据块,保存到driver的blockmanager中
  • 只有executor需要广播变量的时候才会向driver获取,只要有一个worker的executor获取到了某一个block,其他的executor不需要获取了,其他executor向这个获取到的executor获取

19 sparksql的自定义函数

  1. UDF:基本自定义函数,to_date,to_char
  2. UDAF:多成一,用户自定义聚合函数,groupby
  3. UDTF:一对多,用户自定义生成函数,flatmap
  4. 实现
  • 将代码打包成udf.jar,放在hadoop/lib下
  • 第一种:启动spark-sql是通过–jars指定
  • 第二种:启动sparksql后add jar
  • 第三种:使用thrift jdbc使用udf

20 hashpartition和rangepartition

  1. spark分区器
  • hashpartition:对于给出的key值取余
  • rangepartition:抽样分区

21 算子区别:map和flatmap/cache和persist

  1. map函数:输入后返回的是一个对象
  2. flatmap是操作的:先输入后返回对象,再将所有的对象合并为一个对象
  3. cache调用了persist,persist比cache可以设置各种缓存级别,cache默认缓存级别是momery_only

在这里插入图片描述

22 spark的block管理

  1. 内容:RDDblock,shuffleblock,taskresultid
  2. 实现类:memorystore,blockmanager

23 streaming连接kafka的方式/streaming怎么保证数据不丢失

  1. Receiver
  • Receiver-based

    • 使用 Kafka 高级消费者 API 来实现 Receiver
    • 从 Kafka topic分区接收的数据存储在 Spark executors
    • spark开启WAL 才能保证spark中 exactly-one 的处理,但是两者的exactly-one 是需要direct的api来写
    • 多个Dstream实现多个Receiver并行
  • direct

    • 使用简单api就可以,需要自己管kafka的offset

24 streaming的流程

  1. 先成batch数据,给到StreamingContext,然后封装RDD操作,然后再给到Dstream进行自己的算子操作

25 持久化

使用checkpoint机制

启动:创建streamingContext,然后调用start()方法,当Driver挂掉的时候,再从checkpoint中恢复一个streamingcontext

26 streaming的算子

在这里插入图片描述

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

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

相关文章

在线查看EventBus源代码

github&#xff1a;/src/org/greenrobot/eventbus/ 例如&#xff1a;EventBus.java

【LeetCode】HOT 100(15)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

024.【链表算法】

1. 创建单向链表 例如&#xff0c;有“学生”这样一个链表&#xff0c;链表中需要包括学生的姓名、性别、学号等一些基本信息。创建这样的一个链表&#xff0c;链表里面包括多个学生的信息。 可以看出&#xff0c;“学生一”的尾结点“next”指向了下一个“学生二”的头结点学…

【并发编程】创建线程的三种方法

源码 Runnable 函数式接口 package java.lang; FunctionalInterface public interface Runnable { public abstract void run(); }Thread 就是一个典型的静态代理模式 public class Thread implements Runnable {private Runnable target;public Thread() { in…

接口测试用例如何编写?

目录 前言&#xff1a; 在开始编写接口测试用例之前&#xff0c;需要注意几件事&#xff1a; 编写接口测试用例的步骤包括&#xff1a; 常遇到的问题包括&#xff1a; 前言&#xff1a; 编写接口测试用例是接口测试的重要一环。好的接口测试用例能够充分覆盖接口各种情况&…

jmeter负载测试中如何找到最大并发用户数(实战)

目录 前言 负载测试概念 脚本总体设计&#xff1a; 场景介绍&#xff1a; 前言 在进行负载测试时&#xff0c;找到最大并发用户数是非常重要的&#xff0c;这个值将会告诉您系统可以承受多大的并发请求。 在性能测试中&#xff0c;当我们接到项目任务时&#xff0c;很多时…

热烈Matplotlib子图不不会画来看看-分图绘制(怒肝万字)

&#x1f468;&#x1f3fb;‍&#x1f393;博主介绍&#xff1a;大家好&#xff0c;我是大锤爱编程的博客_CSDN博客-大数据,Go,数据分析领域博主&#xff0c;有五年的数据开开发&#xff0c;有着丰富的数仓搭建、数据分析经验。我会在我的系列文章里面分享我学到的知识&#x…

计算机服务器中了encrypted勒索病毒怎么办,什么是encrypted勒索病毒

Encrypted勒索病毒是一种非常危险的电脑病毒&#xff0c;该病毒通过加密计算机中的文件和数据&#xff0c;使其无法访问和使用计算机&#xff0c;并要求受害者支付一定的赎金以获得解密密钥。 Encrypted勒索病毒是一种常见的勒索软件&#xff0c;由于它使用先进的加密技术&…

ansible的部署和模块

一、 ansible 的概述 1、ansible简介 Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。 它用Python写成&#xff0c;类似于saltstack和Puppet&#xff0c;但是有一个不同和优点是我们不需要在节点中安装任何客户端。 它使用SSH来和节点进行通信。Ansible基于 …

【OpenCV DNN】Flask 视频监控目标检测教程 09

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 09 3.9 OpenCVFlask多线程处理实时监控人脸识别新建 Flask 项目 cvFlask09Python程序文件视频流的网页模板程序运行 本系列从零开始&#xff0c;详细讲解使用 Flask 框架…

Windows版Redis安装

最近电脑重装了系统&#xff0c;很多常用的软件、应用都没有了&#xff0c;所以需要重新装&#xff0c;所以想借此机会把一些安装比较复杂的应用的安装过程&#xff0c;重新记录一下&#xff0c;方便后续&#xff0c; 安装 Redis默认只有Linux的版本&#xff0c;但是微软为了更…

Python面向对象编程1-面向过程的简单纸牌游戏程序 项目1.4 打印牌的点数和花色

总项目目标&#xff1a;用面向过程思想设计一个简单的纸牌游戏程序&#xff0c;称为"Higher or Lower"&#xff08;高还是低&#xff09;。游戏中&#xff0c;玩家需要猜测接下来的一张牌是比当前牌高还是低。根据猜测的准确性&#xff0c;玩家可以得到或失去相应的积…

容器(第九篇)ansible-playbook

Ansible 的脚本 --- playbook 剧本 playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0c;即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 &#xff08;2&#xff09;Variables&#xff1a;变量 &#xff08;3&…

pytorch搭建LeNet网络实现图像分类器

pytorch搭建LeNet网络实现图像分类器 一、定义LeNet网络模型1&#xff0c;卷积 Conv2d2&#xff0c;池化 MaxPool2d3&#xff0c;Tensor的展平&#xff1a;view()4&#xff0c;全连接 Linear5&#xff0c;代码&#xff1a;定义 LeNet 网络模型 二、训练并保存网络参数1&#xf…

GAMES101笔记 Lecture03 Transformation

目录 Transoformation(变换)Why stuty transformation(为什么要学习变换呢?)2D transformations(2D变换)Scale transformation(缩放变换)Reflection Matrix(反射矩阵)Shear Matrix(切变矩阵) Rotate transformation(旋转变换)Linear Transforms Matrices(线性变换 矩阵) Hom…

Java泛型详解,史上最全图文详解

泛型在java中有很重要的地位&#xff0c;无论是开源框架还是JDK源码都能看到它。 毫不夸张的说&#xff0c;泛型是通用设计上必不可少的元素&#xff0c;所以真正理解与正确使用泛型&#xff0c;是一门必修课。 一&#xff1a;泛型本质 Java 泛型&#xff08;generics&#…

C#程序设计——Windows应用程序开发,1、初步掌握Windows应用程序的设计方法。2、掌握常用窗体控件的使用方法。

Windows应用程序开发 一、实验目的 初步掌握Windows应用程序的设计方法。掌握常用窗体控件的使用方法。 二、实验内容 1、设计一个Windows应用程序&#xff0c;创建一个用于添加学生个人基本信息的窗体&#xff0c;窗体下方法同时滚动信息“天行健&#xf…

前端学习-html基础

html学习与总结 一、基础认知 1.1.1 认识网页&#xff08;了解&#xff09; ➢ 问题1&#xff1a;网页由哪些部分组成&#xff1f; ✓ 文字、图片、音频、视频、超链接 ➢ 问题2&#xff1a;我们看到的网页背后本质是什么&#xff1f; ✓ 前端程序员写的代码 ➢ 问题3&a…

设计模式的几大原则

设计模式原则 前言一.单一职责原则1.1 定义1.2 例子1.3 总结 二.里氏替换原则2.1 定义1.2 例子1.3 总结 三.依赖倒置原则3.1 定义3.2例子3.3总结 四.接口隔离原则4.1 定义4.2 例子4.3 总结五.迪米特法则5.1 定义5.2 例子5.3 总结 六.开闭原则6.1 定义6.2 例子6.3 结论 前言 设…

MongoDB复制(副本)集实战及其原理分析-04

MongoDB复制集 复制集架构 在生产环境中&#xff0c;不建议使用单机版的MongoDB服务器。 原因如下&#xff1a; 单机版的MongoDB无法保证可靠性&#xff0c;一旦进程发生故障或是服务器宕机&#xff0c;业务 将直接不可用。 一旦服务器上的磁盘损坏&#xff0c;数据会直接丢…