Pemantauan

Spark UI pada cluster, history server.

Daftar isi

Pemantauan memberi dasar bagi keputusan penyetelan. Tanpa melihat waktu per stage, jumlah task, dan ukuran shuffle, keputusan penyetelan hanya tebakan. Spark menyediakan dua antarmuka untuk itu, yaitu Spark UI yang hidup selama aplikasi berjalan, dan history server yang memutar ulang riwayat aplikasi dari berkas event log setelah aplikasi selesai. Topik ini menjelaskan keduanya beserta cara merekam event log nyata yang dibaca history server.

Spark UI selama aplikasi berjalan#

Setiap aplikasi Spark yang menyala membuka web UI pada port 4040, dan alamatnya tercetak pada log saat sesi dibangun. UI menyusun informasi dalam beberapa tab yang urutannya mengikuti alur diagnosis. Tab Jobs menampilkan daftar job beserta durasinya, tab Stages memerinci setiap stage beserta jumlah task, waktu median dan maksimum, serta ukuran input, output, shuffle read, dan shuffle write, sedangkan tab Storage menampilkan blok cache yang tersimpan beserta fraksi memori yang terpakai, dan tab Executors merangkum pemakaian sumber daya tiap executor termasuk memori yang dipakai dan jumlah task yang gagal.

Pola membaca UI yang paling berguna berangkat dari stage yang paling lambat. Ketika satu stage jauh melampaui yang lain, periksa distribusi durasi antar task di dalamnya, karena sebagian kecil task yang jauh lebih lambat menandakan partisi timpang atau kunci yang muncul terlalu sering. Ketika seluruh task lambat namun rata, kemungkinan besar masalahnya bukan distribusi, melainkan ukuran data atau konfigurasi, dan tab SQL menampilkan rencana fisik yang benar-benar dieksekusi lengkap dengan metrik per simpul, yang memudahkan mengaitkan keputusan penyetelan pada topik sebelumnya dengan angkanya.

Pada mode lokal, UI tetap terbuka dan informatif, meski semuanya berjalan di satu mesin. Untuk sesi yang dibangun melalui PySpark tanpa peluncuran spark-submit, UI bisa juga diakses melalui spark.sparkContext.uiWebUrl() dari dalam skrip, dan memanggilnya lebih andal daripada mengingat port, karena ketika port 4040 sedang terpakai, UI otomatis memakai port 4041 dan seterusnya.

Event log dan history server#

Spark UI hilang ketika aplikasi berhenti, dan itulah fungsi history server, yaitu aplikasi web yang membaca berkas event log lalu menyajikan UI yang sama untuk aplikasi yang sudah selesai. Syaratnya satu, yaitu aplikasi merekam event log ke folder yang dapat dibaca history server. Perekaman dinyalakan dengan dua konfigurasi, yaitu spark.eventLog.enabled dan spark.eventLog.dir, dan history server sendiri dijalankan dengan start-history-server.sh sambil menunjuk folder yang sama melalui spark.history.fs.logDirectory.

Skrip berikut menyalakan perekaman event log ke folder sementara, menjalankan satu pekerjaan kecil, menghentikan aplikasi, lalu memeriksa hasil rekamannya. Perhatikan bahwa perekaman hanya menambah sedikit biaya, dan folder hasilnya inilah yang dikonsumsi history server.

python peraga_eventlog.py
import json
import os
import shutil

from pyspark.sql import SparkSession

lokasi = "/tmp/eventlog-m7"
shutil.rmtree(lokasi, ignore_errors=True)
os.makedirs(lokasi)

spark = (
    SparkSession.builder
    .master("local[2]")
    .appName("peraga-eventlog")
    .config("spark.sql.shuffle.partitions", "2")
    .config("spark.eventLog.enabled", "true")
    .config("spark.eventLog.dir", "file://" + lokasi)
    .config("spark.eventLog.compress", "false")
    .getOrCreate()
)

jumlah = spark.range(10).count()
print("jumlah baris hitung ulang:", jumlah)

spark.stop()

folder_aplikasi = os.path.join(lokasi, os.listdir(lokasi)[0])
print("jumlah folder aplikasi   :", len(os.listdir(lokasi)))
berkas = [os.path.join(folder_aplikasi, n) for n in os.listdir(folder_aplikasi) if n.startswith("events_")][0]
with open(berkas) as f:
    baris = [json.loads(x) for x in f]
print("event pertama            :", baris[0]["Event"])
print("event terakhir           :", baris[-1]["Event"])
text Keluaran
WARNING: Using incubator modules: jdk.incubator.vector
jumlah baris hitung ulang: 10
jumlah folder aplikasi   : 1
event pertama            : SparkListenerLogStart
event terakhir           : SparkListenerApplicationEnd

Keluaran memperlihatkan siklus lengkap perekaman. Satu folder per aplikasi dibuat di dalam folder yang ditunjuk spark.eventLog.dir, dan di dalamnya berkas events_ memuat satu baris JSON per peristiwa, mulai dari SparkListenerLogStart saat perekam menyala sampai SparkListenerApplicationEnd saat spark.stop() dipanggil. Setiap peristiwa berisi waktu, identitas stage atau task, dan metriknya, dan seluruh UI pada history server hanyalah tampilan ulang dari berkas ini. Konfigurasi spark.eventLog.compress dimatikan pada skrip supaya berkasnya dapat dibaca langsung sebagai teks, sementara pada produksi kompresi tetap menyala untuk menghemat ruang.

Pola pemantauan di produksi#

Pada cluster produksi, perekaman event log dinyalakan melalui spark-defaults.conf untuk seluruh aplikasi, dan history server menjadi tempat pertama ketika pekerjaan yang sehari sebelumnya berhasil kini berjalan lambat. Perbandingan antar run dari pekerjaan yang sama sering langsung menunjukkan penyebabnya, misalnya volume input naik, satu stage bertambah karena perubahan kunci, atau jumlah task turun karena perubahan partisi.

Di luar UI, Spark memaparkan metrik berbasis Dropwizard yang dapat dikirim ke sistem pemantauan seperti Prometheus atau JMX, dan untuk aplikasi PySpark, tingkat aplikasi bisa ditambah dengan log Python dan metrik kustom yang dibaca dari accumulator. Urutan memakai semuanya biasanya sederhana, yaitu alarm dari sistem pemantauan menandakan pekerjaan bermasalah, history server menjelaskan stage mana yang berubah, dan Spark UI pada run ulang memberi rincian sampai level task.

Kesalahan umum#

Kesalahan pertama adalah mencari Spark UI setelah aplikasi berhenti. UI melekat pada aplikasi yang hidup, dan begitu sesi mati, port 4040 kosong. Solusinya bukan mencari UI lama, melainkan menyalakan perekaman event log sejak sekarang agar aplikasi berikutnya dapat diputar ulang di history server.

Kesalahan kedua adalah menyalakan perekaman event log ke folder lokal tanpa menyadari bahwa folder itu melekat pada mesin tempat driver berjalan. Pada mode cluster, driver berpindah ke mesin lain, dan history server yang berjalan di mesin berbeda tidak menemukan berkasnya. Folder log harus pada penyimpanan bersama yang terlihat oleh seluruh komponen, misalnya HDFS.

Kesalahan ketiga adalah membaca UI hanya dari tab Jobs dan menghentikan diagnosis di sana. Penyebab hampir selalu bersembunyi di rincian stage, yaitu distribusi durasi antar task, ukuran shuffle, dan jumlah task yang gagal lalu diulang. Tab SQL yang menampilkan rencana fisik dengan metrik per simpul adalah jalan terpendek untuk mengaitkan gejala dengan keputusan rencana.

Ringkasan#

  • Spark UI hidup bersama aplikasi pada port 4040 dan menyusun diagnosis dari Jobs, Stages, Storage, Executors, dan SQL dengan metrik per simpul.
  • History server memutar ulang UI untuk aplikasi yang sudah selesai dengan membaca event log dari folder bersama.
  • Perekaman dinyalakan dengan spark.eventLog.enabled dan spark.eventLog.dir, dan satu folder per aplikasi berisi berkas peristiwa JSON per baris.
  • Pada produksi, alarm dari metrik eksternal menandakan masalah, dan history server beserta UI memberi rincian penyebabnya.

Referensi#