- 博客(179)
- 收藏
- 关注
原创 Spark 3.4.0新特性--UI支持存储在RocksDB中
来说,目前存储所有的事件信息以及UI所需要的信息都是默认存储在内存中,这在CS中,对于以。作为存储以后,能够减少driver所需内存,并且引进新的。数据结构为InMemoryStore。能够大大加快spark事件的读写事件。Spark UI和SHS。
2023-07-01 15:39:00
1276
原创 Spark 3.4.x Server Client模式下的数据传输实现
中,我们提到Spark 3.4.x中是Client和Server之间的数据传输是采用。的,那具体是怎么实现的呢?这里的逻辑就是转换为。
2023-06-27 23:17:43
388
原创 Flink中KeyedStateStore实现--怎么做到一个Key对应一个State
所对应的所有的values,也就是* Flink中的Key-Groups*,(关于Key-Groups可以参考。,从网上随便查找资料就能发现正确的答案是:对于每一个Key会绑定一个State,但是这在。很好理解,一个特定的Operator算子共享同一个state,这是实现层面很好做好的。一般来说,正常的人第一眼就会想到:一个task绑定一个。也就是描述符的名字有关的,这就是为什么描述符必须是唯一的,关于。是从每个record中获取的,所以在。方法中才会更新对应的Key值。是在哪里初始化的,可以看。
2023-06-23 18:58:06
1327
原创 Spark中python和jvm的通信杂谈--ArrowConverter
这个方法中,python调用spark中方法,把序列化的*Iterator[Array[Byte]]*传给jvm执行,具体的细节,读者可以自行参考源代码.直接内存,这样可以避免了JVM内存到native内存的数据拷贝,尤其是在大数据场景下,提升的效率更加明显,且减少了用户态和内核态的切换次数。这个项目,该项目的初衷是加速进程间的数据交换,从目前的社区发展以及它的周边来看,其实是一个很不错的项目。的方式,大大提升了进程间的数据交换效率。与spark jvm进行交互,而数据的交换采用的是。
2023-06-21 23:24:58
828
原创 Apache Hudi初探(一)(与flink的结合)
long ckpTimeout = * 获取到。的方式,只需要引入了对应的jar包即可,以。的方式,所以不需要像使用。的超时时间,并设置为。
2023-06-18 16:53:18
1533
1
原创 Apache Hudi初探(九)(与spark的结合)--非bulk_insert模式
来说,什么也不操作(因为该index每次都会从parquet文件中读取信息从而组装成index),构建一个状态信息,主要是记录一下插入的记录数量和更新的记录数量 其中主要形成了以。(默认是true)会进行元数据的commit操作,这些commit的操作和之前。,则会要求排序,如果没有则只是按照partitioner进行重分区,(这里暂时忽略),主要是对数据进行分区处理,设计到小文件的处理。操作,所以没有去重的需要,所以直接采用spark原生的方式,实例的构造方法中会进行一些额外的操作。
2023-06-10 06:17:02
1290
原创 Apache Hudi初探(八)(与spark的结合)--非bulk_insert模式
并且从*.hoodie/20230530073115535.deltacommit* 获取internalSchemaOpt,具体的合并就是把即将写入的schema和internalSchemaOpt进行合并。因为是"bulk insert"操作,所以没有去重的需要,所以直接采用spark原生的方式,把df的schema转换成avro的schema。),则会进行去重处理,具体是调用。开始写操作,这涉及到回滚的操作。,就会进行schema的合并。是没有的,所以不会开启异步的。
2023-06-01 07:22:07
753
原创 Apache Hudi初探(七)(与spark的结合)
目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。最后还会在spark中刷新刚才建立的表,这样才spark的查询中就能查询到插入的hudi表。为true(默认是false,不开启),于此同时会把。表,分别对应snapshot表(实时表)和读优化表。这里主要是同步到数据到hive的元数据中,如果。),则读优化表,则不会家*_ro*后缀。集合中,便于后续调用,当然如果设置了。表来说,会有两张表,一张是*_rt。开启(默认是false,不开启)
2023-05-21 23:54:54
597
原创 Apache Hudi初探(六)(与spark的结合)
目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。之前说到只有获取到分布式锁的线程才可以继续一下操作。后续发现也是基于Datasource V2的。
2023-05-19 00:22:26
468
原创 Apache Hudi初探(五)(与spark的结合)
目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。所以默认情况clean和Archive服务都不是异步后台服务。是否开启异步clean清理服务。是否开启archive归档服务。的实例,该实例的对一个的。
2023-05-15 22:58:31
634
原创 Apache Hudi初探(四)(与spark的结合)
其中: bcbfc2b3-6a8a-480a-b2de-ed7d0e736cde-0 是 fileId ,由uuid + 写文件的次数(从0开始)目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。数据结构,其中包含了分区路径,fileId,以及写入的统计信息如文件记录数等。后续在进一步的写入的时候也是基于DataSource V2的。便于GC,以及收集写入的文件信息。目前的实现是打印出log信息,,注意这是在driver执行的。这是真正的写数据的地方。
2023-05-07 19:07:58
708
原创 Apache Hudi初探(三)(与spark的结合)
目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。"hoodie.bulkinsert.schema.ddl"会在DF.option方法中传递过来。,也就是说是时基于DataSource V2的,而且save的方法最终会调用到。也就是说最终会调用到。可以看到该类是继承了。
2023-05-01 22:29:36
631
原创 Spark 3.1.1遇到的 BroadcastQueryStageExec timeout
主要的问题是在于AQE阶段的任务的提交是同时提交且异步的,如果存在broadcast和shuffle,且shuffle占用了大量的资源以后,导致broadcast的job。目前该问题的解决是通过合并3.2已有的PR解决,目前合并的PR有。没有资源导致broadcast超时,主要原因还是资源不够。
2023-04-27 18:17:58
462
原创 Apache Hudi初探(二)(与spark的结合)
如果同时满足“hoodie.datasource.write.row.writer.enable”(默认是true)和“hoodie.datasource.write.operation”是。配置计算出来的表名(source中配置的hoodie.table.name和tableconfig获取的hoodie.table.name)不一致则报错。目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。,如果表存在,则复用现有的,,这会在文件的后缀上有体现。
2023-04-27 07:50:20
804
原创 Apache Hudi初探(与spark的结合)
hoodie.datasource.write.keygenerator.class”/"hoodie.sql.origin.keygen.class"和“hoodie.table.keygenerator.class”进行比对。获取“hoodie.datasource.write.keygenerator.class”的值,并对应用到“__partition_columns” 的值上,并以逗号分隔。目前hudi的与spark的集合还是基于spark datasource V1来的,这一点可以查看。
2023-04-22 10:39:20
1541
原创 Spark full outer join 数据倾斜导致OOM
spark full outer join目前存在一个问题,那就是在数据倾斜的时候,会导致Execuotr OOM:具体的问题描述,可以见。
2023-04-22 08:18:22
288
原创 数据湖的选型(delta iceberg hudi)以及比对
支持update,支持upsert(merge),具体看类IcebergSparkSqlExtensionsParser.replaceRowLevelCommands。分区是隐藏的,在查询时不需要添加关于分区的筛选条件,建表的时候指定分区的来源(由哪个字段计算而来)Iceberg有catalog的概念,是对表进行管理(create,drop等)的一个组件。需要额外的服务治理小文件,额外的服务清理过期的snapshot。支持多种存储,如 S3,oss,HDFS 等。支持 flink sql upsert。
2023-04-18 08:50:20
1278
原创 SPARK中InMemoryFileIndex文件缓存导致的REFRESH TABLE tableName问题
其中cachedLeafDirToChildrenFiles的值会在InMemoryFileIndex对象初始化的时候进行赋值,对应的方法为。那是因为,在一个jvm中,比如说是写了之后再读取,会进行。的情况下,在转换对应的逻辑计划当中,如果缓存中存在对应的表,则会复用缓存中的,具体的方法在。的错误,这种错误的原因有一种隐形的原因,那就是。在scan file的过程中,最主要涉及的是。对象,从而实现了文件的复用,从未导致问题。会缓存需要scan的文件在内存中,中 ,最主要的点是会公用同一个。
2023-03-12 22:22:17
1548
原创 SPARK outputDeterministicLevel的作用--任务全部重试或者部分重试
方法的时候,如果任务发生了重试,就有可能导致任务的数据不准确,那这个时候改怎么解决这个问题呢?该方法主要用于在重新提交失败的stage时候,用来判断是否需要重新计算上游的所有任务。这里如果任务Fetch失败了,根据该shuffle所对应的上游stage是不是。方法是随机分配数据到下游,这会导致一个问题,有时候如果我们用。所以根据以上分析,我们可以改写对应的RDD的。那么该变量的作用是什么呢?方法进行上游所有任务或者单个任务的重试。方法来进行stage任务的全部重试与否。方法进行循环调用上游的。
2023-02-20 21:54:30
599
原创 Spark 3.1.1 shuffle fetch 导致shuffle错位的问题
进行了重组(在获得streamHandle的时候内部会根据reduceIdArr构建blocks索引,下文中会说到)会导致和成员变量blockIds的顺序不一致,为什么两者不一致会导致问题呢?所以在以上两种情况下,只要有重新fetch数据的操作,就会存在数据的错位,导致数据的不准确。但是这个和createFetchShuffleBlocksMsg输出的顺序是不一致的,的索引下标,也就是下文中numBlockIds组成的数组下标,这里和上面的一样,只不过对应的方法为。这个方法的作用就是: 构建一个。
2023-02-15 21:42:33
1347
2
原创 Spark做TPC-DS性能测试
最近由于在做上云的工作,并且公司离线部分引擎是Spark,所以做了一次基于TPC-DS性能比对测试。生产了大约200GB的数据。
2023-01-31 22:05:23
2955
2
原创 关于jvm范型和scala implicit隐式参数以及classTag[T] typeTag[T]的一点思考
T: Comparator],它主要做了两件事:第一,引入了一个参数类型 T;在上面说到对于java语言来说,会在编译器期间擦除掉类型,但是对于scala来说,我们在编译器阶段是可以保存类型T的,这就是接下来说的。看到我们居然把可以范型为T(也就是object)的类型的值,赋值给String类型的变量,这难道是编译器没有进行类型擦除么?,其中aaa是String类型的变量,这样编译器在编译的时候,就会做一层强制转换。这一行表明编译器确实进行了类型擦数,因为能偶看到调用的是object类型的方法。
2022-12-14 21:31:59
343
1
原创 SPARK中metrics是怎么传递的
在任务运行期间,利用heartbeat心跳来传递metrics在任务结束以后,利用任务结果的更新来传递metrics最终,都是通过sparkListener:SQLAppStatusListener和 AppStatusListener分别完成Spark UI状态的更新。
2022-12-12 23:19:40
1096
原创 Delta Lake中CDC的实现
根据以上的分析,可以知道目前的CDF只是在Delte层级做了反馈,如果说想要在Flink层达到CDC的效果,还得有个中间层,把delta里的CDF的数据给读取出来,转换Flink 内部形式的ChangelogMode CDC格式(比如说。CDF是能让表能够输出数据表变化的能力,CDC是能够捕获和识别数据的变化,并能够将变化的数据交给下游做进一步的处理。是判断过滤条件是否是在元数据层能够囊括,如果可以的话,就通过。我们来分析一下是怎么做到数据行级别的CDF的。这里列举该表的所有文件,并把所有的文件标识为。
2022-12-11 08:05:16
681
原创 SPARK中关于HighlyCompressedMapStatus的说明(会造成运行时的数据不精确)
这是来map端任务记录精确分区的阈值,如果大于该阈值,则会记录真实的reduce数据的分区大小,如果小于则记录的是每个reduce大小的平均值(这导致会在reduce获取运行时的数据大小信息时数据不准确的问题,从而导致AQE的效果不是很理想)。采用的是对于数据量小的reduce分区数据采用公用平均值的方式,这在一定程度上能够减缓Driver OOM的概率,中,这样下游的reduce任务如果需要获取上游MapTask的运行情况的时候就会最终调用到。因为对于小数据量的分区,只需要存储一个平均值,而不像。
2022-11-06 22:45:01
1449
原创 Flink 基于K8S HA 存在的问题
在基于原生K8S做JobManager HA服务的前提下,随着部署在K8S的flink任务越来越多,JobManager节点挂的频率越来越高,这严重影响了整个Flink作业的运行。其实最主要的原因是flink集群对etcd的访问过于频繁(etcd是K8S的最为关键的组件),导致了整个K8S集群的不稳定。对于目前的flink的架构,画出如下的图,该图也是参考了。本文基于Flink 1.13.x。
2022-10-12 16:21:17
1097
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(10)
从一个unit test来探究SPARK Codegen的逻辑,本文基于 SPARK 3.3.0。
2022-09-20 12:29:26
228
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(9)
从一个unit test来探究SPARK Codegen的逻辑,sortAggregateExec的。本文基于 SPARK 3.3.0。updateExprs的不同。操作完后的结果buffer。其他的数据流向和之前的一样,方法,其中input为。阶段,所以更新语句是。
2022-09-20 12:28:41
881
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(8)
constructDoConsumeFunction方法中inputVarsInFunc。从一个unit test来探究SPARK Codegen的逻辑,本文基于 SPARK 3.3.0。根据数据类型的不同,调用。
2022-09-19 20:44:36
877
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(7)
val buffer = 和buffer.init(index, Array(iter))从一个unit test来探究SPARK Codegen的逻辑,对rdd进行迭代,对于当前的第一阶段全代码生成来说,该。代码进行编译,如果编译报错,则回退到原始的执行。代码初始化,对于当前第一阶段全代码生成来说,端进行编译,如果代码生成有误能够提前发现。(默认值),则回退到原始的执行。不会被用到,第二阶段中会把。不会被用到,因为数据是由。如果代码生成的长度大于。对于当前来说,目前只是。会被用来进行产生数据,
2022-09-18 22:53:45
525
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(6)
从一个unit test来探究SPARK Codegen的逻辑,本文基于 SPARK 3.3.0。中我们提到在对应的函数计算完后,是已经计算处理的结果了。的UnsafeRow。
2022-09-17 07:38:09
290
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(5)
是在SortAggregateExec的produce方法进行赋值的,也就是对应“SUM”和“COUNT”初始值的。传递进来了,但是在这个方法中却没有用到,因为对于大部分情况来说,该变量是对外部传递InteralRow的作用。,对于AVG聚合函数来说,聚合的缓冲属性(aggBufferAttributes)为。进行公共子表达式的消除,并提前计算出在计算子表达式计算之前的自表达式。对于当前的计划来说,SortAggregateExec的。本文基于 SPARK 3.3.0。对于目前的物理计划来说,当前的。
2022-09-15 20:32:27
787
原创 SPARK中的wholeStageCodegen全代码生成--GenerateUnsafeProjection.createCode说明
val writeFieldsCode =以及后面的代码组装。因为inputs的类型是LONG类型,所以对应到。因为inputs为null为false,所以。对每一个变量的赋值按照换行符进行分隔。对于在在RangeExec中出现的。
2022-09-14 20:18:58
531
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(4)
计算表达式的长度,对于LONG和DOUBLE类型长度为2,其他的为1,因为range_value_0是LONG类型,所以总的长度为3。不为空的情况下,则说明传入的是InteralRow类型的变量,需要调用InteralRow对应的方法获取对应的值。这部分是产生UnsafeRow类型的变量,这个UnsafeRow类型的变量里包含了rangExec的产生的变量。对于不是直接赋值的变量,而是通过计算得到的变量,则需要进行提前计算,在这里不需要计算。里面具体的细节,这里先忽略,以后会有具体的文章分析。
2022-09-13 23:24:49
422
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(3)
被赋值,这样父节点才能进行消费。值是用来表示rangExec生成的数据的,最终会被*consume(ctx, Seq(ev)val taskContext =和val inputMetrics =就是RangeExec生成数据的逻辑了,每个物理计划都是不一样。也是全部变量,而且还有初始化变量,这种初始化方法将会在生成的类方法。父节点进行消费rangeExec产生的数据,接下来会继续讲解。这部分就是根据每个分区的index不一样,生成不同的数据。是用来产生rangeExec数据的逻辑索引,遍历数据。
2022-09-09 00:03:16
372
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(2)
是对输出的数据进行组装,组装成UnsafeRow以便spark进行的后续处理,也就是在此以后返回的数据就是正常的InteralRow的处理方式了,对于*consume()*这部分代码我们后续再说,在这里我们先按照数据流的方式来解释代码。,如没特别说明,我们就只讲解AVG的代码生成部分,因为MAX等表达式原理是一样的。操作则是声明变量,这里的变量属于全局变量,也就是类的成员变量,前缀是当前类的前缀,具体是在。类型的变量,这样的话,就得调用InternalRow对应的方法获取对应的值,如。
2022-09-07 22:02:39
586
原创 SPARK中的wholeStageCodegen全代码生成--以aggregate代码生成为例说起(1)
看到这里的prefix = “”,所以单纯从执行计划看是没有任何迹象能表明存在着。但是实际在缕代码的时候,你就会发现这个全代码的逻辑根本就缕不通,那是因为。这种符号的,表明是有全代码生成的,而为什么在物理计划的时候没有显示。从一个unit test来探究SPARK Codegen的逻辑,,而这里的数字1和2代表者不同的两个代码生成阶段,因为。不支持代码生成,所以被隔离成了两个代码生成。本文基于 SPARK 3.3.0。作为子计划的前缀传递到了下游。计划是因为该两个计划重写了。
2022-09-02 09:26:17
880
原创 DATA AI Summit 2022提及到的对 aggregate 的优化
该优化的主要是partialaggregate的部分对于类似求count,sum,Avg的聚合操作,会存在现在mapper进行部分聚合的操作,之后在reduce端,再进行FinalAggregate操作。这看起来是没有问题的(能够很好的减少网络IO),但是我们知道对于聚合操作,我们会进行数据的spill的操作,如果在mapper阶段合并的数据很少,以至于抵消不了网络IO带来的消耗的话,这无疑会给任务带来损耗。利用运行时的指标信息,能够达到比较好的加速效果。但是这种在数据倾斜的情况下,会增加OOM的风险。..
2022-07-27 12:43:32
751
1
原创 SPARK中 DS V2 push down(下推)的一些说明
规则则是基于ScanBuilderHolder来做转换的(如果有遇到ScanBuilderHolder类型才会进行DSv2特有的规则转换),所以。我们有提到DSV2pushdown的功能,如JDBC复杂下推,以及Parquet的聚合下推等等。其实这里面有个比较大的背景–就是。类型,也就是DSv2,才会转换为ScanBuilderHolder,而后续的。本文基于SPARK3.3.0。一系列的规则中,第一个规则。.........
2022-07-24 09:56:57
853
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅