从 SortExec 的排序来谈 Spark Tungsten 计划中的缓存友好特性

Hive核心知识点和面试高频考点 Hive是一个开源的,建立在Hadoop上的数据仓库框架,提供类似SQL的HQL语言操作结构化数据,其基本原理是将HQL语言自动转换成Mapreduce任务或Tez任务或Spark任务,从而完成对Hadoop集群中存储的海量数据进行查询和分析。 阅读详情

背景

本文基于Spark 3.5.3
Spark Tungsten(钨丝计划)是 Databricks 引入的 Spark SQL 优化引擎。主要致力于提高Spark的执行效率:
它主要从以下三个方面:

  1. 内存管理优化
  2. 全阶段代码生成
  3. 缓存敏感计算

前两个好理解,如 内存管理优化 主要是通过手动管理内存,使用紧凑二进制的UnsafeRow的数据结构来替换jvm的数据结构
全阶段代码生成 通过消除虚函数的调用(会有二次寻址),来提高JVM运行效率,
那第三个是什么呢?缓存敏感计算到底指的是什么?这一篇文章就来说清楚。

结论

先说结论:在Sort中 Spark通过将排序键和指向数据的指针存储在一起,主要是先利用排序键做前缀索引,来进行Record的数据比较,如果排序键相同的话,再从内存中获取对应的数据进行比较,这种从内存中获取数据是随机访问,导致CPU的局部缓存命中率低,不像把数据排序的键存在一起,可以高效的利用CPU的局部缓存。
支持前缀比较器的类型有: BooleanType | ByteType | ShortType | IntegerType | LongType | DateType |TimestampType | TimestampNTZType | FloatType | DoubleType | _: AnsiIntervalType| DecimalType 且 精度位数小于 18
注意这里的StringType不支持前缀比较器,因为String类型的长度是不定的,不能用long类型来表示,从而无法进行比较。

分析

先看SortExec涉及到排序的数据流:

SortExec.doExecute
   ||
   \/
SortExec.createSorter
   ||
   \/
insertRow  ->   UnsafeExternalRowSorter.sort
                 ||
                 \/
                UnsafeExternalSorter.getSortedIterator
                 ||
                 \/
                UnsafeInMemorySorter.getSortedIterator

这里的UnsafeInMemorySorter包括了 插入数据的recordPointer + keyPrefix ;
注意:这里的数据保存在LongArray中(从taskMemoryManager分配过来的),这里的LongArray以8字节作为一个步长,用Unsafe.putLong和setLong进行操作,也就是存储8字节的数据
这里的 recordPointer 来源于 memory page以及page内的offset

 private MemoryBlock currentPage;
 ...
 recordPointer = taskMemoryManager.encodePageNumberAndOffset(currentPage, pageCursor)

keyPrefix 来源于SortPrefixUtils.getPrefixComparator的computePrefix的方法,这里会根据不同的类型返回不同的前缀比较器。
SortPrefixUtils.getPrefixComparator的代码如下:

def getPrefixComparator(sortOrder: SortOrder): PrefixComparator = {
    sortOrder.dataType match {
      case StringType => stringPrefixComparator(sortOrder)
      case BinaryType => binaryPrefixComparator(sortOrder)
      case BooleanType | ByteType | ShortType | IntegerType | LongType | DateType | TimestampType |
          TimestampNTZType | _: AnsiIntervalType =>
        longPrefixComparator(sortOrder)
      case dt: DecimalType if dt.precision - dt.scale <= Decimal.MAX_LONG_DIGITS =>
        longPrefixComparator(sortOrder)
      case FloatType | DoubleType => doublePrefixComparator(sortOrder)
      case dt: DecimalType => doublePrefixComparator(sortOrder)
      case _ => NoOpPrefixComparator
    }
  }

UnsafeInMemorySorter.getSortedIterator的流程如下:

                ┌─────────────────────────────────────┐
                │  UnsafeInMemorySorter.getSortedIterator()  │
                └─────────────────────────────────────┘
                                    │
                                    ▼
                ┌─────────────────────────────────────┐
                │    prefixComparator 支持 Radix Sort?│
                └─────────────────────────────────────┘
                        │                      │
                       Yes                     No
                        │                      │
                        ▼                      ▼
            ┌───────────────────────┐  ┌───────────────────────┐
            │    RadixSort          │  │    TimSort (Sorter)   │
            ├───────────────────────┤  ├───────────────────────┤
            │ • 直接排序 key prefix  │  │ • 需要比较器           │
            │ • O(n * 8) 复杂度      │  │ • O(n log n) 复杂度   │
            │                       │  │ • 需要完整记录比较      │
            │ • 缓存友好             │  │ • 可能缓存未命中        │
            └───────────────────────┘  └───────────────────────┘
                          │                      │
                          └──────────┬───────────┘
                                     │
                                     ▼
                    ┌─────────────────────────────────────┐
                    │      返回 UnsafeSorterIterator      │
                    └─────────────────────────────────────┘ 

这里会根据 prefixComparator 是否支持Radix sort(基数排序)来判断,是直接走 Radix sort还是 TimSort
如果是Radix sort,则直接根据前缀比较器进行比较;
如果是TimSort的话,则先直接根据前缀比较器进行比较,如果相等,则在根据pointer获取数据进行比较。

注意无论是 Radix sort 还是 TimSort ,如果只是用到前缀比较器的话(没有用到pointer获取数据),因为排序键的前缀都存在一个LongArray类型中,这样CPU需要数据的时候,会以数据块为单位从内存加载到缓存,根据局部性的原理(若一数据被访问,邻近数据也大概率被访问),相邻的排序键的前缀也都会加载到缓存中,这样CPU的缓存命中率就会大大提升:

 offset = RadixSort.sortKeyPrefixArray(
          array, nullBoundaryPos, (pos - nullBoundaryPos) / 2L, 0, 7,
          radixSortSupport.sortDescending(), radixSortSupport.sortSigned());
 ...
 MemoryBlock unused = new MemoryBlock(
          array.getBaseObject(),
          array.getBaseOffset() + pos * 8L,
          (array.size() - pos) * 8L);
 LongArray buffer = new LongArray(unused);
 Sorter<RecordPointerAndKeyPrefix, LongArray> sorter =
   new Sorter<>(new UnsafeSortDataFormat(buffer));
 sorter.sort(array, 0, pos / 2, sortComparator);
【CTF-misc】java盲水印BlindWatermark工具使用 ​ 盲水印是一种肉眼不可见的水印方式,对图片资源使用图片盲水印或者文字水印,借此避免数字媒体未经授权的复制和拷贝,可通过对原图进行解码操作,得到水印图来证明版权归属。 题目来源:NewStarCTF 2023 公开赛道 WEEK2|MISC:Jvav 阅读详情

相关推荐

别再手动填数据了!Vivado里用.coe文件给ROM IP核预装数据的保姆级教程

本文详细介绍了在Vivado中使用.coe文件为ROM IP核预装数据的全流程教程,包括文件格式规范、数据转换技巧和Vivado配置指南。通过自动化数据加载,开发者可以显著提升FPGA开发效率,避免手动输入错误,适用于查找表、波形存储等多种应用场景。

weixin_33377602的博客 337

Spark DPP(动态分区裁剪)导致的DataSourceScanExec NullPointerException问题分析以及解决

背景 本文基于spark 3.1.2,且运行在yarn模式下 最近在调试 spark sql的时候遇到了空指针的问题,如下: Caused by: java.lang.NullPointerException at org.apache.spark.sql.execution.DataSourceScanExec.$init$(DataSourceScanExec.scala:57) at org.apache.spark.sql.execution.FileSourceScanExec.<in

monkeyboy_tech的博客 3万+

别急着做AI:FDE教你识别真需求,让AI真正落地

人工智能项目在落地过程中,经常出现业务方高喊“我们要做AI”,却说不清具体应用场景的现象。判断一个需求是否值得用AI实现,不能只看技术流行度,而要从问题出现频率、当前替代方案以及可量化业务价值三个维度展开验证。同时需要冷静比较规则引擎与大模型的边界:不是所有语义任务都要靠生成式模型,稳定、可解释且低成本的传统方案往往更具工程性价比。数据闭环也至关重要,缺乏历史样本与反馈回流路径的项目,很难在真实环境中持续优化。针对智能客服、合同审查或企业知识库等典型场景,可借助人机协同与最小代价的用户验证,逐步筛除伪需求,

weixin_42624889的博客 341

SPARK SQL中 CTE(with表达式)会影响性能么?

背景及问题 本文基于spark 3.1.2 最近在排查spark sql问题的时候,出现了一系列的(CTE)with操作,导致该任务运行不出来,而把对应的(CTE)with 替换成了临时表以后,任务很快的就能运行出来 对应的最简化的sql如下: with temp1 as ( select null as user_id ,a.sku_id ,int(sum(`可申请数量`)) `开放申请数量` from xxx.xxx `a` where pt between '20

monkeyboy_tech的博客 7321

在 SAP ABAP 里可靠地对接 FTP 服务器:从连接、命令到传输与排错的完整实战

本文详细介绍了在SAP ABAP中实现FTP文件交换的完整技术方案。文章首先解析了FTP协议的双连接特性(控制连接与数据连接),强调保持控制连接的重要性。随后详细说明了ABAP中FTP操作的四步标准流程:建立连接(包含HTTP_SCRAMBLE加密)、执行命令、断开连接和关闭RFC通道。文章提供了实战案例代码,演示如何将FTP文件复制到应用服务器再读取进内表处理,特别指出后台作业与前台操作的关键差异。最后总结了常见错误排查要点,包括连接模型、路径设置和资源释放等问题。全文通过SAP标准函数模块的调用顺序、典

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 305

HTML满屏跳动的爱心(完整代码)

HTML语言实现满屏跳动爱心的完整代码。

AIGC 12万+

Spark task过多导致任务运行过慢甚至超时

背景以及现象 本文基于 spark 3.1.2 设置spark.driver.memory=2g 在调试spark sql任务的时候,发现有几个任务产生了40多万个Task,而且任务长期运行不出来。 分析 运行此sql,可以得到如下的dag(我们只截取产生Task多的Stage),由此可以看到是scan的文件太大了(scan了日志文件半年的数据)。 但是为什么这种情况下会导致任务运行很缓慢甚至会超时呢? 找到driver端, 用jstat -gcutil查看一下对应的gc情况(对应的内存都是调优完后的镜像

monkeyboy_tech的博客 6799

网神 SecGate 3600 防火墙 app_av_import_save文件上传漏洞(含批量验证poc)

网神 SecGate 3600 防火墙 app_av_import_save文件上传漏洞(含批量验证poc)

weixin_43567873的博客 296

【k8s系列5】KubernetesClientException: too old resource version 原因分析

背景 公司目前在基于k8s做调度(基于io.fabric8:kubernetes-client:4.2.0),在运行的过程中,遇到了如下问题: OkHttp WebSocket https://10.25.61.82:6443/...] DEBUG io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager - WebSocket close received. code: 1000, reason: [OkHttp WebSocket

monkeyboy_tech的博客 6041

Allegro如何设置走线自动删除重复走线操作指导

Allegro如何设置走线是自动删除重复走线操作指导在PCB布线的时候,点到点需要重复走一段线的时候,希望原来的线段自动被删除,Allegro设计的时候支持这个操作如下图,重复走中间的线段的时候,希望下方的走线自动删除具体操作如下This section is describe what the function allegro have ,helpfully could let user know more about allegroAllegro Design and Analysis includes

weixin_54787054的博客 4497

IEC 61400-1:2019 附录 C 湍流模型全面解读

IEC 61400-1:2019 附录 C 全面解读

weixin_46713695的博客 471

【mlflow系列1】mlflow 的搭建使用

背景 mlflow是Databrick开源的机器学习管理平台,它很好的解藕了算法训练和算法模型服务,使得算法工程师专注于模型的训练,而不需要过多的关注于服务的, 而且在我们公司已经有十多个服务稳定运行了两年多。 搭建 mlflow的搭建主要是mlflow tracking server的搭建,tracking server主要是用于模型的元数据以及模型的数据存储 我们这次以minio作为模型数据的存储后台,mysql作为模型元数据的存储,因为这种模式能满足线上的需求,不仅仅是用于测试 minio的搭建

monkeyboy_tech的博客 5183

Unity GameObject 核心机制深度解析:从底层结构到工程实践

从底层机制讲透 Unity GameObject:托管壳加原生芯的双层对象模型如何制造假 null 陷阱、Transform 层级与组件通信的原理、生命周期回调的确切顺序。文章同时给出 Instantiate 成本分析与对象池等高频场景的工程实践。

游戏人生 40

【spark系列12】spark remote shuffle service(RSS)杂谈

背景 对于spark shuffle service(以下简称RSS),在社区其实早就有探讨SPARK-25299,只不过一直没有达成一致,且目前的内置的shuffle service 也能满足大部分的场景,也就被搁置了,但是由于kubernetes的越来越火热,spark 社区也慢慢的集成了spark on k8s,当然k8s社区也集成了spark,具体区别见spark on k8s 与 spark on k8s operator的对比. 但是就目前的spark on k8s来说shuffle还是存在问题

monkeyboy_tech的博客 4859

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

FLINK JDBC SQL Connector遇到的类型转换问题

背景 Flink 1.3 最近在写Flink Sql的时候,遇到了java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 问题 分析 直接上报错的sql,如下: CREATE TABLE `xxx` ( `merchantId` BIGINT, `userId` BIGINT, `status` BIGINT ) WITH ( ); 具体的问题堆栈如下: java.lang.C

monkeyboy_tech的博客 4840

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SPARK的计算向量化-已有的向量化项目

背景 在SPARK的计算向量化-spark本身的向量化中,我们提到spark是利用代码生成(生成for循环),从而JIT进行向量化。这是有局限的,所以大部分公司都会采用通过其他方式来进行向量化计算。 我们列举几种已知的应用到spark计算引擎的向量化技术。 Velox Meta(也就是Facebook)开源的一个C++实现的SQL执行引擎,输入逻辑执行计划,利用SIMD指令实现向量化操作,输出结果; 结合Apache Arrow作数据交换,可以实现Spark的计算向量化。 项目见facebookincuba

monkeyboy_tech的博客 4315

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

yarn和k8s(kubernetes)混合部署初步方案(利用cgroup资源限制)

版本 yarn 2.6.0 k8s v1.15.2 背景 随着k8s的越来越火热以及k8s的可扩展以及自修复优势,k8s势必是互联网的优势,但是很大一部分公司的资源管理工具依旧是yarn,而且yarn和k8s也必然并行很久一段时间, 但是由于yarn的隔离型相对于k8s来说还是很弱的,好在yarn 2.6.0版本也集成了LinuxContainerExecutor(默认是DefaultContainerExecutor),也就是说yarn在好长一段时间是不支持cpu限制的,LinuxContainerExe

monkeyboy_tech的博客 4159

SPARK Expand问题的解决(由count distinct、group sets、cube、rollup引起的)

背景 本文基于spark 3.1.2 我们知道spark对于count(distinct)/group sets 以及cube、rollup的处理都是采用转换为Expand的方法处理, 这样做的优点就是在数据量小的情况下,能有以空间换时间,从而达到加速的目的。 但是弊端也是很明显,就是在数据量较大的情况下,而且expand的倍数达到上百倍或者千倍的时候,这任务运行的时间很长(这在数分中是非常常见的)。 分析 先来看一组图: 是不是很刺激,数据从2,635,978,109直接扩张到了168,702,598,

monkeyboy_tech的博客 4010

SPARK 是怎么清除Shuffle中间结果数据的

背景 本文基于 SPARK 3.2.1 我们知道在Spark中,shuffle的数据会存在ESS或者BlockManager中的,但是spark什么时候会删除shuffle的中间结果数据呢?这篇文章我们来分析一下 分析 我们知道spark肯定会删除shuffle结果数据,要不然长期以往,磁盘肯定会爆掉。 其中清除的组件就是ContextCleaner,代码如下: private[spark] class ContextCleaner( sc: SparkContext, shuffleDri

monkeyboy_tech的博客 3839

Spark做TPC-DS性能测试

最近由于在做上云的工作,并且公司离线部分引擎是Spark,所以做了一次基于TPC-DS性能比对测试。生产了大约200GB的数据。

monkeyboy_tech的博客 3701

Spark中的WholeStageCodegenExec(全代码生成)

背景 在之前的文章中Spark DPP(动态分区裁剪)导致的DataSourceScanExec NullPointerException问题分析以及解决,我们直接跳过了动态代码生成失败这版本一步部分,这次我们来分析一下,SQL还是在以上提到的文章中。 分析 运行完该sql,我们可以看到如下的物理计划: 我们看到FilterExec和ColumnarRoRowExec并没有在一个WholeStageCodegen 中, 这是为什么呢? 这是因为exists方法是继承自CodegenFallback Tr

monkeyboy_tech的博客 3466

Spark CTAS union all (union all的个数很多)导致超过spark.driver.maxResultSize配置(1G)

spark CTAS nuion all (union all的个数很多)导致超过spark.driver.maxResultSize配置(2G)

monkeyboy_tech的博客 3041

深入理解SPARK SQL 中HashAggregateExec和ObjectHashAggregateExec以及UnsafeRow

感悟和理解 翻译这篇文章是为了更好的理解ObjectHashAggregateExec和UnsafeRow,关于UnsafeRow的文章,可以参考Spark源码修改系列 - UnsafeRow内存布局和代码优化。 其实明显,UnsafeRow是模拟了offheap的分配方式而在堆上进行的操作,它并没有脱离了jvm,而是使用了Java unsafe API(Java提供的底层非安全操作接口),允许用户像操作C++指针一样来申请和访问内存地址,JVM也不会对这部分非安全数据进行额外的类型检查和垃圾回收。 事实上

monkeyboy_tech的博客 2960

Spark Media 问题清单

本项目基于 libdatachannel 构建 C++ WebRTC SFU 服务器,遵循 IETF WHIP/WHEP 标准信令,采用帧级转发实现低延迟多人互动。

qq_43538607的博客 379

【计算机毕业设计】基于Hadoop的公共交通运营数据分析与可视化系统 大数据毕业设计选题 Hadoop Spark Numpy Pandas Echarts

基于Hadoop生态的公共交通运营数据分析与可视化系统,利用Spark处理海量公交数据,结合K-Means聚类、Pandas/Numpy分析,实现线路、站点、区段等多维度统计。通过Django提供接口,Vue+ElementUI搭建前端,Echarts实现城市规模、线路特征、站点网络等动态可视化看板,构建从数据采集到可视化的完整闭环,助力智慧交通决策。支持机器学习模型定制,文末可获取源码。

weixin_19164791635 761

最新大数据毕业设计选题推荐-基于大数据的电影评分与热度数据可视化分析-大数据-Spark-Hadoop-Bigdata

本文介绍《基于大数据的电影评分与热度数据可视化分析系统》,采用Hadoop+Spark构建大数据处理链路,结合Django/Spring Boot后端与Vue+ECharts前端,实现电影评分、热度数据的采集、清洗、分析与可视化。系统支持高分影片管理、评分分布、热度传播趋势等多维度展示,提供可运行、可扩展的毕业设计参考,涵盖完整技术栈与源码,助力学生掌握大数据项目全流程开发。

IT研究室的博客 267
上一篇: Parquet文件中的索引
下一篇: Spark DynamicJoinSelection 规则根据AQE统计信息动态调整Join策略
鸿乃江边鸟
博客等级 码龄6年 3746粉丝 235原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值