Belajar Apache Spark - RDD & Functional Transformations
Episode 4 of 23

Belajar Apache Spark - RDD & Functional Transformations

Episode ini membedah RDD, abstraksi terendah Spark: cara membuat, transformation dan action, serta fungsi fungsional map, filter, flatMap, reduceByKey, dan groupByKey. Kalian juga memahami lazy evaluation dan lineage untuk fault tolerance.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Semua abstraksi tinggi tingkat Spark — DataFrame, Dataset, Spark SQL — pada akhirnya berjalan di atas fondasi bernama RDD. Memahami RDD berarti memahami mesin di bawah kap: bagaimana data didistribusikan, bagaimana transformasi menumpuk, dan bagaimana Spark bertahan dari kegagalan.

Episode 4 ini membahas RDD secara menyeluruh: cara membuatnya, dua jenis operasi (transformation dan action), fungsi-fungsi fungsional paling penting, lazy evaluation, lineage, serta kapan RDD masih menjadi pilihan yang tepat di zaman DataFrame.

Dasar RDD

Apa Itu RDD

RDD (Resilient Distributed Dataset) adalah kumpulan elemen yang immutable, terdistribusi lintas cluster, dan bisa diproses secara paralel. Kata resilient berarti jika sebagian data hilang karena executor gagal, Spark bisa membangun ulang partisi itu dari jejak komputasi (lineage) tanpa harus mengulang seluruh pekerjaan.

RDD menyimpan data mentah apa pun: teks, angka, objek Scala, atau record struktural. Setiap RDD terbagi menjadi partisi yang tersebar ke executor — inilah unit paralelisme yang menentukan berapa banyak task yang dijalankan bersamaan.

Membuat RDD

Ada beberapa cara membuat RDD. Yang paling umum di eksperimen adalah parallelize, dan di dunia nyata adalah membaca dari sumber penyimpanan:

Membuat RDD dari koleksi lokal
scala> val rdd = sc.parallelize(Seq("budi", "sari", "dewi"))
scala> rdd.partitions.size

Di PySpark, ekuivalennya sc.parallelize(["budi", "sari", "dewi"]). Untuk data file, sc.textFile("data/transaksi.csv") membuat satu RDD string per baris. Jumlah partisi bisa diatur lewat argumen kedua parallelize.

Transformation dan Action

Konsep kunci: operasi RDD terbagi dua.

  • Transformation: operasi lazy yang menghasilkan RDD baru, contoh map, filter, flatMap. Belum ada komputasi dijalankan.
  • Action: operasi yang memicu eksekusi dan mengembalikan nilai, contoh count(), collect(), reduce().
Transformation vs action
scala> val rdd2 = rdd.map(_.toUpperCase)   // transformation, lazy
scala> rdd2.collect()                      // action, memicu eksekusi

Sampai ada action, Spark hanya membangun pipeline operasi yang belum dieksekusi. Ini yang memungkinkan Spark mengoptimalkan urutan eksekusi secara keseluruhan.

Fungsi-Fungsi Fungsional Utama

Map, Filter, dan FlatMap

Tiga transformation paling dasar:

Pythonmap, filter, flatMap di PySpark
sc = spark.sparkContext
angka = sc.parallelize([1, 2, 3, 4, 5])
 
hasil_map = angka.map(lambda x: x * 2)                # [2, 4, 6, 8, 10]
hasil_filter = angka.filter(lambda x: x % 2 == 0)     # [2, 4]
hasil_flatmap = angka.flatMap(lambda x: [x, x + 1])   # [1,2,2,3,3,4,...]
  • map mengubah setiap elemen menjadi tepat satu elemen baru.
  • filter mempertahankan elemen yang memenuhi predikat.
  • flatMap mengubah satu elemen menjadi nol atau lebih elemen, lalu meratakan hasilnya — ideal untuk memecah baris menjadi kata.
PythonWord count klasik dengan flatMap
kalimat = sc.parallelize(["halo dunia", "halo spark"])
kata = kalimat.flatMap(lambda s: s.split(" "))
print(kata.collect())

Hasil ['halo', 'dunia', 'halo', 'spark'] menunjukkan cara flatMap memecah dan meratakan — fondasi dari algoritma word count yang legendaris.

ReduceByKey dan GroupByKey

Untuk data berpasangan (kunci, nilai), Spark menyediakan agregasi berbasis kunci:

PythonreduceByKey vs groupByKey
pasangan = sc.parallelize([("apel", 3), ("pisang", 2), ("apel", 1)])
 
by_key = pasangan.reduceByKey(lambda a, b: a + b)   # [('apel',4),('pisang',2)]
grouped = pasangan.groupByKey().mapValues(list)     # [('apel',[3,1]),...]

Perbedaan penting: reduceByKey menggabungkan nilai sebelum shuffle sehingga data yang dikirim antar node jauh lebih sedikit. groupByKey mengirim semua nilai mentah ke partisi yang sama — sering lebih lambat untuk agregasi sederhana. Aturan praktisnya: pilih reduceByKey bila memungkinkan.

Lazy Evaluation dan Lineage

Lazy Evaluation

Spark menunda eksekusi sampai ada action. Ini bukan sekadar teknik — ini yang memungkinkan optimasi: Spark bisa menggabungkan transformasi beruntun, memangkas kolom yang tidak dipakai, dan menghindari pekerjaan sia-sia. Jika kalian membangun seratus transformation tanpa action, tidak ada satu pun yang dieksekusi.

Lineage Graph

Setiap RDD menyimpan jejak transformasi yang membentuknya — inilah lineage. Jika sebuah partisi hilang, Spark menelusuri lineage dan menghitung ulang hanya partisi tersebut. Ini adalah mekanisme fault tolerance yang tidak membutuhkan replikasi data, sebuah keunggulan arsitektural RDD sejak awal.

Lineage: RDD adalah catatan komputasi
textFile → flatMap → map → filter → reduceByKey

Menampilkan lineage sebuah RDD bisa dilakukan dengan rdd.toDebugString — sangat berguna saat ingin memahami dari mana sebuah RDD berasal atau mengapa recompute terjadi.

Info

Lineage adalah pedang bermata dua: tanpa cache, setiap action mengulang seluruh rantai komputasi dari sumber. Jika kalian menjalankan banyak action pada RDD yang sama, cache atau persist hasil antara untuk menghindari rekalkulasi berulang.

Kapan RDD Masih Relevan

Kekuatan RDD

RDD masih relevan ketika kalian butuh kontrol paling rendah: memanipulasi data yang bukan berbentuk tabel, membangun library transformasi kustom, atau bekerja dengan data yang tidak punya schema tetap. Sebagian besar ekosistem MLlib klasik dan beberapa library pihak ketiga masih mengonsumsi RDD.

Kapan Harus Meninggalkan RDD

Untuk sebagian besar workload, DataFrame adalah pilihan yang lebih baik:

  • Optimasi otomatis: Catalyst optimizer memangkas dan memfilter sedini mungkin.
  • Kolom dan tipe data: schema menghindari bug tersembunyi.
  • Ekosistem: DataFrame terintegrasi dengan Spark SQL, streaming, dan MLlib.

DataFrame pada dasarnya adalah RDD dengan schema dan optimizer — jadi mempelajari RDD di episode ini tetap berharga, karena semua konsep partisi, transformasi, dan action berlaku sama di lapisan atas.

Rekomendasi pemilihan
data berkolom & berstruktur → DataFrame / Dataset / SQL
kontrol rendah & data bebas → RDD

Penutup

Episode 4 menuntaskan pemahaman fondasi: RDD adalah koleksi terdistribusi yang immutable dan resilient, dijalankan lewat transformation lazy dan action eager. Operasi fungsional seperti map, filter, flatMap, reduceByKey, dan groupByKey adalah vokabulari dasar yang muncul kembali di seluruh lapisan Spark.

Inti yang harus dibawa pulang:

  • RDD adalah fondasi terdistribusi; DataFrame adalah RDD dengan schema.
  • Transformation lazy, action eager — tidak ada komputasi tanpa action.
  • flatMap memecah dan meratakan; reduceByKey lebih efisien dari groupByKey.
  • Lineage memungkinkan rekalkulasi partisi yang hilang tanpa replikasi.
  • Pilih RDD hanya untuk kontrol rendah; pakai DataFrame untuk kebanyakan kasus.

Di episode 5 selanjutnya kita akan membahas DataFrame dan Spark SQL — membuat DataFrame dari CSV, JSON, dan Parquet, menjalankan SQL dengan temporary views, memahami schema inference dan Catalyst optimizer, serta transformation dan expression API yang menjadi bahasa sehari-hari Spark.

Belajar Apache Spark - RDD & Functional Transformations | Belajar Apache Spark