当前位置: 首页 > 知识库问答 >
问题:

Spark SQL:“order by”提高了缓存内存占用率

韩玉石
2023-03-14

我有两个场景,其中我有23 GB分区par

设置:

  • 集群:12 节点 EMR
  • 火花版本:1.6
  • Spark 配置:默认
  • 运行配置:两种情况相同

案例1:

val paths = Array("s3://my/parquet/path", ...)
val parqFile = sqlContext.read.parquet(paths:_*)
parqFile.registerTempTable("productViewBase")
val dfMain = sqlContext.sql("select guid,email,eventKey,timestamp,pogId from productViewBase")
dfMain.cache.count

从< code>SparkUI中,读取的输入数据为6.2 GB,缓存的对象为15.1 GB。

案例1:

val paths = Array("s3://my/parquet/path", ...)
val parqFile = sqlContext.read.parquet(paths:_*)
parqFile.registerTempTable("productViewBase")
val dfMain = sqlContext.sql("select guid,email,eventKey,timestamp,pogId from productViewBase order by pogId")
dfMain.cache.count

SparkUI 读取的输入数据为 6.2 GB,缓存的对象为 5.5 GB。

对此行为有任何解释或代码参考吗?

共有1个答案

慎俊雄
2023-03-14

其实比较简单。正如您在SQL指南中看到的:

SparkSQL可以使用内存中的列格式缓存表… SparkSQL将仅扫描所需的列,并自动调整压缩

排序列式存储的好处是它非常容易压缩典型数据。当您进行排序时,您会得到这些类似记录的块,这些块可以使用甚至非常简单的技术(如RLE)挤压在一起。

这是一个实际上在具有列式存储的数据库中经常使用的属性,因为它不仅在存储方面非常有效,而且在聚合方面也非常有效。

sql.execution.columnar介绍了Spark列压缩的不同方面。压缩包,正如您所看到的,RunLengthEncoding

所以这里有两个部分:

>

  • Spark可以根据统计数据动态调整压缩方法:

    Spark SQL将根据数据的统计信息自动为每列选择一个压缩编解码器。

    排序可以将相似的记录聚集在一起,从而使压缩效率更高。

    如果列之间存在一些相关性(当情况并非如此时?),即使是基于单个列的简单排序也会产生相对较大的影响并提高不同压缩方案的性能。

  •  类似资料:
    • 问题内容: 我是所有内存管理主题的新手,所以有很多我不了解的事情。 我正在尝试将图像缓存在我的应用程序中,但是我在内存消耗方面遇到了麻烦: 所有的Bitmap Chaching代码都可以从此处复制粘贴:http : //developer.android.com/training/displaying- bitmaps/index.html 我调试了代码,并在Eclipse的DDMS视图中检查了堆

    • 【内存占用】页面主要展示项目运行过程中内存的使用情况,主要包括以下几个部分: 数据汇总 该项主要展示项目运行过程中的 “总内存峰值”、“堆内存峰值”、“GFX内存峰值” 和 “泄露风险”。其中,总内存为Unity引擎所统计的真实物理内存分配,并不包含系统缓存和第三方库的自身分配内存; 堆内存所指的是 Mono 管理和分配的托管堆内存; GFX内存为用于渲染的资源所占用的内存,主要包括纹理资源、网格

    • Android Studio似乎比其他任何应用程序占用更多内存。Java二进制增加了速度,过一会儿就慢下来了。通常重启android studio可以解决这个问题,但是,我需要每隔几个小时重启一次。在撰写本文时,Android Studio和Java总共占用了大约2.5GB内存。以前觉得eclipse不好:) 我有10GB的RAM,但仍然发现它使用缓慢,有时偶尔会挂起。我想知道其他人是否也面临着同

    • 是否有可能在内存中实现缓存以避免完全堆消耗? 我的spring boot java应用程序使用内存缓存,过期策略设置为1小时(咖啡因库用于缓存目的)。在此之后,所有缓存实例都处于旧代,需要收集完整的GC。现在,当XMX设置为10GB时,我可以看到经过几个小时的测试,我的缓存包含大约100k个实例,但在heap中(正好是旧一代),我可以找到数百万个缓存对象的实例。是否有可能在内存中使用缓存并避免这种

    • 当在进行大量的计算时,提升性能最直接有效的一种方式就是避免重复计算。通过在内存中缓存和重复利用相同计算的结果,称之为内存缓存。最明显的例子就是生成斐波那契数列的程序(详见第 6.6 和 6.11 节): 要计算数列中第 n 个数字,需要先得到之前两个数的值,但很明显绝大多数情况下前两个数的值都是已经计算过的。即每个更后面的数都是基于之前计算结果的重复计算,正如示例 6.11 fibonnaci.g

    • 问题内容: 这最终会消耗我所有的可用内存,然后进程被杀死。我曾尝试将标签从更改为“较小”标签,但这并没有什么不同。 我在做什么错/如何处理这个大文件? 我可以轻松地将其切碎并以较小的块进行处理,但这比我想要的还要难看。 问题答案: 当遍历整个文件时,将构建一棵树,并且不会释放任何元素。这样做的好处是元素可以记住其父元素是谁,并且您可以形成引用祖先元素的XPath。缺点是它会消耗大量内存。 为了在解