2017-09-14 4 views
1

Spark SQL을 사용하여 하이브의 데이터를 쿼리합니다. 데이터가 분할되고 Spark SQL은 쿼리 할 때 파티션을 올바르게 제거합니다.하이브 테이블의 파티션 정리 된 입력을 나열하는 방법은 무엇입니까?

그러나 파티션 필터 또는 특정 입력 파일 (.inputFiles은 분명한 선택이 될 수 있지만 정리 작업은 반영되지 않음)과 함께 소스 테이블을 나열해야합니다. 주어진 쿼리에 대해 어떤 부분 계산이 수행 될 데이터의

가장 가까운 곳은 df.queryExecution.executedPlan.collectLeaves()입니다. 여기에는 관련 계획 노드가 HiveTableScanExec 인스턴스로 포함됩니다. 그러나이 클래스는 org.apache.spark.sql.hive 패키지의 경우 private[hive]입니다. 관련 분야는 relationpartitionPruningPred입니다.

이것을 달성 할 방법이 있습니까?

업데이트 : 내가 제이 섹의 제안 및 반환 relationgetHiveQlPartitions을 사용하고 매개 변수로 partitionPruningPred을 제공함으로써 관련 정보 덕분에 얻을 수있었습니다 : 이것은 내가 필요한 모든 데이터를 포함

scan.findHiveTables(execPlan).flatMap(e => e.relation.getHiveQlPartitions(e.partitionPruningPred)) 

을, 모든 입력 파일에 대한 경로를 포함하여 올바르게 파티션이 정리됩니다.

답변

0

글쎄, 당신은 질의 실행의 저수준 세부 사항을 요구하고 있습니다. 경고되었습니다 :

귀하의 의견에 언급했듯이, 모든 실행 정보는 private[hive] HiveTableScanExec에 있습니다.

HiveTableScanExec 실제 운영자 (실행시 하이브 테이블)에 대한 통찰력을 얻는 한 가지 방법은 private[hive]이 아닌 org.apache.spark.sql.hive 패키지에 백도어 일종을 만드는 것입니다.

package org.apache.spark.sql.hive 

import org.apache.spark.sql.hive.execution.HiveTableScanExec 
object scan { 
    def findHiveTables(execPlan: org.apache.spark.sql.execution.SparkPlan) = execPlan.collect { case hiveTables: HiveTableScanExec => hiveTables } 
} 

필요에 맞게 코드를 변경하십시오.

scan.findHiveTables은 보통 :paste -raw이고 spark-shell은 "알려지지 않은 영역"에 몰래 들어가기 위해 사용합니다.

당신은 단순히 다음을 수행 할 수 :

scala> spark.version 
res0: String = 2.4.0-SNAPSHOT 

// Create a Hive table 
import org.apache.spark.sql.types.StructType 
spark.catalog.createTable(
    tableName = "h1", 
    source = "hive", // <-- that makes for a Hive table 
    schema = new StructType().add($"id".long), 
    options = Map.empty[String, String]) 

// select * from h1 
val q = spark.table("h1") 
val execPlan = q.queryExecution.executedPlan 
scala> println(execPlan.numberedTreeString) 
00 HiveTableScan [id#22L], HiveTableRelation `default`.`h1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#22L] 

// Use the above code and :paste -raw in spark-shell 

import org.apache.spark.sql.hive.scan 
scala> scan.findHiveTables(execPlan).size 
res11: Int = 1 

relation 필드는 스파크 분석기는 데이터 소스와 하이브 테이블을 분석하는 데 사용할 ResolveRelationsFindDataSourceTable 논리적 규칙을 사용하여 해결 됐어요 후 하이브 테이블입니다.

spark.sharedState.externalCatalog으로 사용할 수있는 ExternalCatalog 인터페이스를 사용하여 Spark에서 하이브 (Hive) 메타 스토어에서 사용하는 모든 정보를 얻을 수 있습니다. Spark이 하이브 테이블을 통해 쿼리 계획을 세우는 데 사용하는 메타 데이터를 모두 제공합니다.

+0

감사! 반환 된'relation'에서'getHiveQlPartitions'를 사용하여 관련 정보를 얻을 수 있었고'partitionPruningPred'를 매개 변수로 제공 할 수있었습니다 : 'scan.findHiveTables (execPlan) .flatMap (e => e.relation.getHiveQlPartitions (e.partitionPruningPred))' 여기에는 모든 입력 파일에 대한 경로를 포함하여 필요한 모든 데이터가 포함되어 있으며 올바르게 파티션이 정리되었습니다. 저수준 패키지 개인 액세스가 필요하고 표준'inputFiles'는 그 자체로 그렇게하지 못하는 점은 유감 스럽습니다. 나는 그것을 성능상의 이유로 생각하니? – binarek

관련 문제