Spark SQL Kullanımı: Dosyadan Sorguya, Sorgudan DataFrame'e
Beceri rehberi

Spark SQL Kullanımı: Dosyadan Sorguya, Sorgudan DataFrame'e

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

Veriyi okuyup geçici görünüm olarak kaydetme, SQL ile süzme, birleştirme ve toplulaştırma, DataFrame ile birlikte kullanma ve planı okuma adımları.

Spark SQL nedir ve neden SQL yazılır?

Spark SQL, Apache Spark'ın yapılandırılmış veriyi işleyen modülüdür. Resmî belgeye göre RDD API'sinin aksine verinin yapısı ve hesaplama hakkında Spark'a daha fazla bilgi verir ve Spark bu bilgiyle ek optimizasyonlar yapar. SQL, Dataset API ya da başka bir dil kullanmanız fark etmez; sonucu aynı yürütme motoru hesaplar, bu yüzden API'ler arasında rahatça geçiş yapabilirsiniz.

Pratikte bu şu anlama gelir: SQL bilen bir analist, Python ya da Scala yazmadan dağıtık bir veriyi sorgulayabilir. SQL sonucu Python, Scala, Java ya da R'dan çalıştırıldığında Dataset ya da DataFrame olarak döner ve istenirse DataFrame işlemleriyle devam edilir. Veri yüklü olduğu sürece SELECT, WHERE, JOIN, GROUP BY gibi tanıdık yapılar çalışır; fark, verinin tek bir makinede değil küme üzerinde bölümlenmiş olmasıdır.

Adım adım: veriyi okuyup sorgulamak

Tipik bir PySpark akışı şöyledir. Önce SparkSession oluşturulur, sonra veri okunur, geçici görünüm olarak kaydedilir ve SQL ile sorgulanır:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("sales-analysis").getOrCreate()

orders_df = spark.read.parquet("/data/orders") orders_df.createOrReplaceTempView("orders")

sonuc = spark.sql( "SELECT customer_id, SUM(amount) AS toplam " "FROM orders WHERE durum = 'tamamlandi' " "GROUP BY customer_id ORDER BY toplam DESC" ) sonuc.show()

createOrReplaceTempView ile DataFrame, oturum süresince SQL'den görünür bir tablo adı kazanır. Görünüm veriyi kopyalamaz, yalnızca bir ad verir. spark.sql ifadesi ise sorguyu çalıştırıp DataFrame döndürür. Dosya biçimi olarak sütunlu biçimler, örneğin Parquet, metin tabanlı biçimlere göre sorgularda genellikle daha az veri okur; okuma yöntemi biçime göre değişir.

SQL ile DataFrame API'yi birlikte kullanmak

Bu yaklaşımlar birbirinin alternatifi değildir, aynı program içinde karıştırılabilir. Karmaşık toplulaştırma ve birleştirmeler SQL'de daha okunaklıdır; koşullu mantık ya da programatik sütun üretimi ise DataFrame API'sinde daha kolaydır. Bir sorgunun sonucunu DataFrame olarak alıp ek dönüşümler uygulayabilir, bir DataFrame'i yeniden görünüm olarak kaydedip SQL'e geri dönebilirsiniz.

Karar ölçütü okunabilirliktir. Ekipte SQL bilgisi yaygınsa ağır dönüşümleri SQL ile yazmak bakım maliyetini azaltır. Test edilebilirlik açısından ise küçük, adlandırılmış fonksiyonlara ayrılmış DataFrame kodu daha rahat birim testine girer. Karışık kullanırken tek bir kural koyun, örneğin ham veri okuma ve temizlik DataFrame'de, iş mantığı SQL'de olsun.

Birleştirme, pencere fonksiyonu ve küçük örnekler

Spark SQL, tanıdık analitik yapıların çoğunu destekler: birleştirmeler, toplulaştırmalar, alt sorgular ve pencere fonksiyonları gibi. Örneğin müşteri başına son siparişi bulmak için ROW_NUMBER ile PARTITION BY kullanabilirsiniz. Küçük bir boyut tablosuyla büyük bir olgu tablosunu birleştirirken Spark'ın küçük tabloyu tüm düğümlere dağıtmasını sağlayan BROADCAST ipucunu kullanmak, resmî belgede belirtildiği gibi bir sorgu içi ipucuyla yapılabilir:

SELECT /*+ BROADCAST(m) */ s.customer_id, m.segment, s.amount FROM orders s JOIN customers m ON s.customer_id = m.customer_id;

İpuçları bağlayıcı değildir; Spark bazı birleştirme türlerinde ipucunu uygulayamayabilir. Ayrıca sorgu planını incelemek için sonuç DataFrame'inde explain çağrısını kullanabilirsiniz. Plan, hangi birleştirme stratejisinin seçildiğini ve verinin nerede yeniden dağıtıldığını gösterir. Bu çıktıyı okumak, performans sorunlarını anlamanın ilk adımıdır.

Örnek iş akışı: müşteri başına son sipariş ve çıktıyı yazma

Örneğin her müşterinin en son siparişini ayrı bir tabloya yazmak istiyorsunuz. SQL ile pencere fonksiyonu kullanılır, sonuç DataFrame olarak alınır ve dosyaya yazılır:

son = spark.sql( "SELECT * FROM (" "SELECT *, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS row_num " "FROM orders) WHERE row_num = :hedef" )

Buradaki :hedef bir yer tutucudur; gerçek sorguda row_num değerinin ilk sırayı göstermesi koşulunu yazarsınız. Sonra sonuç.drop("row_num").write.mode("overwrite").parquet("/cikti/last_order") gibi bir yazma işlemiyle çıktıyı alırsınız. Yazma modu önemlidir: overwrite mevcut veriyi siler, append ekler. Hangi modu seçtiğinizi bilinçli verin; yanlış mod, üretim verisinin üzerine yazmaya yol açabilir.

Yazılan çıktıyı klasörlere bölmek isterseniz yazma sırasında bir sütuna göre bölümleme yapabilirsiniz; bu sonraki sorguların yalnızca ilgili klasörleri okumasını sağlar. Ancak çok fazla küçük klasör üretmek de sorun yaratır, bu yüzden bölümleme sütunu seçimi dikkat ister.

Hızlı sorgu için temel alışkanlıklar

Dağıtık sorguda maliyetin büyük kısmı veri okumaya ve ağ üzerinden yeniden dağıtmaya gider. Bu nedenle şu alışkanlıklar fark yaratır:

  • Yalnızca gereken sütunları seçin. SELECT yıldız yazmak, sütunlu biçimin avantajını azaltır.
  • Filtreleri mümkün olduğunca erken uygulayın; Spark çoğu zaman bunu kendisi yapar, ama karmaşık ifadelerde sorgunuzu açık yazmak yardımcı olur.
  • Aynı veriyi birçok kez kullanacaksanız önbelleğe almayı düşünün; ancak her şeyi önbelleğe almak belleği tüketir.
  • Küçük tabloları birleştirirken yayın (broadcast) ipucunu değerlendirin.
  • Sonuç büyükse tamamını sürücüye toplamak yerine bir dosyaya yazın.

Sorguyu yazdıktan sonra planı kontrol etmek, bu alışkanlıkların hepsini doğrulayan adımdır.

Sık hatalar

  • Veriyi yerel bir veri çerçevesi gibi düşünmek: Spark işlemleri tembeldir; sorgu, bir eylem (show, write gibi) çağrılana kadar çalışmaz. Yavaşlığı yanlış satıra yormak yaygındır.
  • Küçük veride denemek, büyük veride hız beklemek. Çalışma süresi veri büyüklüğüne ve kümeye bağlıdır.
  • collect gibi işlemlerle tüm sonucu sürücü belleğine toplayıp belleği aşmak.
  • Veri tipini denetlememek: CSV'den okunan sütunlar metin olabilir; tip dönüşümü yapılmazsa karşılaştırmalar ve toplamlar beklenmedik çıkar.
  • Geçici görünümün oturum bittiğinde kaybolduğunu unutmak; kalıcı tablo için ayrı bir kayıt yöntemi gerekir.
  • Aynı mantığı farklı not defterlerinde kopyalayıp yönetmek yerine ortak bir görünüm ya da kütüphane kullanmamak.

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

Mindset'in Apache Spark Temelleri programı Spark mimarisi, DataFrame ve Dataset API, Spark SQL ile veri analizi ve veri okuma yazma işlemlerini ayrı modüllerde işler; Temel PySpark Eğitimi ise PySpark DataFrame API, veri temizleme ve dönüşümler ile Spark SQL ile sorgulamayı kapsar.

SQL bilen analistlerin büyük veri ortamına geçişi için, ayrıca Python tarafında DataFrame işlemlerini öğrenmek isteyen veri mühendisleri için uygun bir çıkış noktasıdır. Kurumsal ekipler, veri ambarı SQL'ini Spark ortamına taşıyacak ekip üyelerini bu programlarla hazırlayabilir.

İlgili Mindset programı

Apache Spark Temelleri

Sık sorulanlar

Sık sorulan sorular

Spark SQL ile PySpark DataFrame API arasında hız farkı var mı?

Genel olarak yok. Resmî belgede belirtildiği gibi SQL, Dataset API ya da başka bir dil kullanmanız fark etmez; sonucu aynı yürütme motoru hesaplar. Hız farkı yazım biçiminden değil, sorgunun mantığından, veri biçiminden ve bölümlemeden doğar; bu yüzden önce planı inceleyin.

Geçici görünüm veriyi bellekte mi tutar?

Hayır. Görünüm yalnızca bir ad ve sorgu tanımıdır, veriyi kopyalamaz ve bellekte de tutmaz. Veriyi bellekte tutmak istiyorsanız önbelleğe alma işlemini ayrıca yapmanız gerekir. Geçici görünüm oturum kapandığında kaybolur, kalıcı tablo için ayrı bir kayıt yöntemi kullanın.

Spark SQL standart SQL ile birebir aynı mı?

Büyük ölçüde tanıdıktır, ancak her sistemde olduğu gibi kendine özgü işlev adları ve söz dizimi farkları vardır. Başka bir veritabanından sorgu taşırken sorguları tek tek deneyin, farkları resmî SQL başvurusundan kontrol edin ve sonuçları eski sistemle karşılaştırın.

Büyük veriyi sorgulamak için Spark şart mı?

Veri tek bir makinenin belleğine ya da disk işleme kapasitesine sığıyorsa Spark gereksiz karmaşıklık getirebilir. Veri büyüdükçe ya da birden çok kaynak birleştirilecekse dağıtık işleme anlam kazanır. Karar, veri büyüklüğüne ve büyüme beklentisine bağlıdır.

Spark SQL ile Büyük Veri Nasıl Sorgulanır