00:00
接下来我们聊聊Spark写入的过程当中的一个并发控制啊,那这个并发控制。那对于护Di来讲,主要有两种,一种是依赖于多版本控制,第二种呢是基于乐观锁,那它是不同的场景来用的,那么默认来讲咱们用的都是macc,这是什么意思呢?诶,我们还记得咱们在这个timeline上面不是有一个一个的instant instant里面有他的动作包含了什么?可能是commit,对吧,可能是compassion,可能是clean。对不对啊等等这些各种各样的动作,那么有没有可能说在同一个时刻有多个?提交或者compassion这种事情发生呢?正常来讲啊是。如果我们只有一个writer,大家注意一个关键词,如果使用同一个R,它是不会出现这种冲突问题的。
01:05
说白了,咱们依赖于护本身是不是有一个文件版本呢,对吧,咱们不是每一次都会,呃,最新的话都是一个最最大的一个文件版本嘛,对吧,前面咱们也聊聊这个版本的问题,那基于这种机制就可以了。我们会以什么呢?呃。来控制多个什么写入和查询之间的快照隔离嘛,咱们之前是不是还做了什么时间旅行,对不对?我们可以看到历史的某一个状态,因为它看起来都是一个一个。单次的操作啊,单次的写入啊,单个写入啊,那一定是顺序的挨个去执行的啊。那这样的话,这种模型没有问题啊,没有问题,这种就是ACC的多版本控制啊,简单聊一下就行了,下面是我们拿到一个动图,这是只有一个writer,然后是同步执行的。什么叫同步执行啊,大家看这个动图有什么?这里就是instant的各种action啊,你可能是commit,可能是compassion,可能是呃,那个那个那个clean,对吧,可能是classing,就classing这个数据句促就是合并文件啊,跟compassion的区别就在于compassion,它是合并增量数据。
02:20
它是对增量数据对点到跟pack进行合并啊,那class class呢,可能比如说你有多个文件了,哎呃,小文件,我们把你合并成一个大文件啊,这样子好了,那你看这就是只有一个writer,只有一个writer,并且呢,我们做的所有动作都是由它来同步完成,所谓的同步完成就是一排就呃排好队,一个一个来。啊,排好队一个一个来,这种很明显没有并发问题啊,不会出现什么并发问题对吧?好,那另外一个场景,我也只有一个writer,但是呢,同学们,我们的这个compassion也好,这个classing也好,就是跟我们写的这个动作跟去合并啊,压缩啊,这些是可以异步执行的,诶同学们大家注意,我说的是异步而不是多线,而不是同时执行啊,什么意思呢?啊,我可以去往里面写数据,但回头我是不是要进行compassion呢?啊,我就去调用一下compassion命令就好了,我不用等待compassion完成,大家注意,这是区别啊,我执行完写入了,我需要compassion,我调用了compassion,呃,这个动作,这个命令,然后呢,Compassion自己就开始干活了。
03:31
那至于你什么时候干完,那是你的事儿,能理解吧?而不是说我写入的同时再进行compassion啊,不是它本身有一个什么先后顺序,大家先要明白这一点,即使我是异步的,我这个写入跟compassion,其他这些也是有先后顺序的啊,只不过是啊,我通知你开始了,但是你什么时候做完,那是你的事儿啊,那么在这种时候呢,而且有一个特点是什么,大家注意看这个图啊,这个图从左到右不是有个。
04:01
一一格一格的嘛,对吧?啊,那么其实是什么呢?这边表示最新。的一个版本,这边表示旧的版本,那么大家想想我们写入的时候,大部分呃,不管咱们是up的话,是更新或者插入,是不是都是往比较新的文件来写啊。对不对,比较新的来写,那我们所谓的comparison一般都是对比较旧的,相对较旧的这些进行一个一个合并。啊,一个就是合并和压缩这些事儿啊,本身他们就是有先后顺序,本来就冲突不大,第二件事情呢,就是他们处理的对象很大程度上不是同一个啊,那这样呢,也没有没有什么并发问题,这种场景也是用ACC好说了这么多,咱们总结一句话啊,什么时候用macc啊,只有一个writer。只有一个writer,那这句怎么理解的?比比如说我有一张表A,那我只有一个任务,不管你用什么语法写的,不管你是写Spark df那种什么DF.right去写入,还是说Spark circle。
05:11
里面你去insert数据。这都是一种写入,对吧?比如说insert吧,啊,比如说upsett,我同时有多个作业在操作写入同一张表,如果有多个作业同时大家注意是同时这是一个程序,这是一个程序,它是要对表a afteret,那这个也是对表a afteret,那就有问题了,那就不适合用ACC了,但是如果我整体来看只有一个写入作业是对表A的写入,那这个时候用默认的ACC就足以能理解这个意思吧?好,那接下来就引申到另外一个东西了,针对于写入操作,如果有多个write,就像我刚才讲的,对于护底的一张表A啊,我有多个程序都要对表A进行一个写入,对吧?
06:02
我有一个程序往表A写入,另一个程序也在往表A写入,这种就是属于多个writer。那这个时候就有问题了,你就没法保证啊,它的一个并发,并发场景下的111个一致性的问题,那这个时候护体是基于什么实现呢?它基基于乐观锁来实现的,那乐观所悲观所这个知识,嗯。呃,简单,我们简单讲讲什么叫乐观锁啊,那比如说这里有一个对象叫表A吧,啊,那这个是嗯,WRITE1吧,我叫WRITE1,这个叫二。好,现在表A的版本是V同学们,那么。RIGHT1是不是往V1这个版本去写入新的数据啊,比如说写入A这条数据,他要写入B这条数据啊,你们都要写,那那么大家分开来看,对于他来讲,我们结合前面知识,如果是cow的表,它是不是会把老版本的pack文件跟新增量数据进行一个一个合并啊,对吧,写实拷贝合并嘛,对吧,他是不是要想要生成V2版本。
07:17
那么对于WRITE2来讲,他是不是也是操作的对象是V1啊?他也想生成一个VR版本。对不对,那这时候就有问题啊,比如说原先这里有一条数据C啊,V1里面只有一条数据C,这个的V2是包含了A跟C,这个的V2是包含B跟C,那到底谁谁才是真正的VR。对吧?你以谁为准都不对,你以他为准,你就漏了B,你以他为准,你就漏了A。是吧,那什么叫乐观锁呢?乐观锁是这个意思啊,这里也有个版本啊,然后这个是W1,这W2它是这样好,你们可以同时来进行操作,但是呢,你们会,呃,就是比如说W1在写入的同时,他不会去妨碍和阻止W2去写入,就互不影响,但是他们怎么区别取结果呢?谁快谁赢,谁慢,谁放弃,这个就是乐观锁,我举个例子啊,呃,他写的快,他快速的生成了VR版本。
08:21
那W2在写入的时候回头,比如说他呃,已经有V2了,对吧。然后W2去写,还没写完,到最后他写完了,或者说他写完的时候发现,诶已经变成VR了,我已经慢了一步,好,那你的结果就放弃就丢弃掉啊,它是基于这种机制嘛,对不对,也就是说乐观手机是加上了一个版本标记,对吧,我如果就多个并发同时在操作的话啊,谁快谁就赢了,谁慢,他会看一下标记啊,他已经落后了啊,他已经过时了,被淘汰了啊这样子,这咱们简单聊一下就行了。
09:00
另外他这一边呢,它是支持文件级的乐观一致性啊,如果同一张表任何两个写入没有更改的重叠文件,也就是说他们中间如果没有冲突的部分,那是两个都可以同时成功的啊,也就是他有进一步的改进啊。好行,这个是我们简单聊一下啊,这里是一个动图,你看有多个writer,你看都在同时进行什么往这张表去去去写啊,往这张表去写,你可写的话,你可能是增删改都有。好,那接下来我们介绍一下使用的方式啊,使用方式,那使用方式的话,也就是说如果是这有多个writer的场景,你想要启用它的乐观并发控制乐观锁的方式,那么需要配置几个参数,第一,因为我们默认是MVC,对吧,你现在有多个right,你就得改了,改成并发写啊,那首先是这个参数right,你看这个叫什么,并发模式为这个。为第二种方式啊。
10:01
叫乐观并发控制所啊,乐观并发控制乐观,第一个单词就乐观嘛,积极的啊,这是并发,这是控制好,然后第二个你要指定一个清理策略啊,就失败的时候,呃,这边是为累积啊,就固定这么写就行了,另外呢,还有一个叫。所的提供者是由谁来管理这个所,这个所维护在哪里,对吧,这个所谓的乐观锁的锁,他维护在哪里,那么它维护的地方啊,有三个地方啊,一个是主keepper,一个是hi的原数据,还有一个动态的DB啊,这边我只写了两个啊,官网的话目前是多多了,一个是动态DB,那么如果是。Keepper,那么就需要指定这么几个东参数啊,首先这个provider,那你就指定为什么keepper啊,Provider指定个主keepper,那既然是主keepper,那你就要指定主keepper的诶地址端口,还有它的锁的key,还有它存储的路径啊,也就是一些参数要指定,那么如果是have原数据库,那你就provider。
11:09
指定为have啊,然后呢,你要指定元数据的相关一些配置啊,一些配置参数就照着来就行啊,需要什么用什么。那另外一种那个那个DB是亚马逊特有的,那我们这边就不去说明了啊,你有需要去查阅官网就可以了啊呃,也不是所有人都会用亚马逊的这个产品,好,这个就是相关的一个说明。
我来说两句