00:00
那么聊完了内存方面的事儿,咱们就得来聊一聊CPU了啊,就线程资源对咱们来讲也是特别的重要,那首先呢。我们分析一下CPU低效的原因,其实就是并行度设的不够好,那首先呢,咱们来了解这么几个概念,第一个叫并行度,所谓的并行度大家可以理解为什么呢?Task的数量,也就是说我整个可以切分成多少个task,那的并行度就应该有多少。那么。这个并行度咱们一般是可以通过参数来指定的啊,通过这两个参数,一个叫这个是RDD使用的,下面这个是Spark circle才生效的,它们两个之间互不影响啊,不同场景使用,那像这个spark.defa paraism。这个是RDD的默认并行度,默认呢是没有设的,那它是怎么来的呢?呃,它是由咱们join reduce by key。
01:00
等等。这种杀手算子。生成结果的分区数来决定,也就是说它自动的啊,默认是自动的啊,你比如说你数据有。三种不同的key,比如说ABC吧,那原来是散的,那么咱们做了一个group by group by,那之后是不是就A在一个分区,B在一个分区,C在一个分区啊,那这个时候呢,这个并行度它就会变成三对吧,它是根据咱们的杀手结果来默认设置,咱们也可以预先自己指定啊,预先指定。那么还有一个就是咱们重点关注的circle里面去指定的啊,Circle必须用这个参数啊,上面这个对它不会生效的,那就是在杀否之后,Reduce阶段默认并行度,它默认呢是200这个参数,就是大家很熟悉的那个参数,200指的就这个时候。他不,他同样的不能够去控制一个RDD的啊,他们两个是没有关联的。
02:01
这是第一个并行度的概念啊,咱们先有个印象,在之后呢,还有一个得知道叫并发度。并发度指的就是咱们。呃,同时可以执行的task数量,这是不是取决于咱们的E,比如说像咱们刚才的参数啊,有三个ex,每一个两个和。对吧,那你想想呃,一个task运行需要占用一个核心。需要需要占用一个V空,那么咱们一共才六个核心对吧,三乘以二嘛,一共才六个核,那么它同一时刻是不是只有六个全部占满了呀。也就是说它的并发度咱们是不是可以理解为六啊,那有的同有的人就有疑问呢?那比如说我默认变行度200,那不是代表我会有200个task吗?那只有六个核心,他会怎么办?呃,他会六个先跑,哪个空出来了,其他等待的task就过去接着跑,相当于是咱们生活中咱们不是有一些厕所吗?比如说一个地方厕所只有三个人,这个时候来了。
03:12
十来个人都急着上厕所,在那排队,那是不是先到的三个是不是先使用啊,他们先进去用啊,那比如说这个人好了出来了,那么下一个人是不是可以继续使用这个坑位啊,啊就是这么一个意思,所以咱们的并发路就可以理解为一共有多少个task同时再跑,或者说呢,咱们整个集群,Spark集群有多少核心可以使用啊,那就是它的并发度。那明白这两个概念之后,咱们就可以来分析CPU为何低效,其实就是这两个东西的区别,第一个并行度较低,也就是咱们那个task总数太太少了。它这个总数少呢,那数据分片就比较大了。
04:01
容易导致CPU线程挂起。什么叫数据分片啊,比如说我的数据的时候一共有100个G,那同样的咱们。并行度是200的话。那一个是不是,呃500兆,那如果我的并行度只有100,那每一个并行度是不是也就是每一个task是不是应该要处理一个G的数据啊,啊,这个这个就是一个task处理多大的数据量,也就是咱们所谓的数据分片呢?啊,那数据分片越大。那就会。占用更多的内存。它可能会出现这么一种情况的,同学们,比如说我这个一共六个G。呃,有两个和。呃,那比如说我们算完之后啊,正常来讲应该是两个可以同时跑的。但是呢,我一个数据分配,也就是说一个task需要占用五个G的内存。
05:05
那你你想想,如果两个task同时跑,是不是得需要十个G啊,那这个内存够吗?那肯定不够,所以这个时候就会造成一个现象,只有一个task在跑,但是呢,核数还有剩,那这种呢,就是CPU低效的原因,没有利用起来。啊,这是这种场景,就是并行度设的太低了,每一个task要需要处理的数据量比较大。啊,导致呢,内存不够,然后CPU在那浪费啊,这是这一种原因,第二种原因就是并行度太过于高,数据太过分散。并行度就touch个数吗?比如说默认是200,假设你设的是2000,一共才100个G,原来是200的话,你可能每一个分片500兆,那现在多少啊,每一个分片才50兆,对内存没有压力对吧?单个task,但是呢。
06:03
T的数量。是不是太多了,比原来多了很多呀,而且咱们task是不是需要调度的呀。那调度也是有开销的呀,也就是说你把一些呃资源浪费在调度上,真正用来执行的时候,时间反而少了,这个时候呢,得不偿失,那么可能有的人听完之后说这也不行,那也不行,那到底该咋办呢?哎,咱们有一个原则啊。这个原则呢?简单的结论就是这个。这个比例也是官方所推荐的一个比例,也就是说咱们的并行度,也就是所有的task数量刚好是集群里面核心数的两到三倍。举个例子,如果咱们以之前的资源去提交三个ex,每一个呢是两个和那一共是不是六个,那咱们的并行度就设置为它的。
07:08
两到三倍,两倍就是二,三倍就是八,这个就是比较高效利用CPU的一个场景,当然你也要衡量一下数据分片合不合理,对吧,一般都是可以的啊,一般都是可以的。那如果你会发现单个分配内存过高了,那怎么办?那你再去调呗,对吧。那你在调高并行度的同时,你是不是也得把集群的核心数也上调一下啊,这个是一起的配套了。那比如说咱们这个啊。这次咱们给的是三个ex,每个四个核心,然后呢,每一个是咱们还是给六个G吧,那这样我们可以看到它的一个并发是不是一共有12个。
08:00
那这个时候咱们的并并行度,也就task的数量设为两到三倍,是不是24~36之间是比较合理的?对吧,那咱们现在呢,先来一个不调的看一下现象啊。我先看一下我的雅安恢复健康没有,没有的话我得亲一下,哎呀,有两个不行了。稍等好了,那个雅安问题处理处理过了啊,啊,现在是健康状态,那咱们现在要来提交的就是这个partition DEMO,这个呢,就没有任何的指定并行度的,那我们看一看这边的代码啊,大概的做法。流程也简单啊,给大家简单讲一下,就是查询出了读出咱们之前上传的三张表啊,这就三张表啊,之后呢,再对这三张表做了一个join之后将join的结果写到一张新的表,叫做SCO detail,反正就是有一个detail detect对吧,蚯蚓后的表写到detail,就是简简单单一个逻辑,像其他的就是换个别名,因为怕那个冲突嘛,名字冲突就没有了,那接下来。
09:13
咱们就来提交这个,来观察一下它的一个现象啊,来咱们提交。啊,这是我刚才听的好,进到是B目录下面啊。提交。这个咱们就没有再去死循环了,对吧,因为没必要看那个存储内存了啊,这个时候咱们等。这应用已经上来了。
10:00
看一下。好,你看现在都很正常的啊。那。咱来看。Stage。那在这次这局大家能看到啊,这边前面几个都比较快,但后面这几个都有多少个task,可能是不是各有200个,其实就是咱们做了两次交易嘛。对吧,每次join是不是要杀uffle啊,那每次shuffle咱们说了是b circle的默认并行度就是200,因为我也没去指定嘛,他取的就是默认值。来看一下代码,就是一次,这是第二次啊。那我们得。好,先看看这个。大家看一看,首先并行度多是一个问题,另外还有一个问题是什么?
11:06
对于这个来讲。这段时间来讲,这边的CPU资源是不是只有一个在跑啊。一时间只有绿色的这个在跑,都在转啊,这个就是一个CPU资源浪费,那包括这时。对吧。这段时间是没有浪费的。他们是。看你看。这是看了一个executor,这个executor同一时刻只有四个线程嘛,根据咱们的提交参数啊啊,所以它有四个。再跑这是没问题的啊,然后你看看到了这个时刻,这个时刻。是不这个执行完了啊,然后空出来了,是不是有一个塞进去了啊,所以这个是这么一回事,你不要看着上下好像都它没有在一起的,也就是说你一画一条线下来只可能有四个在一起,总而言之呢,但是到后面为止,这块只有一个和在跑依它是不是三个河都在空转了。
12:11
这就是一个CPU的浪费啊,CPU的浪费。应该也快跑完了啊。嗯,还有一点点已经跑完其中一个一,其中一个join跑完了,还有一个join。你看这个就两一共200个task来,同学们大家一起看200个task。
13:04
它是三个exe都用到,都分配到了,那么其中哈多二哈其中两个exe,他们每一个都是四核嘛,他们只跑了四个task就没了,后面这么一段时间都都都。都没干啥了,那其他的都集中在这一块了。啊,你看大家可以明显的看到它这个CPU浪费的现象还是比较严重的啊,比较严重的,那咱们来尝试着把它做一个调整,怎么调呢,同学们。根据咱们讲的原则。现在咱们是并发度是确定的,是12,那咱们要调的是不是一个并行度啊,也就task的数量,默认我们说的是200,有浪费现象,这个时候咱们要把它切换到并发度的二到三倍之间,也就24或者36,那咱们就取个三十六百八,24还是偏小的。
14:00
那所以呢,在后面咱们就对他进行了一个调整。把这个circle的沙并行度调成了36,刚好是三倍,那其他的代码一模一样啊,没有改变啊没有改变。那这个时候咱们再来提交另一个任务。啊,再也给六个G吧,保持一致。提交,提交完之后,咱们同样的去看他的一个执行情况。啊,咱们这里少了少了一个包名啊,我稍微调一下啊,应该是叫爬水。
15:04
包名是不是又写错了,我看一下。我上次拷贝的时候好像按到了这里多了一个N啊,全内名也错了。啊,这次没问题了,行,那咱们退退退退好延按页面看一下。现在还在接收阶段啊,好,Running。也可以去看历史服务器啊,现在就不用去看。好,咱们点进来运行时的UI页面。嗯。Exec都添加了。看一下stage。啊,正在跑,那这个时候pending是挂起的,就是等待执行的stage,那现在在跑这三个三个stage,这三个其实就分别对应三张表读取嘛,他们等他们读完刷一下。
16:08
好,跑完三个了,那另外两个你看。那是不是对应三张表的两次join呢?每一次join都是一个shuffle,那这一块呢?是不是就有36个并行度,36个并行度就对应36个task对吧,这边就很直观了。好,跑完其中一一个交易呢,那我们可以先来看看它啊这个。大家也可以这边看到shuffle情况嘛,对吧,这个有shuffle rate,其他三个都是right对吧。点进来瞅一眼他的一个CPU使用情况。让他加载一会儿,不要着急啊。这好像有点久啊。
17:05
那我们看看。这边跑四个,这边跑四个,这边跑了一些,那么其中这边空闲的时间段是干嘛的呢?是不是其他stage去占用了呀,啊,它是被其他stage占用,那我们从纵向的来看,这边是不是有四个,你随便抽一个点都有四个在跑,CPU是没有浪费啊,一个executor是不是有四个核对吧。你包括这里也有四个,这里也是划中了四个四个,四个基本上我们可以看到CPU没有太多的浪费啊,没有太多的浪费。那再看看另外一个stage。这个是stage。这个是不是看起来就很均匀呢?它首先三个ex都。
18:00
都分布了它的一个task,那你看。这边有,这边有,这边有,这边有,这边有,具体来讲还是比较均匀的,比较均匀的。这相比于前面那种浪费就好多了啊,这就是咱们调的一个效果。等他跑完一下。好,应该已经跑完了,刷一下。
我来说两句