Aplikasi Spark sering kali bergantung pada library Java atau Scala pihak ketiga. Berikut adalah pendekatan yang direkomendasikan untuk menyertakan dependensi ini saat Anda mengirimkan tugas Spark ke cluster Dataproc:
Saat mengirimkan tugas dari komputer lokal dengan perintah
gcloud dataproc jobs submit
, gunakan flag--properties spark.jars.packages=[DEPENDENCIES]
.
Contoh:gcloud dataproc jobs submit spark \ --cluster=my-cluster \ --region=region \ --properties=spark.jars.packages='com.google.cloud:google-cloud-translate:1.35.0,org.apache.bahir:spark-streaming-pubsub_2.11:2.2.0'
Saat mengirim tugas langsung di cluster Anda, gunakan perintah
spark-submit
dengan parameter--packages=[DEPENDENCIES]
.
Contoh:spark-submit --packages='com.google.cloud:google-cloud-translate:1.35.0,org.apache.bahir:spark-streaming-pubsub_2.11:2.2.0'
Menghindari konflik dependensi
Pendekatan di atas dapat gagal jika dependensi aplikasi Spark bertentangan dengan dependensi Hadoop. Konflik ini dapat muncul karena Hadoop memasukkan dependensinya ke dalam classpath aplikasi, sehingga dependensinya lebih diutamakan daripada dependensi aplikasi. Saat terjadi konflik, NoSuchMethodError
atau error lainnya
dapat dihasilkan.
Contoh:
Guava
adalah library inti Google untuk Java yang digunakan oleh banyak library dan framework, termasuk
Hadoop. Konflik dependensi dapat terjadi jika tugas atau dependensinya memerlukan
versi Guava yang lebih baru dari yang digunakan oleh Hadoop.
Hadoop v3.0 menyelesaikan masalah ini , tetapi aplikasi yang mengandalkan versi Hadoop sebelumnya memerlukan solusi dua bagian berikut untuk menghindari kemungkinan konflik dependensi.
- Buat satu JAR yang berisi paket aplikasi dan semua dependensinya.
- Pindahkan paket dependensi yang bertentangan dalam JAR uber untuk mencegah nama jalurnya bertentangan dengan paket dependensi Hadoop. Daripada mengubah kode, gunakan plugin (lihat di bawah) untuk secara otomatis melakukan relokasi ini (alias "shading") sebagai bagian dari proses pengemasan.
Membuat JAR uber yang diarsir dengan Maven
Maven adalah alat pengelolaan paket untuk mem-build aplikasi Java. Plugin Maven scala dapat digunakan untuk mem-build aplikasi yang ditulis dalam Scala, bahasa yang digunakan oleh aplikasi Spark. Plugin Maven shade dapat digunakan untuk membuat JAR yang terinkorporasi.
Berikut adalah contoh file konfigurasi pom.xml
yang mewarnai library Guava, yang terletak dalam paket com.google.common
. Konfigurasi ini
menginstruksikan Maven untuk mengganti nama paket com.google.common
menjadi
repackaged.com.google.common
dan memperbarui semua referensi ke
class dari paket asli.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <groupId><!-- YOUR_GROUP_ID --></groupId> <artifactId><!-- YOUR_ARTIFACT_ID --></artifactId> <version><!-- YOUR_PACKAGE_VERSION --></version> <dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version><!-- YOUR_SPARK_VERSION --></version> <scope>provided</scope> </dependency> <!-- YOUR_DEPENDENCIES --> </dependencies> <build> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <scalaVersion><!-- YOUR_SCALA_VERSION --></scalaVersion> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass><!-- YOUR_APPLICATION_MAIN_CLASS --></mainClass> </transformer> <!-- This is needed if you have dependencies that use Service Loader. Most Google Cloud client libraries do. --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/maven/**</exclude> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <relocations> <relocation> <pattern>com</pattern> <shadedPattern>repackaged.com.google.common</shadedPattern> <includes> <include>com.google.common.**</include> </includes> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Untuk menjalankan build:
mvn package
Catatan tentang pom.xml
:
- ManifestResourceTransformer
memproses atribut dalam file manifes JAR uber (
MANIFEST.MF
). Manifes juga dapat menentukan titik entri untuk aplikasi Anda. - Cakupan Spark adalah
provided
, karena Spark diinstal di Dataproc. - Tentukan versi Spark yang diinstal di cluster Dataproc Anda (lihat Daftar Versi Dataproc). Jika aplikasi Anda memerlukan versi Spark yang berbeda dengan versi yang diinstal di cluster Dataproc, Anda dapat menulis tindakan inisialisasi atau membuat image kustom yang menginstal versi Spark yang digunakan oleh aplikasi Anda.
- Entri
<filters>
mengecualikan file tanda tangan dari direktoriMETA-INF
dependensi Anda. Tanpa entri ini, pengecualian waktu prosesjava.lang.SecurityException: Invalid signature file digest for Manifest main attributes
dapat terjadi karena file tanda tangan tidak valid dalam konteks JAR uber Anda. - Anda mungkin perlu menandai beberapa library. Untuk melakukannya, sertakan beberapa jalur.
Contoh berikutnya akan mewarnai library Guava dan Protobuf.
<relocation> <pattern>com</pattern> <shadedPattern>repackaged.com</shadedPattern> <includes> <include>com.google.protobuf.**</include> <include>com.google.common.**</include> </includes> </relocation>
Membuat JAR uber yang diarsir dengan SBT
SBT adalah alat untuk mem-build aplikasi Scala. Untuk membuat JAR yang diarsir dengan SBT,
tambahkan plugin sbt-assembly
ke definisi build Anda, pertama-tama dengan membuat file bernama assembly.sbt
di direktori project/
:
├── src/ └── build.sbt └── project/ └── assembly.sbt
... lalu dengan menambahkan baris berikut di assembly.sbt
:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
Berikut adalah contoh file konfigurasi build.sbt
yang mewarnai library
Guava, yang terletak di com.google.common package
:
lazy val commonSettings = Seq( organization := "YOUR_GROUP_ID", name := "YOUR_ARTIFACT_ID", version := "YOUR_PACKAGE_VERSION", scalaVersion := "YOUR_SCALA_VERSION", ) lazy val shaded = (project in file(".")) .settings(commonSettings) mainClass in (Compile, packageBin) := Some("YOUR_APPLICATION_MAIN_CLASS") libraryDependencies ++= Seq( "org.apache.spark" % "spark-sql_2.11" % "YOUR_SPARK_VERSION" % "provided", // YOUR_DEPENDENCIES ) assemblyShadeRules in assembly := Seq( ShadeRule.rename("com.google.common.**" -> "repackaged.com.google.common.@1").inAll )
Untuk menjalankan build:
sbt assembly
Catatan tentang build.sbt
:
- Aturan shade dalam contoh di atas mungkin tidak menyelesaikan semua konflik
dependensi karena SBT menggunakan strategi penyelesaian konflik yang ketat. Oleh karena itu,
Anda mungkin perlu memberikan aturan yang lebih terperinci yang secara eksplisit menggabungkan jenis
file tertentu yang bertentangan menggunakan strategi
MergeStrategy.first
,last
,concat
,filterDistinctLines
,rename
, ataudiscard
. Lihat strategi penggabungansbt-assembly
untuk mengetahui detail selengkapnya. - Anda mungkin perlu menandai beberapa library. Untuk melakukannya, sertakan beberapa jalur.
Contoh berikutnya akan mewarnai library Guava dan Protobuf.
assemblyShadeRules in assembly := Seq( ShadeRule.rename("com.google.common.**" -> "repackaged.com.google.common.@1").inAll, ShadeRule.rename("com.google.protobuf.**" -> "repackaged.com.google.protobuf.@1").inAll )
Mengirimkan JAR uber ke Dataproc
Setelah membuat JAR uber yang diarsir yang berisi aplikasi Spark dan dependensinya, Anda siap untuk mengirimkan tugas ke Dataproc.
Langkah selanjutnya
- Lihat spark-translate, contoh aplikasi Spark yang berisi file konfigurasi untuk Maven dan SBT.
- Menulis dan menjalankan tugas Spark Scala di Dataproc. Mulai cepat untuk mempelajari cara menulis dan menjalankan tugas Spark Scala di cluster Dataproc.