00:00
好,上节课呢,我们在讲数据可靠性的时候,遗留了一个问题,什么问题呢?比如说你即使数据可靠,也有可能产生数据的重复问题。那接下来3.7我们就着重来解决一下数据从问题,那首先来看一下数据的传递语义。从概念上来了解一下啊,那第一个概念呢,叫至少一次,什么叫至少一次呢。就是你生产者发送到卡卡集群,至少这边能收到一次数据。那怎么保证啊?我们上节课刚学完,你要想保证数据能够安全的送到目的地。这么几个条件,第一个条件AC等于负一。分区副本大于等于二。Isr里面应答的最小副本量大于等于二,这三者满足数据就一定能够送到生产者啊,送到卡帕集群。送到卡法集群。
01:00
那下面来看下一个。叫最多一次。比如说你上面至少一次的时候,容易产生什么问题呢。有可能会产生多发的问题,比如说重复发售。那好,那为了解决这个重复发送的问题,我这里面引出一个叫最多一次,也是最多我就往这面发送一次数据。那怎么实现呢?哎,我AC等于零啊。等于零的话,就不会有什么重复发送的问题,我就给你一个哪来的重复。那稍微总结一下。至少一次的话,保证的是数据不丢,但是呢,有可能重复。那至多一次呢,保证的是数据不重复,但是有可能会丢数。那怎么办呢?在生产环境当中,我们有这样一种场景,我们需要实现的是叫精确一次。尤其是跟钱相关的数据,我们不允许他多,也不允许它重复。
02:00
那这怎么办呢?那在卡卡0.1版本之后,引入了一个非常重大的特性,叫密等性和事物。他就来帮我们解决数据的重复性问题。好,那我们来看一看呗。看一看,首先来看第一个叫幂等性。双击打开。打开之后首先看一下幂等性的概念。什么叫密等性呢?没等性呢,就是生产者无论向博科发送多少次的重复数据。生产者博科。博客端只会持久化一条。比如说你这边往这发数据,只要他认为这两个相同了,那第二条就不发了。这也就是幂等性。那如果说幂等性再加上我们之前的数据可靠,比如说至少一次。这么三个条件。那我不就能保证数据不丢也不重了吗?这个是不丢,这个是不重复。
03:00
就这意思。那往下看。那么这个幂等性,它怎么判断数据不是一条重复数据呢?那它有判断的一个标准,就是它的P值。也就是说,只要这三个条件满足,他就认为这是一条数据。那它判断标准是PID分区以及序列化number号。那其中这个PID它什么含义?他呢叫丢失ID生产者ID号。那只要卡不卡,每重启一次就会分配一个新的。记住我这句话叫每重启一次就会分配一个新的PID,那好,那一旦这个卡卡集群挂掉之后,那PID是不是就变新的了?那你再通过这个去判断数据是否重复,是不是就不能判断了。所以幂等性呢,它确实不能保证叫什么呢?多会画的时候仍然能够不重复,它只能保证单会画内数据不重复,那所谓的单绘画就是你正常启动这一次,那算一次会画,那你再启动就是另一个会话。
04:07
那这意思。那再往下呢,下面是分区。那有分区号的话,那很显然你这是零号分区,一号分区号分区,那如果分区与分区间数据的重复有影响吗?没影响。那有没有影响之后呢,是这个序列化number号,它是单调递增的,比如说从零,然后1234这样递增啊。所以呢,幂等性呢,保证呢叫单分区单绘画啊,所谓的分区是这个单绘画呢,是这个PID数数据不重复,那我们来详细看一下对应的这个原理啊。左侧呢这块呢是生产者,右侧呢是卡法集群,卡法集群当中一个topic a有两个分区。首先这边发送数据过来了。过来之后都收到了一本数据,你看他的PID呢是1000,他的PID也是1000,没问题。那下一个看分区号。
05:01
分区号,分区号不同。那这两波就是不同的数据。那就没毛病啊,就可以继续收。那继续收的话往下看。上面呢,这个是PIDPID没问题,然后分区。分区不同。那么它们之间的PID。序列号,序列号不同啊,没问题,那再往下发。发送到这的时候有问题了,看一下这波数据当中,PID它俩相同,分区相同,序列化ID号也相同,那这波数据怎么处理呢?他就不会往磁盘上落盘。直接在内存当中就会把它干掉。这就是幂等性定的原理。啊,也就是说它判断的标准是PID分区和序列号。好,那我要想实现这个幂等性,在生产文件当中怎么配置呢?只需要把这个参数开启就可以了。这个参数的值默认就是处。默认就是打开的,我们来看一下是不是这样的哈。
06:01
把它复制。来到这里面CTRLF中看到吗。哎,这呢,就是这个开启对应的幂等性,它默认值呢,就是处。好,所以说你不用管它也可以,那当然你想把它关闭掉,那就制成false。好,这是幂等性。那下面我们来看一下对应的叫生产者事物,为什么要引入事物呢?大家思考一个问题,我上面啊密等性它保证的是单分机单会挂,一旦这个卡把挂掉之后再重启,那还是有可能产生重复据的。那我就不想产生任何一条冲数据。那这时候就只能用事物的方式来解决。那首先来看一下数字原理,双击。打开。打开之后,首先看第一句话。什么意思呢?开启事物必须得开启对应的幂等性,这是必须的。那好,因为啊,事物底层依赖的是密性,OK。
07:01
看右侧这块BROKE0博一,那这里面有一个叫事物协调器,还有对应的这是一个副本,这个好说,这个大家都会,那事物协调器专门用来处理事物的。那右侧这块呢,叫存储事物的特殊主题。因为事物它在提交过程当中,是要持久化到硬盘上一些信息的,那这个信息它存在哪里呢?诶存在某一个主题里面,比如他没持久化磁盘。我先存到主题,主题它底层仍然是存在磁盘里面。它是这样一个过程啊。那现在有这样一个问题哈,有什么问题呢。这个事物协调器啊,每一个博克节点,记住它都有这个事物协调器。那问题来了,你这个生产者发送过来的数据,我到底用哪一个博克节点的是吸造器呢?它这两个规则,它按这种方式哈,首先呢,它根据这个主题,它这个主题呢,默认是50个分区。那每个分区呢,负责处理一部分数据,比如说你事物都要存一些数据,那存数据就由这里面对应的分区来存。
08:06
那好,那事物的划分呢,是根据一个叫事物ID。这个事,ID是用户必须手动指定的一个。而且是全局唯一值。啊,这个我们用户可以设定啊,一会写代码的时候会看到,那么这个是YID它的哈希扣的值,对这个50球膜,就你50个分区吗?哎,我对你球膜,那就告诉我,我这个数据呢,是放到哪一个分区。那这样呢,计算出该事物属于哪一个分区,那假如说我们算的就属于这个零号分区。可以吧,那就放到零去了。那么该分区的leader副本所在的博克节点。这不lead吗?这个副本吗?即为45ID对应的这个四五协调器系列。啥意思啊,思考一下,你说首先找到对应的这个分区。那这个分区所在的节点上的这个事务协调器,他就是这次事故的主负责人。
09:02
就这么个事啊,就这么选的啊,对这个哈奇Co特值啊,就说45ID的哈奇特值,对50球膜。得到。那行,那下面来看。生产者在使用事物功能前,必须先制定一个唯一的事ID。全局唯一啊。有了ID之后,即使客户端挂了,它重启之后也能继续处理完成后续的事务。这个就很硬啊,你看我们之前密等性的时候,它是不是PID啊,PID呢是一旦卡卡挂掉之后重启它就生成新的了。那我们提前设置好这个室外地。他不受这个影响,你即使挂掉了,我这个给你持久化到这里面了。对吧,这句话到某一个主题里面,主题底下就是硬盘呢。那下面看一下它的工作原理,首先第一个。我这个生产者呢,向这个事物器道器请求对应的PID。那这个PID给谁用的,就是给密等性用的,因为这个事物底层就是密等性啊,所以他得拿到对应的这个PID,那对方呢,就给他一个PID好,那给完PID之后,这边就开始发送数据,往这个leader里面发。
10:11
发送完之后,他要提交请求提交。那提交请求,这个请求的消息他一定会给他持久化到里面。比如说进行一个记录。方便后续的一个回滚,那他持久化完毕之后,就会告诉这个生产者说,哎,我这边已经持久化完了。蒸了。成功之后,他会给这个节点发送一个肯定的请求,发生什么请求呢?判断你这波数据有没有真真正正的。持久化,完毕你就写好。如果说这边给他一个消息,说哥们儿,我已经把所有数据处理完了,正常返回,那这个事物就结束了。那他会把这个持久化的事物,成功信息持久化到这儿。进行一个记录啊,这是提交,这是成功。
11:02
这就是整个事物的一个底层原理啊,大家稍微了解一下就可以了,那这个过程啊,我们来看一下,卡巴呢,给我们提供了这个五个API参数。你说说了半天,那要在企业里面怎么真正的实操呢?哎,第一个就是初始化事物。第二个呢?开启事物。第三个啊,应该是第四个叫提交事务帝国是放弃事物,那中间这个第三个呢,它是为消费者提交那个offset的时候,带着事物啊来准备的,那我们后面再讲到的时候再提,那现在呢,主要我们用到四个。说实话。开启提交,放弃。那我们来试一下好不好?写个代码,还是它CTRLCCTRLV。这个呢叫四五。那这个写完之后怎么写呢?来到这里面,来到这个生产者下面这块。
12:02
拿了他。第二。初始化。初始化完毕之后呢,是启动,那点启动的话呢,就是begin启动。启动完毕之后,这块呢,就开始发送数据,那发送完数据我得commit提交一下吧,提交正常就OK了,但是万一失败的时候,我是要终止这个事,我。那这怎么写呢?哎,在你发送这个代码这块来一个。然后catch。Exception。这样写,这样写之后把它拿过来放到这里面。然后把这个提交拿过来,也放到这里面之后。62.2。About来终止事务,然后再来一个finally结束。把他踢过来。
13:01
哎,这样就OK了,比如说初始化事务,开启事务,提交事务以及事务的回滚。那行,那试一下看行不行啊行不行。把这个。调一下。看看我加完这几句话之后,有没有代码的相关的影响。哎,没成功啊,说明有问题,有同学该看了,这什么问题呢,就怕这个遇到bug。看一下。详详细细看一下,能不能看懂。我刚才在讲原理的时候,反复强调了,必须要手动指定一下,这个是YD,那你这里指定了吗?没有指定,那他就报错,必须指定,那必须指定来呗,在哪里指定呢?在这个配置信息当中。指定事物ID。好点。Producer。这个呢,就是对应的叫事物ID。
14:02
那失败ID呢,这个名称你任意取,但是保证全局唯一就可以了。那比如说我起一个ID01。这样就OK了,那我们来试一下这回行不行。你看这边就能够正常收到数据,帅哥,那你的提交成功没问题,那我要失败了怎么办呢?那我就模拟一下失败。我这边呢是发送数据,那发送过程当中有可能失败,我这样去模拟I等于一除以零。OK吧,那这样的话是不是就提交不成功啊,你这个提交就失败呗,那看一下中。看我下边已经执行完毕了,这边有没有收到数据,数据没有收到数据啊,因为这块呢,他提交不成功啊,这就是整个这个呃事务啊。
我来说两句