원래 질문은 Google Cloud에 spark 1.4를 배포하려는 것이 었습니다 . 다운로드 및 설정 후
SPARK_HADOOP2_TARBALL_URI='gs://my_bucket/my-images/spark-1.4.1-bin-hadoop2.6.tgz'
bdutil을 사용한 배포는 괜찮 았습니다. 그러나 SqlContext.parquetFile ( "gs : //my_bucket/some_data.parquet")을 호출하려고하면 다음 예외가 발생합니다.
java.lang.ClassCastException: com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem cannot be cast to org.apache.hadoop.fs.FileSystem
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2595)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:169)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:354)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
at org.apache.hadoop.hive.metastore.Warehouse.getFs(Warehouse.java:112)
at org.apache.hadoop.hive.metastore.Warehouse.getDnsPath(Warehouse.java:144)
at org.apache.hadoop.hive.metastore.Warehouse.getWhRoot(Warehouse.java:159)
그리고 나를 혼란스럽게하는 것은 GoogleHadoopFileSystem이 org.apache.hadoop.fs.FileSystem의 하위 클래스 여야하고 동일한 스파크 쉘 인스턴스에서도 확인했습니다.
scala> var gfs = new com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem()
gfs: com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem = com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem@46f105c
scala> gfs.isInstanceOf[org.apache.hadoop.fs.FileSystem]
res3: Boolean = true
scala> gfs.asInstanceOf[org.apache.hadoop.fs.FileSystem]
res4: org.apache.hadoop.fs.FileSystem = com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem@46f105c
내가 놓친 것이 있거나 해결 방법이 있습니까? 미리 감사드립니다!
업데이트 : 이것은 배포를위한 내 bdutil (버전 1.3.1) 설정입니다.
import_env hadoop2_env.sh
import_env extensions/spark/spark_env.sh
CONFIGBUCKET="my_conf_bucket"
PROJECT="my_proj"
GCE_IMAGE='debian-7-backports'
GCE_MACHINE_TYPE='n1-highmem-4'
GCE_ZONE='us-central1-f'
GCE_NETWORK='my-network'
GCE_MASTER_MACHINE_TYPE='n1-standard-2'
PREEMPTIBLE_FRACTION=1.0
PREFIX='my-hadoop'
NUM_WORKERS=8
USE_ATTACHED_PDS=true
WORKER_ATTACHED_PDS_SIZE_GB=200
MASTER_ATTACHED_PD_SIZE_GB=200
HADOOP_TARBALL_URI="gs://hadoop-dist/hadoop-2.6.0.tar.gz"
SPARK_MODE="yarn-client"
SPARK_HADOOP2_TARBALL_URI='gs://my_conf_bucket/my-images/spark-1.4.1-bin-hadoop2.6.tgz'
짧은 대답
실제로 IsolatedClientLoader와 관련이 있으며 근본 원인을 추적하고 수정 사항을 확인했습니다. 이 문제를 추적하기 위해 https://issues.apache.org/jira/browse/SPARK-9206 을 제출 했으며 간단한 수정으로 내 포크에서 깨끗한 Spark tarball을 성공적으로 빌드했습니다 : https://github.com/apache/spark / 풀 / 7549
몇 가지 단기 옵션이 있습니다.
--default_fs=hdfs
)으로 사용합니다. gs://
HDFS가 중간 데이터 및 스테이징 파일에 사용된다는 것만으로도 작업에서 경로 를 직접 지정할 수 있습니다. 하지만이 모드에서 원시 Hive를 사용하는 경우 약간의 비 호환성이 있습니다.val sqlContext = new org.apache.spark.sql.SQLContext(sc)
HiveContext 기능이 필요하지 않은 경우 HiveContext 대신 원시 를 사용하십시오 .git clone https://github.com/dennishuo/spark
./make-distribution.sh --name my-custom-spark --tgz --skip-java-test -Pyarn -Phadoop-2.6 -Dhadoop.version=2.6.0 -Phive -Phive-thriftserver
bdutil에서 지정할 수있는 새로운 tarball을 얻기 위해 실행 합니다 spark_env.sh
.긴 답변
우리는 단지 매니페스트 것을 확인했습니다 fs.default.name
그리고 fs.defaultFS
A와 설정 gs://
에 관계없이에서 경로를로드하려고 여부의 경로 parquetFile("gs://...")
나 parquetFile("hdfs://...")
, 때 fs.default.name
와 fs.defaultFS
HDFS 경로로 설정되어, 모두 HDFS에서와 GCS에서 데이터를로드 잘 작동합니다. 이것은 현재 Spark 1.4 이상에만 해당되며 Spark 1.3.1 이전 버전에는 없습니다.
회귀는 https://github.com/apache/spark/commit/9ac8393663d759860c67799e000ec072ced76493 에 도입 된 것으로 보이며 실제로 이전 관련 클래스 로딩 문제인 SPARK-8368을 수정합니다 . 수정 자체는 일반적인 경우에 맞지만 사용할 클래스 로더를 결정하는 데 사용되는 IsolatedClientLoader.isSharedClass 메소드 가 있으며 앞서 언급 한 커밋과 상호 작용하여 GoogleHadoopFileSystem 클래스 로딩을 중단합니다.
해당 파일의 다음 줄에는 com.google.*
Guava 및 실제로 공유 라이브러리로로드되는 protobuf 종속성으로 인해 "공유 클래스" 아래 에있는 모든 항목이 포함되어 있지만 안타깝게도 GoogleHadoopFileSystem은이 경우에서와 같이 "하이브 클래스"로로드되어야합니다 org.apache.hadoop.hdfs.DistributedFileSystem
. 우리는 불행하게도 com.google.*
패키지 네임 스페이스를 공유합니다 .
protected def isSharedClass(name: String): Boolean =
name.contains("slf4j") ||
name.contains("log4j") ||
name.startsWith("org.apache.spark.") ||
name.startsWith("scala.") ||
name.startsWith("com.google") ||
name.startsWith("java.lang.") ||
name.startsWith("java.net") ||
sharedPrefixes.exists(name.startsWith)
...
/** The classloader that is used to load an isolated version of Hive. */
protected val classLoader: ClassLoader = new URLClassLoader(allJars, rootClassLoader) {
override def loadClass(name: String, resolve: Boolean): Class[_] = {
val loaded = findLoadedClass(name)
if (loaded == null) doLoadClass(name, resolve) else loaded
}
def doLoadClass(name: String, resolve: Boolean): Class[_] = {
...
} else if (!isSharedClass(name)) {
logDebug(s"hive class: $name - ${getResource(classToPath(name))}")
super.loadClass(name, resolve)
} else {
// For shared classes, we delegate to baseClassLoader.
logDebug(s"shared class: $name")
baseClassLoader.loadClass(name)
}
}
}
다음 행을 추가하여 확인할 수 있습니다 ${SPARK_INSTALL}/conf/log4j.properties
.
log4j.logger.org.apache.spark.sql.hive.client=DEBUG
출력 결과는 다음과 같습니다.
...
15/07/20 20:59:14 DEBUG IsolatedClientLoader: hive class: org.apache.hadoop.hdfs.DistributedFileSystem - jar:file:/home/hadoop/spark-install/lib/spark-assembly-1.4.1-hadoop2.6.0.jar!/org/apache/hadoop/hdfs/DistributedFileSystem.class
...
15/07/20 20:59:14 DEBUG IsolatedClientLoader: shared class: com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem
java.lang.RuntimeException: java.lang.ClassCastException: com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem cannot be cast to org.apache.hadoop.fs.FileSystem
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다