Mengonfigurasi Spark pada YARN

Habr, halo! Kemarin pada pertemuan yang didedikasikan untuk Apache Spark, dari teman-teman Rambler&Co cukup banyak pertanyaan dari peserta terkait konfigurasi alat ini. Kami memutuskan untuk mengikuti jejaknya dan berbagi pengalaman kami. Topiknya tidak mudah - jadi kami mengundang Anda untuk berbagi pengalaman Anda di komentar, mungkin kami juga memahami dan menggunakan sesuatu yang salah.

Sedikit pengenalan tentang cara kami menggunakan Spark. Kami memiliki program tiga bulan “Spesialis Data Besar”, dan sepanjang modul kedua peserta kami mengerjakan instrumen ini. Oleh karena itu, tugas kami sebagai penyelenggara adalah mempersiapkan cluster untuk digunakan dalam kasus seperti itu.

Keunikan penggunaan kami adalah jumlah orang yang mengerjakan Spark secara bersamaan bisa sama dengan seluruh grup. Misalnya, di sebuah seminar, ketika semua orang mencoba sesuatu pada saat yang sama dan mengulanginya setelah guru kita. Dan ini tidak banyak - terkadang hingga 40 orang. Mungkin tidak banyak perusahaan di dunia yang menghadapi kasus penggunaan seperti itu.

Selanjutnya, saya akan memberi tahu Anda bagaimana dan mengapa kami memilih parameter konfigurasi tertentu.

Mari kita mulai dari awal. Spark memiliki 3 opsi untuk dijalankan di cluster: mandiri, menggunakan Mesos, dan menggunakan YARN. Kami memutuskan untuk memilih opsi ketiga karena masuk akal bagi kami. Kami sudah memiliki cluster hadoop. Peserta kami sudah mengenal arsitekturnya dengan baik. Ayo gunakan BENANG.

spark.master=yarn

Lebih jauh lagi lebih menarik. Masing-masing dari 3 opsi penerapan ini memiliki 2 opsi penerapan: klien dan kluster. Berdasarkan dokumentasi dan berbagai tautan di Internet, kita dapat menyimpulkan bahwa klien cocok untuk pekerjaan interaktif - misalnya, melalui notebook jupyter, dan cluster lebih cocok untuk solusi produksi. Dalam kasus kami, kami tertarik pada pekerjaan interaktif, oleh karena itu:

spark.deploy-mode=client

Secara umum, mulai sekarang Spark akan bekerja pada YARN, tetapi ini tidak cukup bagi kami. Karena kami memiliki program tentang data besar, terkadang para peserta tidak memiliki cukup informasi yang diperoleh dalam kerangka pembagian sumber daya yang merata. Dan kemudian kami menemukan hal yang menarik - alokasi sumber daya dinamis. Singkatnya, intinya adalah ini: jika Anda memiliki tugas yang sulit dan cluster bebas (misalnya, di pagi hari), menggunakan opsi ini Spark dapat memberi Anda sumber daya tambahan. Kebutuhan dihitung di sana menurut rumus yang licik. Kami tidak akan menjelaskan secara detail - ini berfungsi dengan baik.

spark.dynamicAllocation.enabled=true

Kami menetapkan parameter ini, dan saat startup, Spark mogok dan tidak dapat dijalankan. Itu benar, karena saya harus membacanya dokumentasi lebih berhati-hati. Dinyatakan bahwa agar semuanya baik-baik saja, Anda juga perlu mengaktifkan parameter tambahan.

spark.shuffle.service.enabled=true

Mengapa itu diperlukan? Ketika pekerjaan kita tidak lagi membutuhkan begitu banyak sumber daya, Spark harus mengembalikannya ke kumpulan umum. Tahapan yang paling memakan waktu di hampir semua tugas MapReduce adalah tahap Shuffle. Parameter ini memungkinkan Anda untuk menyimpan data yang dihasilkan pada tahap ini dan melepaskan eksekutor yang sesuai. Dan eksekutor adalah proses yang menghitung segala sesuatu pada pekerja. Ia memiliki sejumlah inti prosesor dan sejumlah memori tertentu.

Parameter ini telah ditambahkan. Segalanya tampak berhasil. Terlihat jelas bahwa para peserta sebenarnya diberi lebih banyak sumber daya ketika mereka membutuhkannya. Namun masalah lain muncul - pada titik tertentu peserta lain terbangun dan juga ingin menggunakan Spark, tetapi semuanya sibuk di sana, dan mereka tidak senang. Itu bisa dimengerti. Kami mulai melihat dokumentasinya. Ternyata ada sejumlah parameter lain yang bisa digunakan untuk mempengaruhi proses tersebut. Misalnya, jika pelaksana dalam mode siaga, setelah jam berapa sumber daya dapat diambil darinya?

spark.dynamicAllocation.executorIdleTimeout=120s

Dalam kasus kami, jika pelaksana Anda tidak melakukan apa pun selama dua menit, silakan kembalikan mereka ke kolam umum. Namun parameter ini tidak selalu cukup. Jelas bahwa orang tersebut sudah lama tidak melakukan apa pun, dan sumber daya tidak tersedia. Ternyata ada juga parameter khusus - setelah jam berapa memilih pelaksana yang berisi data cache. Secara default, parameter ini tak terhingga! Kami memperbaikinya.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Artinya, jika eksekutor Anda tidak melakukan apa pun selama 5 menit, berikan mereka ke pool umum. Dalam mode ini, kecepatan melepaskan dan mengeluarkan sumber daya untuk sejumlah besar pengguna menjadi lumayan. Jumlah ketidakpuasan telah berkurang. Namun kami memutuskan untuk melangkah lebih jauh dan membatasi jumlah maksimum pelaksana per aplikasi - pada dasarnya per peserta program.

spark.dynamicAllocation.maxExecutors=19

Sekarang, tentu saja, ada orang-orang yang tidak puas di sisi lain - “klasternya menganggur, dan saya hanya punya 19 pelaksana,” tapi apa yang bisa Anda lakukan? Kita memerlukan semacam keseimbangan yang tepat. Anda tidak bisa membuat semua orang bahagia.

Dan satu lagi cerita kecil terkait dengan spesifik kasus kami. Entah bagaimana, beberapa orang terlambat mengikuti pelajaran praktik, dan karena alasan tertentu Spark tidak memulai untuk mereka. Kami melihat jumlah sumber daya gratis - tampaknya memang ada. Percikan harus dimulai. Untungnya, pada saat itu dokumentasi telah ditambahkan ke subkorteks di suatu tempat, dan kami ingat bahwa ketika diluncurkan, Spark mencari port untuk memulai. Jika port pertama dalam rentang tersebut sibuk, port tersebut berpindah ke port berikutnya secara berurutan. Jika gratis, ia menangkap. Dan ada parameter yang menunjukkan jumlah upaya maksimum untuk ini. Standarnya adalah 16. Jumlah tersebut kurang dari jumlah orang dalam kelompok kita di kelas. Oleh karena itu, setelah 16 kali mencoba, Spark menyerah dan berkata bahwa saya tidak dapat memulai. Kami telah memperbaiki pengaturan ini.

spark.port.maxRetries=50

Selanjutnya saya akan memberi tahu Anda tentang beberapa pengaturan yang tidak terlalu terkait dengan kasus kami secara spesifik.

Untuk memulai Spark lebih cepat, disarankan untuk mengarsipkan folder jars yang terletak di direktori home SPARK_HOME dan meletakkannya di HDFS. Maka dia tidak akan membuang waktu untuk memuat jarnik tersebut oleh para pekerja.

spark.yarn.archive=hdfs:///tmp/spark-archive.zip

Disarankan juga untuk menggunakan kryo sebagai serializer untuk pengoperasian yang lebih cepat. Ini lebih optimal daripada yang default.

spark.serializer=org.apache.spark.serializer.KryoSerializer

Dan ada juga masalah lama dengan Spark yang sering crash dari memori. Seringkali hal ini terjadi pada saat para pekerja sudah menghitung semuanya dan mengirimkan hasilnya kepada pengemudi. Kami membuat parameter ini lebih besar untuk diri kami sendiri. Secara default, ini adalah 1GB, kami membuatnya menjadi 3.

spark.driver.maxResultSize=3072

Dan yang terakhir, sebagai hidangan penutup. Cara memperbarui Spark ke versi 2.1 pada distribusi HortonWorks - HDP 2.5.3.0. Versi HDP ini berisi versi 2.0 yang sudah diinstal sebelumnya, tetapi kami pernah memutuskan sendiri bahwa Spark berkembang cukup aktif, dan setiap versi baru memperbaiki beberapa bug plus menyediakan fitur tambahan, termasuk untuk API python, jadi kami memutuskan, apa yang perlu dilakukan adalah pembaruan.

Mengunduh versi dari situs resmi untuk Hadoop 2.7. Buka ritsletingnya dan masukkan ke dalam folder HDP. Kami menginstal symlink sesuai kebutuhan. Kami meluncurkannya - itu tidak dimulai. Menulis kesalahan yang sangat tidak jelas.

java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig

Setelah googling, kami mengetahui bahwa Spark memutuskan untuk tidak menunggu hingga Hadoop lahir, dan memutuskan untuk menggunakan jersey versi baru. Mereka sendiri saling berdebat tentang topik ini di JIRA. Solusinya adalah mengunduh jersey versi 1.17.1. Tempatkan ini di folder jars di SPARK_HOME, zip lagi dan unggah ke HDFS.

Kami berhasil mengatasi kesalahan ini, namun kesalahan baru dan lebih sederhana muncul.

org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master

Pada saat yang sama, kami mencoba menjalankan versi 2.0 - semuanya baik-baik saja. Coba tebak apa yang terjadi. Kami melihat log aplikasi ini dan melihat sesuatu seperti ini:

/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar

Secara umum, karena alasan tertentu hdp.version tidak terselesaikan. Setelah googling, kami menemukan solusinya. Anda harus pergi ke pengaturan BENANG di Ambari dan menambahkan parameter di sana ke situs benang khusus:

hdp.version=2.5.3.0-37

Sihir ini membantu, dan Spark pun lepas landas. Kami menguji beberapa laptop jupyter kami. Semuanya berfungsi. Kami siap untuk pelajaran Spark pertama pada hari Sabtu (besok)!

DUP. Selama pembelajaran, masalah lain terungkap. Pada titik tertentu, YARN berhenti menyediakan wadah untuk Spark. Di YARN perlu untuk memperbaiki parameter, yang secara default adalah 0.2:

yarn.scheduler.capacity.maximum-am-resource-percent=0.8

Artinya, hanya 20% sumber daya yang berpartisipasi dalam pendistribusian sumber daya. Setelah mengubah parameter, kami memuat ulang BENANG. Masalahnya terselesaikan dan peserta lainnya juga dapat menjalankan konteks percikan.

Sumber: www.habr.com

Tambah komentar