Sql server Spark\u秩窗口函数-不带partitionBy子句
我使用的是Spark 1.6.2、Scala 2.10.5和Java1.7 我们的用例要求我们对超过2亿行的数据集执行稠密的_rank(),而不使用partitionBy子句,只使用orderBy子句。这目前在MSSQL中运行,大约需要30分钟才能完成 我在Spark中实现了如下所示的等效逻辑:Sql server Spark\u秩窗口函数-不带partitionBy子句,sql-server,scala,apache-spark,yarn,hadoop2,Sql Server,Scala,Apache Spark,Yarn,Hadoop2,我使用的是Spark 1.6.2、Scala 2.10.5和Java1.7 我们的用例要求我们对超过2亿行的数据集执行稠密的_rank(),而不使用partitionBy子句,只使用orderBy子句。这目前在MSSQL中运行,大约需要30分钟才能完成 我在Spark中实现了如下所示的等效逻辑: val df1 = hqlContext.read.format("jdbc").options( Map("url" -> url, "driver" -> driver, "db
val df1 = hqlContext.read.format("jdbc").options(
Map("url" -> url, "driver" -> driver,
"dbtable" -> "(select * from OwnershipStandardization_PositionSequence_tbl) as ps")).load()
df1.cache()
val df1_drnk = df1.withColumn("standardizationId",denseRank().over(Window.orderBy("ownerObjectId","securityId","periodId")))
我提交的纱线集群模式的工作如下所示。我有一个2节点的Hadoop 2.6集群,每个集群有4个vCore和32 GB内存
spark-submit --class com.spgmi.csd.OshpStdCarryOver --master yarn --deploy-mode cluster --conf spark.yarn.executor.memoryOverhead=3072 --num-executors 2 --executor-cores 3 --driver-memory 7g --executor-memory 16g --jars $SPARK_HOME/lib/datanucleus-api-jdo-3.2.6.jar,$SPARK_HOME/lib/datanucleus-core-3.2.10.jar,$SPARK_HOME/lib/datanucleus-rdbms-3.2.9.jar,/usr/share/java/sqljdbc_4.1/enu/sqljdbc41.jar --files $SPARK_HOME/conf/hive-site.xml $SPARK_HOME/lib/spark-poc2-14.0.0.jar
在日志中,我可以看到MSSQL中大约2亿行的表在15分钟内被导入并缓存到Spark中。在这个阶段之前,我看到大约有5 GB的内存被使用,其中一个执行器上大约有6.2 GB的内存可用,而另一个执行器上有11 GB的内存可用
但是,稠密_rank()的步骤总是失败,几分钟后出现“超出GC开销限制”错误。我甚至将驱动程序内存设置为7g,正如您在上面的spark submit命令中所注意到的那样。但是,没有用!。
当然,我知道缺少partitionBy条款实际上在Spark中造成了麻烦。但是,不幸的是,这是我们需要处理的用例
你能不能在这里再亮一点?我错过什么了吗?在Spark中使用稠密_秩窗口函数有其他选择吗?比如,使用本论坛其他专家建议的“zipWithIndex”功能?按照我的理解,“zipWithIndex”方法复制的是row_number()函数,而不是densite_rank,它会产生与densite_rank相同的结果吗
任何有用的建议都将不胜感激!
非常感谢 这里有两个不同的问题:
- 您可以通过JDBC连接加载数据,而不提供分区列或分区谓词。这将使用单个执行器线程加载所有数据 这个问题通常很容易解决,可以使用现有列之一,也可以提供人工键
- 您使用的窗口函数没有
。因此,所有数据都被重新排列到单个分区,在本地进行排序,并使用单个线程进行处理 一般来说,没有通用的解决方案可以仅使用partitionBy
API解决此问题,但您可以使用以下技巧:Dataset
- 创建反映所需记录顺序的人工分区。我在回答问题时描述了这种方法 在您的案例中也可以使用类似的方法,但它需要多步骤的过程,相当于下面描述的过程
- 使用关联方法,您可以对排序后的
使用两个单独的扫描(也可以在不从RDD
数据集转换的情况下执行类似操作)和其他操作:
- 计算每个分区的部分结果(在您的例子中,是给定分区的秩)
- 收集所需的摘要(在您的例子中是分区边界和每个分区的累积秩值)
- 执行第二次扫描以更正前面分区中的部分聚合李>