YARN da Sparkni sozlash

Xabr, salom! Kecha Apache Spark ga bag'ishlangan uchrashuv, Rambler&Co yigitlaridan ushbu vositani sozlash bo'yicha ishtirokchilardan juda ko'p savollar bo'ldi. Biz uning izidan borib, tajribamiz bilan o‘rtoqlashishga qaror qildik. Mavzu oson emas - shuning uchun biz sizni sharhlarda tajribangizni baham ko'rishni taklif qilamiz, ehtimol biz ham noto'g'ri narsani tushunamiz va foydalanamiz.

Sparkdan qanday foydalanishimiz haqida bir oz tanishish. Bizda uch oylik dastur bor "Katta ma'lumotlar bo'yicha mutaxassis", va ikkinchi modul davomida ishtirokchilarimiz ushbu asbob ustida ishlashadi. Shunga ko'ra, tashkilotchilar sifatida bizning vazifamiz klasterni bunday holatda foydalanishga tayyorlashdir.

Bizning foydalanishimizning o'ziga xosligi shundaki, Sparkda bir vaqtning o'zida ishlaydigan odamlar soni butun guruhga teng bo'lishi mumkin. Misol uchun, seminarda hamma bir vaqtning o'zida bir narsani sinab ko'rsa va o'qituvchimizdan keyin takrorlaydi. Va bu juda ko'p emas - ba'zida 40 kishigacha. Dunyoda bunday foydalanish holatlariga duch kelgan kompaniyalar ko'p emas.

Keyinchalik, qanday qilib va ​​nima uchun biz ma'lum konfiguratsiya parametrlarini tanlaganimizni aytaman.

Eng boshidan boshlaylik. Spark-da klasterda ishlash uchun 3 ta variant mavjud: mustaqil, Mesos-dan foydalanish va YARN-dan foydalanish. Biz uchinchi variantni tanlashga qaror qildik, chunki bu biz uchun mantiqiy edi. Bizda allaqachon hadoop klasteri mavjud. Ishtirokchilarimiz allaqachon uning arxitekturasi bilan yaxshi tanish. Keling, YARN dan foydalanamiz.

spark.master=yarn

Yana qiziqroq. Ushbu 3 ta joylashtirish opsiyalarining har biri 2 ta o'rnatish variantiga ega: mijoz va klaster. Asoslangan hujjatlar va Internetdagi turli havolalardan xulosa qilishimiz mumkinki, mijoz interaktiv ish uchun mos keladi - masalan, jupyter notebook orqali va klaster ishlab chiqarish echimlari uchun ko'proq mos keladi. Bizning holatlarimizda biz interaktiv ish bilan qiziqdik, shuning uchun:

spark.deploy-mode=client

Umuman olganda, bundan buyon Spark qandaydir tarzda YARN ustida ishlaydi, ammo bu biz uchun etarli emas edi. Bizda katta ma'lumotlar bo'yicha dastur mavjud bo'lganligi sababli, ba'zida ishtirokchilar resurslarni teng ravishda taqsimlash doirasida olingan narsalarga ega bo'lishmadi. Va keyin biz qiziqarli narsani topdik - dinamik resurslarni taqsimlash. Muxtasar qilib aytganda, gap shundaki: agar sizda qiyin vazifa bo'lsa va klaster bepul bo'lsa (masalan, ertalab), unda ushbu Spark opsiyasidan foydalanish sizga qo'shimcha resurslarni berishi mumkin. U erda zarurat ayyor formula bo'yicha hisoblanadi. Tafsilotlarga kirmaymiz - u yaxshi ishlaydi.

spark.dynamicAllocation.enabled=true

Biz ushbu parametrni o'rnatdik va ishga tushirilganda Spark qulab tushdi va ishga tushmadi. To'g'ri, chunki men uni o'qishim kerak edi hujjatlar ehtiyotkorlik bilan. Unda aytilishicha, hamma narsa yaxshi bo'lishi uchun siz qo'shimcha parametrni ham yoqishingiz kerak.

spark.shuffle.service.enabled=true

Nima uchun kerak? Bizning ishimiz endi ko'p resurslarni talab qilmasa, Spark ularni umumiy hovuzga qaytarishi kerak. Deyarli har qanday MapReduce topshirig'ida eng ko'p vaqt talab qiladigan bosqich bu Aralashtirish bosqichidir. Ushbu parametr ushbu bosqichda yaratilgan ma'lumotlarni saqlash va shunga mos ravishda ijrochilarni chiqarish imkonini beradi. Ijrochi esa ishchi ustidagi hamma narsani hisoblab chiqadigan jarayondir. Unda ma'lum miqdordagi protsessor yadrolari va ma'lum hajmdagi xotira mavjud.

Ushbu parametr qo'shildi. Hammasi ishlayotgandek tuyuldi. Ishtirokchilarga haqiqatan ham kerak bo'lganda ko'proq resurslar berilganligi sezilarli bo'ldi. Ammo yana bir muammo paydo bo'ldi - bir vaqtning o'zida boshqa ishtirokchilar uyg'onib, Spark dan foydalanishni xohlashdi, lekin u erda hamma narsa band edi va ular baxtsiz edi. Ularni tushunish mumkin. Biz hujjatlarni ko'rib chiqishni boshladik. Ma'lum bo'lishicha, siz hali ham jarayonga ta'sir qilishingiz mumkin bo'lgan bir qator parametrlar mavjud. Misol uchun, agar ijrochi kutish rejimida bo'lsa, undan qancha vaqtdan keyin resurslarni olish mumkin?

spark.dynamicAllocation.executorIdleTimeout=120s

Bizning holatda, agar sizning ijrochilaringiz ikki daqiqa davomida hech narsa qilmasa, iltimos, ularni umumiy hovuzga qaytaring. Ammo bu parametr har doim ham etarli emas edi. Bu odam uzoq vaqtdan beri hech narsa qilmayotgani va resurslar bo'shatilmayotgani aniq edi. Ma'lum bo'lishicha, maxsus parametr ham bor - keshlangan ma'lumotlarni o'z ichiga olgan ijrochilarni qaysi vaqtdan keyin tanlash kerak. Odatiy bo'lib, bu parametr cheksizlik edi! Biz uni tuzatdik.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Ya'ni, agar sizning ijrochilaringiz 5 daqiqa davomida hech narsa qilmasa, ularni umumiy hovuzga bering. Ushbu rejimda ko'p sonli foydalanuvchilar uchun resurslarni chiqarish va chiqarish tezligi munosib bo'ldi. Norozilik darajasi kamaydi. Ammo biz oldinga borishga qaror qildik va har bir dastur uchun ijrochilarning maksimal sonini chekladik - asosan dastur ishtirokchisiga.

spark.dynamicAllocation.maxExecutors=19

Endi, albatta, boshqa tomonda norozi odamlar bor - "klaster ishlamayapti, menda atigi 19 nafar ijrochi bor", lekin nima qila olasiz? Bizga qandaydir to'g'ri muvozanat kerak. Hammani baxtli qila olmaysiz.

Va bizning ishimizning o'ziga xos xususiyatlari bilan bog'liq yana bir kichik hikoya. Negadir bir necha kishi amaliy darsga kechikib qolishdi va negadir ular uchun Spark boshlanmadi. Biz bepul resurslar miqdorini ko'rib chiqdik - u erda bo'lganga o'xshaydi. Uchqun boshlanishi kerak. Yaxshiyamki, o'sha vaqtga kelib, hujjatlar subkorteksga allaqachon qo'shilgan edi va biz Spark ishga tushirilganda boshlash uchun portni qidirayotganini esladik. Agar diapazondagi birinchi port band bo'lsa, u navbatdagisiga o'tadi. Agar u bepul bo'lsa, u qo'lga kiritadi. Va buning uchun maksimal urinishlar sonini ko'rsatadigan parametr mavjud. Odatiy - 16. Bu raqam guruhimizdagi sinfdagi odamlar sonidan kamroq. Shunga ko'ra, 16 urinishdan so'ng, Spark taslim bo'ldi va men boshlay olmasligimni aytdi. Biz ushbu parametrni tuzatdik.

spark.port.maxRetries=50

Keyinchalik men sizga ishimizning o'ziga xos xususiyatlariga unchalik bog'liq bo'lmagan ba'zi sozlamalar haqida gapirib beraman.

Spark-ni tezroq ishga tushirish uchun SPARK_HOME uy katalogida joylashgan jars jildini arxivlash va HDFS-ga joylashtirish tavsiya etiladi. Shunda u bu jarniklarni ishchilar yuklash uchun vaqt sarflamaydi.

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

Bundan tashqari, tezroq ishlash uchun kryo-dan serializator sifatida foydalanish tavsiya etiladi. U standartga qaraganda ko'proq optimallashtirilgan.

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

Bundan tashqari, Spark bilan uzoq vaqtdan beri muammo bor, u tez-tez xotiradan ishdan chiqadi. Ko'pincha bu ishchilar hamma narsani hisoblab chiqqan va natijani haydovchiga yuborgan paytda sodir bo'ladi. Biz ushbu parametrni o'zimiz uchun kattaroq qildik. Odatiy bo'lib, u 1 GB, biz uni 3 ga aylantirdik.

spark.driver.maxResultSize=3072

Va nihoyat, shirinlik sifatida. HortonWorks tarqatishda Spark-ni 2.1 versiyasiga qanday yangilash mumkin - HDP 2.5.3.0. HDP ning ushbu versiyasi oldindan o'rnatilgan 2.0 versiyasini o'z ichiga oladi, lekin biz bir marta o'zimiz uchun qaror qildikki, Spark juda faol rivojlanmoqda va har bir yangi versiya ba'zi xatolarni tuzatadi va qo'shimcha funktsiyalarni, shu jumladan python API uchun ham taqdim etadi, shuning uchun nima qilish kerakligini hal qildik. bajarilishi yangilanishdir.

Hadoop 2.7 uchun rasmiy veb-saytdan versiya yuklab olindi. Uni oching va HDP jildiga qo'ying. Biz symlinksni kerak bo'lganda o'rnatdik. Biz uni ishga tushiramiz - u boshlamaydi. Juda noaniq xato yozadi.

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

Googlingdan so'ng biz Spark Hadoop tug'ilguncha kutmaslikka qaror qilganini va trikotajning yangi versiyasidan foydalanishga qaror qilganini bilib oldik. Ularning o'zlari JIRAda bu mavzuda bir-biri bilan bahslashadilar. Yechim yuklab olish edi jersey versiyasi 1.17.1. Buni SPARK_HOME-dagi jars jildiga joylashtiring, uni qaytadan ziplang va HDFS-ga yuklang.

Biz bu xatoni hal qildik, ammo yangi va ancha soddalashtirilgan xato paydo bo'ldi.

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

Shu bilan birga, biz 2.0 versiyasini ishga tushirishga harakat qilamiz - hamma narsa yaxshi. Nima bo'layotganini taxmin qilishga harakat qiling. Biz ushbu ilovaning jurnallarini ko'rib chiqdik va shunga o'xshash narsani ko'rdik:

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

Umuman olganda, negadir hdp.version hal qilinmadi. Googlingdan so'ng biz yechim topdik. Siz Ambari-da YARN sozlamalariga o'tishingiz va u erda maxsus ip-saytga parametr qo'shishingiz kerak:

hdp.version=2.5.3.0-37

Bu sehr yordam berdi va Spark uchib ketdi. Biz bir nechta jupyter noutbuklarimizni sinab ko'rdik. Hammasi ishlayapti. Shanba kuni (ertaga) birinchi Spark darsiga tayyormiz!

DUP. Dars davomida yana bir muammo yuzaga keldi. Bir nuqtada YARN Spark uchun konteynerlar berishni to'xtatdi. YARN-da sukut bo'yicha 0.2 bo'lgan parametrni tuzatish kerak edi:

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

Ya'ni, resurslarni taqsimlashda faqat 20% resurslar ishtirok etgan. Parametrlarni o'zgartirgandan so'ng biz YARNni qayta yukladik. Muammo hal qilindi va qolgan ishtirokchilar ham uchqun kontekstini ishga tushirishga muvaffaq bo'lishdi.

Manba: www.habr.com

a Izoh qo'shish