首先让我介绍一下我的用例,我每天会收到5亿行,如下:
ID |分类
1 | cat1,cat2,cat3,...,catn
2 | cat1,catx,caty,...,anothercategory
输入数据:50个压缩的csv文件,每个文件为250 MB - >总计:12.5 GB压缩
目的是回答以下问题:查找属于Catx和Caty的所有ID,找到属于cat3而不是caty等的ID ...:ie: cat1 U cat2 中的ID ids cat3∩catx
假设动态创建类别(每天我有一组新的类别),我的企业想要探索所有可能的交叉点和联合(我们没有一套固定的查询)我想出了以下解决方案:
我写了一个火花作业,将日期转换为脂肪稀疏矩阵,其中列是所有可能的类别加上列ID,对于每一行和列,我设置为true,如果id属于此类别,则为false,否则为false:
ID | cat1 | cat2 | cat3 | ... | catn | catx | caty | anothercategory | ....
1 |是的|是的|真| ... |是的| false | false | false | ....
2 | true | false | false | ... | false |是的|是的| true | ....
SQL可以简单地回答我的问题,例如,如果我想找到属于类别cat1和类别catx的所有id,那么我对该矩阵运行以下sql查询:
从MyTable中选择id,其中cat1 = true且catx = true;
我选择将这个稀疏矩阵保存为压缩的镶木地板文件,我对稀疏性和查询性质做出了这个选择,我相信柱状存储是最合适的存储格式。
现在我在这里描述的用例是我的观察,我可能会遗漏一些优化点:
我最终得到了太多镶木地板文件,我对最小的镶木地板文件的并行化程度越高。好像每个RDD给出一个镶木地板文件 - >因为我的查询遍历所有列值
我经历了很多帖子,但仍然不明白为什么写入500万/ 1000柱压缩拼花到S3要花费这么多时间,一旦在S3上小文件总和达到~35G
查看应用程序主UI,作业在写作阶段,转换阶段和洗牌时挂起似乎是资源/时间消耗。
我试图调整镶木地板参数,例如group_size,page_size和disable_dictionnary,但没有看到性能改进。
我尝试分区到更大的RDD并将它们写入S3以获得更大的镶木地板文件,但这项工作耗费了太多时间,最后我将其杀了。
我可以在~1小时内使用一个类型为r4.16xlarge的4个aws实例的spark 2.1独立集群来运行这个工作,我觉得我正在使用一个巨大的集群来实现一个小的改进,唯一的好处我得到的是运行更多并行任务。我错过了什么吗?我可以利用~1 To RAM来更好地实现这一目标并获得更大的镶木地板文件。
你对使用spark在S3上写大型镶木地板文件有什么反馈吗?
我也想知道你对这个解决方案的看法/批评。
谢谢和问候。
答案 0 :(得分:2)
这是Spark重读东西的组合,用于做摘要(你可以禁用的东西)和用于提交重命名()的工作的算法,它在S3中被副本模仿。
有关详细信息,请参阅“Apache Spark and object stores”和一些可以略微加快工作速度的开关(禁用摘要,使用较少重命名的算法)
即使有了这些,你也会得到延迟,因为S3最终是一致的,有可能产生腐败的输出。最安全的是写入瞬态HDFS文件系统,然后在所有工作结束时复制到S3