Spark'ta Shuffle'ı Azaltmak ve Bölümlemeyi Doğru Ayarlamak
Beceri rehberi

Spark'ta Shuffle'ı Azaltmak ve Bölümlemeyi Doğru Ayarlamak

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Spark'ta shuffle'ın neden maliyetli olduğunu, bölüm sayısını, repartition ve coalesce farkını, AQE ve broadcast ile çarpık veri sorunlarının çözümünü öğrenin.

Shuffle nedir, neden maliyetlidir?

Spark veriyi bölümlere ayırarak küme üzerinde paralel işler. Çoğu dönüşüm bir bölümü başka bir bölüme ihtiyaç duymadan işler. Ancak bir toplulaştırma, birleştirme ya da yeniden bölümleme aynı anahtara sahip kayıtların aynı bölümde buluşmasını gerektirir. Bu durumda veri düğümler arasında yeniden dağıtılır; işte buna shuffle denir.

Shuffle pahalıdır, çünkü veri diske yazılır, ağdan geçer ve yeniden okunur. Bu yüzden Spark performans ayarının büyük kısmı şu soruların cevabıdır: gereksiz shuffle'ı nasıl engellerim ve kaçınılmaz shuffle'ı nasıl dengeli ve verimli yaparım? Hangi dönüşümlerin shuffle tetiklediğini bilmek ilk adımdır: groupBy ve toplulaştırmalar, çoğu birleştirme, distinct, genel sıralama ve açık repartition çağrıları bunların başında gelir.

Shuffle'ı planda ve arayüzde görmek

Ayarlamadan önce ölçün. Sorgunun fiziksel planını explain ile alabilirsiniz; planda veri yeniden dağıtımı Exchange adlı düğümlerle görünür. Her Exchange, bir shuffle sınırıdır. Gereksiz görünen bir Exchange varsa sorguyu yeniden yazmayı veya veriyi önceden bölümlemeyi düşünün.

Spark'ın web arayüzünde iş aşamalarını (stage) ve görevleri (task) izleyebilirsiniz. Dikkat edilecek işaretler: bir aşamada görevlerin çoğu çabuk biterken birkaç görevin çok uzun sürmesi (çarpıklık), çok sayıda çok küçük görev (fazla bölüm), disk taşması göstergeleri ve shuffle okuma-yazma hacminin girdiden büyük olması. Bu işaretler, sonraki bölümlerdeki ayarlardan hangisine ihtiyaç olduğunu söyler.

Bölüm sayısı: spark.sql.shuffle.partitions

Resmî performans belgesine göre spark.sql.shuffle.partitions ayarı, birleştirme veya toplulaştırma için veriyi shuffle ederken kullanılan bölüm sayısını belirler. Varsayılan değer her iş yüküne uymaz.

Çok az bölüm, her bölümün büyük olmasına, belleğin taşmasına ve paralelliğin düşmesine yol açar. Çok fazla bölüm ise çok sayıda küçük görev, zamanlama yükü ve küçük çıktı dosyaları üretir. Doğru değer veri büyüklüğüne ve kümedeki toplam çekirdek sayısına bağlıdır; hedef, bölümlerin yeterince büyük ve kümenin tüm kapasitesini kullanacak kadar çok olmasıdır. Pratik yaklaşım denemektir: aynı işi farklı değerlerle çalıştırıp arayüzde görev sürelerini ve shuffle boyutlarını karşılaştırın.

spark.conf.set("spark.sql.shuffle.partitions", sayi)

Burada sayi, kendi deneylerinizden çıkan değerdir; başka birinin kümesinde işe yarayan sayıyı kopyalamayın.

Uyarlanabilir sorgu yürütmesi (AQE)

Adaptive Query Execution, Spark'ın çalışma sırasında istatistiklere bakarak planı yeniden düzenlediği özelliktir. Resmî belgeye göre ana anahtar spark.sql.adaptive.enabled'dır ve güncel sürümlerde varsayılan olarak açıktır. AQE shuffle sonrası bölümleri birleştirir (coalesce), çarpık birleştirmeleri böler ve uygun görürse birleştirme stratejisini değiştirir.

Bölüm birleştirme, spark.sql.adaptive.coalescePartitions.enabled ile kontrol edilir; Spark ardışık küçük bölümleri hedef boyuta doğru birleştirir ve gereksiz küçük görevleri engeller. Hedef boyut spark.sql.adaptive.advisoryPartitionSizeInBytes ile ifade edilir. Belge, yoğun kümelerde parallelismFirst ayarını kapatmayı önerir; bu nüansı kendi ortamınızda test edin.

AQE sayesinde shuffle bölüm sayısını mükemmel ayarlamak daha az kritiktir, ama yerine geçmez: başlangıç bölüm sayısı hâlâ iş yükünü etkiler ve çok büyük veride ayarlanmış bir değer fark yaratır.

Çarpık veri (skew) ve birleştirme

Veri bir anahtara göre dengesiz dağıldığında, örneğin bir müşteri kayıtların büyük kısmına sahipse, o anahtarın bölümü diğerlerinden çok büyük olur ve tek bir görev tüm işi bekletir. Belirti, arayüzde bir görevin diğerlerinden belirgin biçimde uzun sürmesidir.

Çözüm yolları:

  • AQE'nin çarpık birleştirme optimizasyonu: spark.sql.adaptive.skewJoin.enabled ile çalışır ve sort-merge birleştirmede çarpık bölümleri bölerek dengeler.
  • Küçük tabloyu yayınlamak: birleştirmenin bir tarafı küçükse BROADCAST ipucu ile o tabloyu tüm düğümlere dağıtıp büyük tablonun shuffle'ını tamamen önleyebilirsiniz. Belgeye göre spark.sql.autoBroadcastJoinThreshold bu otomatik yayın için üst boyutu belirler. İpucu bağlayıcı değildir, bazı birleştirme türleri desteklemeyebilir.
  • Anahtarı tuzlamak: çarpık anahtara rastgele bir ek bileşen ekleyip yükü yaymak; bu daha ileri bir yöntemdir ve sorgu mantığını karmaşıklaştırır.
  • Çarpıklığın kaynağını bulmak: bazen sorun NULL anahtarlardır ve bunları ayrı ele almak yeterli olur.

repartition ve coalesce ne zaman?

Bölüm sayısını elle değiştirmenin başlıca yolları vardır. repartition, verinin tamamını yeniden dağıtır; bölüm sayısını artırır veya azaltır ve belirli bir sütuna göre dengeli bölümler üretir, ama tam shuffle maliyeti vardır. coalesce ise yalnızca bölüm sayısını azaltır ve mümkün olduğunca shuffle yapmadan komşu bölümleri birleştirir; ucuzdur ama bölümler dengesiz kalabilir.

Basit kural: bölüm sayısını azaltıyorsanız ve dengeyi önemsemiyorsanız coalesce; bölüm sayısını artırıyorsanız ya da bir anahtara göre dağıtmak istiyorsanız repartition. SQL tarafında aynı işlevi COALESCE, REPARTITION, REPARTITION_BY_RANGE ve REBALANCE ipuçları görür; belge bu ipuçlarının çıktı bölümlemesini ve dosya sayısını kontrol etmek için kullanıldığını belirtir.

Tipik kullanım: yazmadan önce çok sayıda küçük çıktı dosyası oluşmasını önlemek için bölümü azaltmak ya da yazılacak verinin sonraki sorgularda kullanılacak sütuna göre düzenlenmesi. Ardışık gereksiz repartition çağrıları sorgunun yavaşlamasının yaygın nedenidir; her çağrı kendi shuffle'ını getirir.

Pratik kontrol listesi

  • Önce planı okuyun: Exchange düğümleri nerede, kaç tane?
  • Yalnızca gereken sütunları ve satırları erken seçin; shuffle edilen veri küçülür.
  • Küçük tablo birleştirmelerinde yayını değerlendirin.
  • AQE açıkken çarpıklık ve küçük bölüm belirtilerini arayüzden kontrol edin.
  • Shuffle bölüm sayısını deneyle ayarlayın, kopyalamayın.
  • Yazmadan önce çıktı dosyalarının boyutunu düşünün; çok küçük dosyalar sonraki okumaları yavaşlatır.
  • Aynı veriyi birden çok kez kullanıyorsanız önbelleğe almayı düşünün, ama belleği aşırı yüklemeyin.
  • Her değişiklikte önce ve sonra süreyi, shuffle hacmini ve görev dağılımını karşılaştırın.

Sık hata, neden olduğunu anlamadan ayar değiştirmektir. Her ayarın bir belirtisi vardır; belirti yoksa ayar fayda getirmez, riski artırır.

Bu beceriyi Mindset programlarında nerede çalışırsınız

Mindset'in Apache Spark Temelleri programında Spark mimarisi ve temel kavramlar ile performans optimizasyonu ve üretim ayrı modüllerdir; Temel PySpark Eğitimi ise dağıtık sistemlerde PySpark konusunu kapsar. Bu içerikler shuffle'ın nerede doğduğunu anlamak için gereken mimari bilgiyi sağlar.

Bu bilgi, yavaş çalışan Spark işlerini düzeltmekle görevli veri mühendisleri ve küme maliyetini yönetmesi gereken ekipler için pratik bir temeldir. Kurumsal tarafta, iş yazan herkesin aynı kontrol listesiyle plan ve arayüz okumasını sağlamak, bireysel deneme yanılma süresini azaltır.

İlgili Mindset programı

Apache Spark Temelleri

Sık sorulanlar

Sık sorulan sorular

repartition ile coalesce arasındaki fark nedir?

repartition tam shuffle yaparak verinin tamamını yeniden dağıtır ve dengeli bölümler üretir. coalesce yalnızca bölüm sayısını azaltır, mümkün olduğunca shuffle yapmadan komşu bölümleri birleştirir. Bu yüzden ucuzdur, ama bölümler dengesiz kalabilir.

AQE açıkken shuffle bölüm sayısını ayarlamaya gerek var mı?

AQE küçük bölümleri birleştirebilir ve çarpık birleştirmeleri bölebilir, bu nedenle ayarın kritikliği azalır. Yine de başlangıç bölüm sayısı iş yükünü etkiler; çok büyük verilerde iyi seçilmiş bir değer fark yaratır. Arayüzdeki görev dağılımına bakarak karar verin.

Shuffle'ı tamamen önlemek mümkün mü?

Hayır. Toplulaştırma ve çoğu birleştirme doğası gereği veri yeniden dağıtımı gerektirir. Hedef onu sıfıra indirmek değil, gereksiz olanları kaldırmak ve kalanları dengeli yapmaktır. Küçük tabloları yayınlamak, erken filtrelemek ve ardışık repartition çağrılarından kaçınmak en etkili adımlardır.

Çarpıklığı nasıl fark ederim?

Spark arayüzünde bir aşamada görevlerin çoğu çabuk biter, birkaç görev ise belirgin biçimde uzun sürer ve çok daha büyük veri okur. Anahtar dağılımına bakarak suçlu anahtarı bulabilirsiniz. Genelde NULL değerler ya da çok baskın tek bir anahtar nedendir.

Spark Shuffle ve Partition Ayarı ile Performans