Apache Spark: Çekirdek sayısı ve uygulayıcı sayısı


194

YARN'de bir Spark işi çalıştırırken çekirdek sayısının ve uygulayıcı sayısının ilişkisini anlamaya çalışıyorum.

Test ortamı aşağıdaki gibidir:

  • Veri düğümü sayısı: 3
  • Veri düğümü makine özellikleri:
    • İşlemci: Core i7-4790 (çekirdek sayısı: 4, iplik sayısı: 8)
    • Rastgele erişimli hafıza: 32GB (8GB x 4)
    • HDD: 8 TB (2 TB x 4)
  • Ağ: 1Gb

  • Kıvılcım sürümü: 1.0.0

  • Hadoop sürümü: 2.4.0 (Hortonworks HDP 2.1)

  • Spark iş akışı: sc.textFile -> filtre -> harita -> filtre -> mapToPair -> reduceByKey -> harita -> saveAsTextFile

  • Veri girişi

    • Tür: tek metin dosyası
    • Boyut: 165GB
    • Satır sayısı: 454,568,833
  • Çıktı

    • İkinci filtreden sonraki hat sayısı: 310.640.717
    • Sonuç dosyasının satır sayısı: 99,848,268
    • Sonuç dosyasının boyutu: 41GB

İş, aşağıdaki yapılandırmalarla gerçekleştirildi:

  1. --master yarn-client --executor-memory 19G --executor-cores 7 --num-executors 3 (veri düğümü başına yürütücüler, çekirdekler kadar kullanın)

  2. --master yarn-client --executor-memory 19G --executor-cores 4 --num-executors 3 (çekirdek sayısı azaltıldı)

  3. --master yarn-client --executor-memory 4G --executor-cores 2 --num-executors 12 (daha az çekirdek, daha fazla yürütücü)

Geçen süreler:

  1. 50 dk 15 sn

  2. 55 dk 48 sn

  3. 31 dk 23 sn

Şaşırtıcı bir şekilde, (3) çok daha hızlıydı.
(1) 'in daha hızlı olacağını düşündüm, çünkü karıştırma sırasında daha az uygulayıcılar arası iletişim olacaktı.
(1) 'in çekirdeklerinin sayısı (3)' ten daha az olsa da, 2) 'den bu yana çekirdeklerin sayısı anahtar faktör değildir.

(Pwilmot'un cevabından sonra arkadaşlar eklendi.)

Bilgi için performans monitörü ekran görüntüsü aşağıdaki gibidir:

  • (1) için Ganglia veri düğümü özeti - iş 04:37 'de başladı.

İçin Ganglia veri düğümü özeti (1)

  • (3) için Ganglia veri düğümü özeti - iş 19:47'de başladı. Lütfen o zamandan önce grafiği görmezden gelin.

İçin Ganglia veri düğümü özeti (3)

Grafik kabaca 2 bölüme ayrılmıştır:

  • İlk: baştan sona azaltmak: ByKey: Yoğun CPU, ağ etkinliği yok
  • İkincisi: reduceByKey'den sonra: CPU alçalır, ağ G / Ç yapılır.

Grafikte görüldüğü gibi, (1) verildiği kadar CPU gücü kullanabilir. Bu nedenle, iş parçacığı sayısının sorunu olmayabilir.

Bu sonuç nasıl açıklanır?


2
Şimdi GC'den şüpheleniyorum ... Aslında, Spark UI'de GC için harcanan toplam süre 1) 2'den daha uzun).
14:04

Neden 3) 19G ile denemediniz? İşçileri 4G ile sınırlamak, bazı insanların puanlarının NUMA etkisini azaltması olabilir mi? yani 4G'niz iş akışınıza tahsis edilen 2 çekirdekten birinde bulunur ve bu nedenle daha az g / Ç yavaşlaması olur ve bu da daha iyi genel performans sağlar. Aksi takdirde ana soru şudur: Bir çekirdek üzerinde tek bir yürütücü kaç tane çekirdek / iş parçacığı kullanabilir? (Bir kişi sadece bir çalışan için toplam çekirdek sayısını belirtebilir, uygulayıcının ayrıntı düzeyinde değil)
Bacon

5
Btw Ben sadece core / src / main / scala / org / apache / spark / deploy / worker / ExecutorRunner.scala adresindeki kodu kontrol ettim ve 1 executor = 1 işçi iş parçacığı gibi görünüyor.
Bacon

biraz geç ama işte bu konuda cloudera hakkında bir yazı: blog.cloudera.com/blog/2015/03/…
Orelus

1
Bu arada, bu bilgiyi bir cloudera slayt güvertesinde buldum slideshare.net/cloudera/… , bu da uygulayıcılar, çekirdekler ve hafızadaki karar verme sürecini biraz açıklıyor
Manish Sahni

Yanıtlar:


58

Umarım tüm bunları biraz daha somut hale getirmek için, bir Spark uygulamasını mümkün olan en fazla kümeyi kullanacak şekilde yapılandırmanın işlenmiş bir örneği: Her biri 16 çekirdek ve 64 GB bellek ile donatılmış NodeManagers çalıştıran altı düğüme sahip bir küme düşünün . NodeManager kapasiteleri, yarn.nodemanager.resource.memory-mb ve yarn.nodemanager.resource.cpu-vcores, büyük olasılıkla sırasıyla 63 * 1024 = 64512 (megabayt) ve 15 olarak ayarlanmalıdır. Kaynakların% 100'ünü YARN kaplarına tahsis etmekten kaçınırız, çünkü düğümün OS ve Hadoop artalanlarını çalıştırmak için bazı kaynaklara ihtiyacı vardır. Bu durumda, bu sistem süreçleri için bir gigabayt ve bir çekirdek bırakıyoruz. Cloudera Manager bunları hesaplayarak ve bu YARN özelliklerini otomatik olarak yapılandırarak yardımcı olur.

Muhtemelen ilk dürtü --num-executor 6 - executor-cores 15 - executor-memory 63G kullanmak olacaktır . Ancak, bu yanlış bir yaklaşımdır çünkü:

63GB + yürütücü bellek yükü, NodeManagers'ın 63GB kapasitesine sığmaz. Uygulama yöneticisi düğümlerden birinde bir çekirdek alacaktır, yani bu düğümde 15 çekirdekli bir yürütücü için yer kalmayacaktır. Yürütücü başına 15 çekirdek kötü HDFS G / Ç çıkışına yol açabilir.

--Num-execrators 17 --executor-cores 5 - executor-memory 19G kullanmak daha iyi bir seçenek olacaktır . Neden?

Bu yapılandırma, iki yürütücüye sahip olacak AM dışındaki tüm düğümlerde üç yürütücü ile sonuçlanır. - yürütücü-bellek (düğüm başına 63/3 yürütücü) = 21. 21 * 0.07 = 1.47 olarak türetilmiştir. 21-1,47 ~ 19.

Açıklama Cloudera'nın Nasıl Yapılır: Apache Spark İşlerinizi Ayarlayın (Bölüm 2) blogunda bir makalede verildi .


1
Msgstr "Bu yapılandırma, iki yürütücüye sahip olacak AM dışındaki tüm düğümlerde üç yürütücü ile sonuçlanır." Bu "--executor-cores 5" için ne anlama geliyor?
derek

Bu, her uygulayıcının 5 çekirdek kullandığını gösterir. Bu nedenle, düğümlerden biri iş için uygulama yöneticisini çalıştırması dışında her düğümde 3 yürütücü vardır, bu nedenle yalnızca 2 yürütücüyü, yani yürütücü olarak kullanılan 10 çekirdeği barındırabilir.
Davos

Güzel açıkladı - lütfen yarn.scheduler.capacity.resource-calculatorbunun varsayılan olan devre dışı için geçerli olduğunu unutmayın . Bunun nedeni, varsayılan olarak CPU tarafından değil Bellek ile zamanlamasıdır.
YoYo

1
Daha fazla yürütücü kötü HDFS G / Ç çıkışına neden olabilir. Eğer HDFS kullanmıyorsam, bu durumda her yürütücü için 5'ten fazla çekirdek kullanabilir miyim?
Darshan

Uygulama yöneticisi her Düğüm üzerinde çalışıyor olsa da. Yukarıdakilere göre, bu, işi çalıştırmak için sadece 1 Uygulama Yöneticisi'nin olacağı anlamına gelir. Bu doğru mu?
Roshan Fernando

15

Sandy Ryza'ya göre kıvılcım uygulamanızı HDFS üzerinde çalıştırırken

HDFS istemcisinin tonlarca eşzamanlı iş parçacığında sorun yaşadığını fark ettim. Kaba bir tahmin, her yürütücü başına en fazla beş görevin tam yazma hacmine ulaşabileceğidir, bu nedenle yürütücü başına çekirdek sayısını bu sayının altında tutmak iyidir.

Bu yüzden ilk yapılandırmanızın üçüncü yapılandırmadan daha yavaş olduğuna inanıyorum, kötü HDFS I / O verimi


11

Bu ayarlarla kendim oynamadım, bu sadece spekülasyon, ancak bu konuyu dağıtılmış bir sistemdeki normal çekirdekler ve iş parçacıkları olarak düşünürsek, kümenizde 12 çekirdeğe (4 * 3 makine) ve 24 iş parçacığına kadar kullanabilirsiniz. (8 * 3 makine). İlk iki örneğinizde, işinize adil bir sayıda çekirdek (potansiyel hesaplama alanı) veriyorsunuz, ancak bu çekirdeklerde çalıştırılacak iş parçacığı (iş) sayısı o kadar sınırlı ki, tahsis edilen işlem gücünün çoğunu kullanamayacaksınız ve tahsis edilmiş daha fazla hesaplama kaynağı olmasına rağmen iş daha yavaştır.

Endişenizin karıştırma adımında olduğunu belirtiyorsunuz - karıştırma adımındaki ek yükü sınırlamak güzel olsa da, genellikle kümenin paralelleştirilmesini kullanmak çok daha önemlidir. Aşırı durumu düşünün - sıfır karıştırma ile tek bir dişli program.


Cevabınız için teşekkürler. Ama iş parçacığı sayısının ana sorun olmadığını düşünüyorum. İzleme ekran görüntüsünü ekledim. Grafikte gösterildiği gibi, 1) verildiği kadar CPU gücü kullanabilir.
zeodtr

1
@zeodtr pwilmot doğru - çekirdeklerinizin tüm potansiyelini kullanabilmek için MINIMUM 2-4 göreve ihtiyacınız var. Şunu koy - 80 çekirdek kümem için genellikle en az 1000 bölüm kullanıyorum.
samthebest

@samthebest Bilmek istediğim, 1) ve 3) arasındaki performans farkının sebebidir. Spark kullanıcı arayüzünü izlediğimde, her ikisi de bölüm 2'de 21 görevi paralel olarak çalıştırır (3 durumunda 24 yerine 21 yerine neden bilinmemektedir) Ancak, 3 için görevler daha hızlı çalışır.
zeodtr

10

Kısa cevap : Bence tgbaggio haklı. İcracılarınızda HDFS işlem sınırlarına ulaştınız.

Buradaki cevabın, buradaki bazı önerilerden biraz daha basit olabileceğini düşünüyorum.

Benim için ipucu küme ağı grafiğinde. Çalışma 1 için, kullanım ~ 50 M bayt / s'de sabittir. 3. çalışma için sabit kullanım iki katına çıkar, yaklaşık 100 M bayt / s.

Gönderen cloudera blog post tarafından paylaşılan DzOrd , bu önemli teklifi görebilirsiniz:

HDFS istemcisinin tonlarca eşzamanlı iş parçacığında sorun yaşadığını fark ettim. Kaba bir tahmin, her yürütücü başına en fazla beş görevin tam yazma hacmine erişebilmesidir, bu nedenle yürütücü başına çekirdek sayısını bu sayının altında tutmak iyidir.

Şimdi, birkaç hesaplama yapalım, eğer bu doğruysa hangi performansı beklediğimizi görelim.


Yarış 1: 19 GB, 7 çekirdek, 3 uygulayıcı

  • 3 uygulayıcı x 7 konu = 21 konu
  • yürütücü başına 7 çekirdek ile, sınırlı IO - HDFS bekliyoruz (~ 5 çekirdekte maksimum çıkış)
  • etkili iş hacmi ~ = 3 uygulayıcı x 5 iş parçacığı = 15 iş parçacığı

Yarış 3: 4 GB, 2 çekirdek, 12 uygulayıcı

  • 2 uygulayıcı x 12 konu = 24 konu
  • Her yürütücü için 2 çekirdek, bu nedenle hdfs verimi tamam
  • etkili iş hacmi ~ = 12 uygulayıcı x 2 iş parçacığı = 24 iş parçacığı

İş, eşzamanlılık (iş parçacığı sayısı) ile% 100 sınırlıysa. Çalışma zamanının iş parçacığı sayısı ile mükemmel bir şekilde ters orantılı olmasını bekleriz.

ratio_num_threads = nthread_job1 / nthread_job3 = 15/24 = 0.625
inv_ratio_runtime = 1/(duration_job1 / duration_job3) = 1/(50/31) = 31/50 = 0.62

Yani ratio_num_threads ~= inv_ratio_runtime, ağ sınırlıyız gibi görünüyor.

Bu aynı etki, Çalışma 1 ile Çalışma 2 arasındaki farkı açıklar.


Yarış 2: 19 GB, 4 çekirdek, 3 uygulayıcı

  • 3 uygulayıcı x 4 iş parçacığı = 12 iş parçacığı
  • yürütücü başına 4 çekirdek ile, tamam IO - HDFS
  • etkili iş hacmi ~ = 3 uygulayıcı x 4 iş parçacığı = 12 iş parçacığı

Etkili iş parçacığı sayısını ve çalışma zamanını karşılaştırma:

ratio_num_threads = nthread_job2 / nthread_job1 = 12/15 = 0.8
inv_ratio_runtime = 1/(duration_job2 / duration_job1) = 1/(55/50) = 50/55 = 0.91

Son karşılaştırma kadar mükemmel değil, ancak konuları kaybettiğimizde yine de performansta benzer bir düşüş görüyoruz.

Şimdi son bit için: neden daha fazla iş parçacığı ile daha iyi performans elde ediyoruz, esp. CPU sayısından daha fazla iş parçacığı?

Paralellik (verileri birden fazla CPU'ya bölerek elde ettiklerimiz) ve eşzamanlılık (tek bir CPU'da çalışmak için birden fazla iş parçacığı kullandığımızda elde ettiğimiz) arasındaki farkın iyi bir açıklaması Rob Pike: Concurrency tarafından sağlanmıştır. paralellik değildir .

Kısa açıklama, bir Spark işi bir dosya sistemi veya ağ ile etkileşime giriyorsa, CPU'nun bu arabirimlerle iletişimi beklemek için çok fazla zaman harcaması ve aslında "iş" yapması için çok fazla zaman harcamamasıdır. Bu CPU'lara bir seferde çalışmak için 1'den fazla görev vererek, daha az beklemeye ve çalışmaya daha fazla zaman harcıyorlar ve daha iyi performans görüyorsunuz.


1
İlginç ve ikna edici bir açıklama, yürütücünün maksimum verim elde etmek için 5 görev sınırına sahip olduğunu nasıl tahmin ettiğinizi merak ediyorum .
Dat Nguyen

Bu yüzden 5 sayısı geldiğim bir şey değil: IO darboğaz belirtilerini fark ettim ve bu darboğazların nereden gelebileceğini araştırmaya gittim.
turtlemonvh

8

Gönderen mükemmel mevcut kaynakların RStudio en Sparklyr paketi sayfasında :

SPARK TANIMLARI :

Spark isimlendirmesi için bazı basit tanımlar sağlamak yararlı olabilir:

Düğüm : Bir sunucu

İşçi Düğümü : Kümenin bir parçası olan ve Spark işlerini çalıştırmak için kullanılabilen bir sunucu

Ana Düğüm : Çalışan düğümlerini koordine eden sunucu.

Yürütücü : Bir düğüm içindeki bir tür sanal makine. Bir Düğümde birden çok Yürütücü bulunabilir.

Sürücü Düğümü : Spark oturumunu başlatan Düğüm. Genellikle bu, sparklyr'nin bulunduğu sunucu olacaktır.

Sürücü (Yürütücü) : Sürücü Düğümü Yürütücü listesinde de gösterilir.



1

Bence ilk iki yapılandırmada küçük bir sorun var. İplik ve çekirdek kavramları aşağıdaki gibidir. Diş açma kavramı, çekirdeklerin ideal olması durumunda verileri işlemek için bu çekirdeği kullanır. Bu nedenle, bellek ilk iki durumda tam olarak kullanılmaz. Bu örneği karşılaştırmak istiyorsanız , her makinede 10'dan fazla çekirdeğe sahip makineleri seçin . Sonra bench mark yapın.

Ancak, yürütücü başına 5'ten fazla çekirdek vermeyin, i / o performansında şişe boynu olacaktır.

Bu nedenle bu işaretlemeyi yapmak için en iyi makineler 10 çekirdeğe sahip veri düğümleri olabilir.

Veri düğümü makine özellikleri: CPU: Core i7-4790 (çekirdek sayısı: 10, iplik sayısı: 20) RAM: 32GB (8GB x 4) HDD: 8 TB (2 TB x 4)


0

Bence en önemli nedenlerden biri yerellik. Giriş dosya boyutunuz 165G, dosyanın ilgili blokları kesinlikle birden fazla Veri Düğümüne dağıtılmış, daha fazla yürütücü ağ kopyasını önleyebilir.

Yürütücü num eşit blok sayısını ayarlamaya çalışın, bence daha hızlı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.