Topik temu duga representatif

Temu Bual Kejuruteraan Data: Bagaimanakah Anda Mendiagnosis dan Memperbaiki Kepencongan Data (Data Skew) Spark?

DataSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu tugasan harian Spark SQL melakukan left-join antara jadual fakta peristiwa 4.8 TB dengan dimensi produk 180 GB. Selepas satu pelepasan huluan (upstream release), 32% daripada peristiwa dipetakan kepada product_id='UNKNOWN'. Di seluruh 2,000 partisi shuffle, median bacaan shuffle tugas ialah 1.1 GiB, tetapi satu tugas membaca 720 GiB, berulang kali melimpah (spill) ke cakera, dan gagal dengan OOM; masa jalanan meningkat daripada 24 kepada 96 minit. Bagaimanakah anda akan membuktikan puncanya, membetulkannya tanpa menggugurkan data atau mengubah hasil cantuman, dan mengesahkan penyelesaian tersebut?

Gesaan dan Bila Ia Terpakai

Satu tugasan harian Spark SQL melakukan left-join antara jadual fakta peristiwa 4.8 TB dengan dimensi produk 180 GB pada product_id. Selepas satu pelepasan huluan, 32% peristiwa dinormalisasikan kepada product_id='UNKNOWN'. Tugasan ini menggunakan 2,000 partisi shuffle. Dalam peringkat cantuman, Spark UI menunjukkan median bacaan shuffle tugas sebanyak 1.1 GiB, manakala satu tugas membaca 720 GiB, melimpah berulang kali ke cakera, dan akhirnya gagal dengan OOM selepas beberapa percubaan semula. Masa jalanan telah meningkat daripada 24 kepada 96 minit. Pihak perniagaan memerlukan tugasan ini selesai dalam masa 45 minit, tanpa membuang peristiwa produk tidak diketahui atau mengubah hasil left-join.

Saiz jadual, perkongsian kunci, metrik partisi, masa jalanan, dan SLA adalah andaian temu bual. Tugas utamanya adalah untuk membezakan kepencongan data daripada kekurangan sumber dan letupan output cantuman menggunakan bukti peringkat partisi, kemudian memilih pemulihan yang mengekalkan kontrak data. Ini tergolong dalam kategori data kerana ia menguji pelan pelaksanaan Spark, partisi shuffle, taburan data, dan ketepatan kelompok (batch). Soalan Kafka hot-partition sedia ada memfokuskan pada kunci mesej, susunan, dan ofset pengguna. Soalan ini memfokuskan pada partisi SQL masa jalanan, strategi cantuman, AQE, dan pemeliharaan hasil, jadi lapisan kegagalan dan kaedah pengesahan adalah berbeza.

Penaakulan yang sama terpakai kepada groupBy, distinct, fungsi tetingkap (window functions), dan kebergantungan luas yang lain. Apabila banyak rekod untuk satu kunci bertumpu pada beberapa tugas pasca-shuffle, ia boleh mencipta tugas lembap (stragglers), limpahan, tekanan GC, atau OOM. Jawapan yang baik tidak bermula dengan menambah memori. Ia terlebih dahulu membuktikan sama ada tugas paling perlahan memegang jumlah data dan pengiraan yang tidak berkadar.

Perkara yang Dinilai oleh Penemu Bual

Mulakan dengan ketelitian bukti. Jawapan yang kukuh bergerak daripada tugasan kepada pertanyaan SQL, kemudian kepada peringkat tertentu dan tugas individunya. Ia membandingkan tempoh, rekod dan bait bacaan shuffle, limpahan, memori pelaksanaan puncak, dan masa GC. Tugas yang membaca beratus-ratus kali ganda median dan kekal perlahan apabila dicuba semula pada pelaksana (executor) lain menyokong kepencongan data yang deterministik. Memori pelaksana agregat dan jumlah masa jalanan sahaja tidak membuktikan punca tersebut.

Kemahiran membaca pelan pelaksanaan adalah sama penting. EXPLAIN FORMATTED mengesahkan Exchange, jenis cantuman, dan cantuman fizikal. EXPLAIN COST dan statistik masa jalanan dalam SQL UI mendedahkan anggaran dan saiz data yang diperhatikan. Spark AQE menggunakan statistik masa jalanan untuk melaraskan pelan. Dalam Spark 4.2.0, pengoptimuman cantuman pencong (skew-join) boleh membahagikan partisi sort-merge-join yang pencong dan mereplikasi bahagian yang lebih kecil apabila diperlukan. Nilai lalai yang didokumenkan menandakan partisi sebagai pencong hanya apabila ia melebihi kedua-dua lima kali median dan 256 MiB. Calon harus memeriksa konfigurasi persekitaran yang berkuat kuasa kerana nilai lalai dokumentasi bukanlah fakta kluster yang tidak boleh diubah.

Semantik data menjadi garis pemisah. UNKNOWN mungkin merupakan peristiwa “tidak diatribusikan” yang sah atau kecacatan huluan. Menggugurkan, mengagihkan secara rawak, atau menulis semula baris tersebut boleh mengubah hasil. Cantuman bergaram (salted join) mesti mereplikasi hanya baris kunci panas daripada dimensi dan memberikan garam deterministik kepada baris fakta panas. Mereplikasi keseluruhan dimensi menggandakan volum data, manakala merawakkan kedua-dua belah pihak secara bebas akan menghilangkan padanan.

Pemilihan pemulihan mendedahkan satu lagi tahap kedalaman. Meningkatkan spark.sql.shuffle.partitions mencipta lebih banyak baldi cincangan (hash buckets), tetapi setiap baris untuk satu kunci panas masih mendarat dalam satu baldi. Broadcast hanya sesuai apabila unjuran (projection), penapisan, dan statistik yang boleh dipercayai membuktikan bahawa satu bahagian muat dengan selamat pada setiap pelaksana; memaksa dimensi 180 GB untuk di-broadcast adalah tidak selamat. AQE ialah pilihan pertama dengan pencerobohan rendah. Salting eksplisit sesuai untuk kunci panas yang stabil apabila AQE tidak dicetuskan atau masih terlepas SLA. Pengagregatan sering menggunakan pengagregatan separa bergaram diikuti oleh penggabungan kedua.

Pengesahan lengkap menutup jawapan. Pembaikan prestasi juga mesti membuktikan bahawa bilangan baris, jumlah perniagaan, kunci tidak diketahui, kadar tidak sepadan, dan kadar pendua tidak berubah. Mengurangkan masa jalanan daripada 96 kepada 40 minit tidak membuktikan ketepatan atau menunjukkan sama ada penyelesaian itu bertahan terhadap taburan kunci yang berbeza pada hari esok.

Soalan untuk Dijelaskan Sebelum Menjawab

  • Adakah kesesakan (bottleneck) dalam imbasan (scan), penulisan shuffle, atau selepas bacaan shuffle? Tugas imbasan yang tidak sekata mungkin datang daripada fail yang besar atau tidak boleh dibahagikan. Gesaan ini mencapai laluan kepencongan kunci kerana nilai luar biasa muncul selepas shuffle cantuman.
  • Adakah 32% merujuk kepada rekod, bait mampat, atau kos pemprosesan? Baris lebar, UDF mahal, dan pelebaran output (fan-out) boleh mencipta kepencongan kos walaupun bilangan baris kelihatan sederhana. Bandingkan rekod, bait, masa, dan baris output.
  • Apakah maksud UNKNOWN kepada perniagaan? Jika produk yang tidak diketahui tidak memerlukan atribut dimensi, asingkannya daripada cantuman utama dan isi atribut null di bawah kontrak asal. Jika ia mesti sepadan dengan baris dimensi sentri (sentinel), kekalkan cantuman dan bahagikan titik panas tersebut.
  • Adakah product_id unik dalam dimensi produk? Beberapa baris dimensi UNKNOWN mengubah kunci fakta panas menjadi letupan output banyak-ke-banyak. Asingkan kardinaliti yang buruk daripada kepencongan partisi sebelum penalaan.
  • Versi Spark dan tetapan AQE manakah yang berkuat kuasa? Semak halaman Environment dan pelan penyesuaian akhir untuk suis, ambang, jenis cantuman, dan bukti bahawa pembahagian kepencongan benar-benar dijalankan.
  • Adakah 180 GB merupakan dimensi asal atau input cantuman yang diunjurkan? Jika menapis kepada kunci dan dua atribut menjadikannya selamat untuk di-broadcast, broadcast mungkin menewaskan shuffle dua belah pihak. Statistik masa jalanan dan belanjawan memori pelaksana mesti membuktikan kes itu.
  • Invarian manakah yang mentakrifkan hasil yang setara? Sekurang-kurangnya, tentukan jumlah baris, peristiwa unik, ukuran perniagaan aditif, baris kunci tidak diketahui, baris tidak sepadan, dan semantik pendua yang dibenarkan.
  • Adakah kunci panas stabil dan boleh dienumerasikan? Beberapa kunci stabil sesuai dengan salting bersasar. Ekor panjang yang berubah-ubah memihak kepada AQE, pengesanan kunci panas dinamik, atau pembetulan semantik huluan.

Rangka Kerja Jawapan 30 Saat

“Saya akan membandingkan bacaan shuffle tugas cantuman, limpahan, GC, dan lokasi percubaan semula dalam SQL UI. Tugas 720 GiB berbanding median 1.1 GiB, ditambah 32% UNKNOWN, menyokong kepencongan kunci; saya juga akan mengesahkan keunikan dimensi untuk mengecualikan letupan output. Mula-mula saya akan mengesahkan bahawa AQE skew join membahagikan partisi besar tersebut. Jika masa jalanan masih melebihi 45 minit, saya akan mengenakan garam pada UNKNOWN secara deterministik melalui event_id yang stabil dan mereplikasi hanya baris sentrinya. Akhir sekali, saya akan menyelaraskan baris dan jumlah dengan garis dasar, kemudian membandingkan input tugas maksimum-ke-median, masa peringkat, dan kos.”

Jawapan Mendalam Langkah demi Langkah

Langkah 1: Atribusikan 96 minit kepada peringkat dan tugas

Simpan log peristiwa dan gunakan Spark History Server untuk membandingkan larian biasa dan terjejas bagi tarikh data yang sama. Ikuti pertanyaan SQL ke dalam butiran peringkatnya. Catat persentil dan tempoh tugas maksimum, sejajar dengan rekod dan bait bacaan shuffle, limpahan shuffle, memori pelaksanaan puncak, masa GC, sebab kegagalan, dan pelaksana. Dalam pelan SQL, semak Exchange hashpartitioning(product_id, 2000) sebelum left-join, kenal pasti cantuman fizikal akhir, dan tentukan sama ada pelan penyesuaian telah selesai.

Di sini, tugas yang sama masih membaca kira-kira 720 GiB selepas mencuba semula pada pelaksana lain, manakala kebanyakan tugas membaca kira-kira 1.1 GiB. Itu menunjukkan kepada partisi input itu sendiri. Jika tugas perlahan mempunyai input biasa dan GC tinggi atau penantian cakera pada satu pelaksana, siasat nod terlebih dahulu. Jika setiap tugas melimpah secara seragam, fokus pada saiz partisi keseluruhan dan belanjawan sumber. Jika baris output berganda secara tiba-tiba, periksa pendua dimensi dan syarat cantuman.

Langkah 2: Buktikan punca dengan taburan kunci dan kardinaliti cantuman

Ukur kunci panas selepas menggunakan penapis dan penormalan kunci yang betul-betul sama seperti yang digunakan oleh pengeluaran. Memeriksa lajur mentah adalah tidak mencukupi kerana trim, penormalan huruf, coalesce, atau UDF mungkin mencantumkan beberapa nilai menjadi satu kunci. Pada jadual yang sangat besar, gunakan statistik sedia ada, sampel terkawal, atau pengagregatan terikat supaya diagnostik tidak menjadi satu lagi tugasan tanpa kekangan. Pertanyaan di bawah menganggap bahawa jadual fakta sudah mengandungi atau mengira awal payload_bytes, membolehkan kepencongan baris dan bait diukur. Tanpa lajur itu, gunakan statistik storan atau anggaran pensirian terkawal. Pertanyaan ini menyatakan perakaunan yang diperlukan:

sql
SELECT
  COALESCE(product_id, '<NULL>') AS join_key,
  COUNT(*) AS row_count,
  SUM(payload_bytes) AS payload_bytes
FROM fact_events
WHERE event_date = DATE '2026-07-17'
GROUP BY COALESCE(product_id, '<NULL>')
ORDER BY row_count DESC
LIMIT 20;

Buktikan juga bahawa setiap product_id muncul paling banyak sekali dalam dimensi dan bandingkan kiraan peristiwa fakta sebelum dan selepas cantuman. Untuk left-join ini, kunci dimensi yang unik bermakna setiap peristiwa fakta menghasilkan tepat satu baris, termasuk peristiwa yang tidak sepadan. Jika UNKNOWN memiliki 32% baris fakta, dimensi mempunyai satu baris sentri, dan output tidak berganda, pembahagian cincangan (hash partitioning) menerangkan partisi tunggal 720 GiB tersebut.

Langkah 3: Tangani punca semantik sebelum memilih teknik pelaksanaan

Siasat mengapa pelepasan huluan memetakan 32% peristiwa kepada UNKNOWN. Jika ia adalah regresi, undurkan (roll back) atau betulkan pemetaan dan jalankan semula partisi yang terjejas. Itu memulihkan kedua-dua kualiti data dan prestasi. Jika ia adalah nilai perniagaan yang sah, lapisan pelaksanaan mesti menyokong taburan tersebut.

Peristiwa tidak diketahui yang sah yang tidak memerlukan atribut produk boleh mengambil laluan berasingan: cantumkan kunci sejuk secara normal, isi atribut dimensi dengan null untuk laluan tidak diketahui di bawah kontrak sedia ada, dan gabungkan dengan unionByName. Itu membuang shuffle tanpa kehilangan maklumat. Jika UNKNOWN mesti sepadan dengan atribut sentri, kekalkan cantuman dan bahagikan kerja dengan AQE atau salting bersasar. Semantik hasil menentukan cabang; partisi seragam bukan kebenaran untuk membuang data.

Langkah 4: Pilih pemulihan paling murah yang berkesan

Semak AQE dahulu. Dalam Spark 4.2.0, spark.sql.adaptive.enabled dan spark.sql.adaptive.skewJoin.enabled ditetapkan secara lalai kepada didayakan, tetapi kluster, tugasan, atau platform terurus boleh mengatasi (override) tetapan tersebut. Faktor skew-join dan ambang bait mutlak kedua-duanya mesti sepadan. Periksa pelan penyesuaian akhir untuk pengendalian kepencongan dan sahkan bahawa metrik peringkat menunjukkan pembahagian partisi besar tersebut. Untuk sort-merge join yang serasi, AQE boleh membahagikan bahagian besar dan mereplikasi bahagian yang lebih kecil. Ia menyesuaikan diri dengan taburan harian yang berubah, tetapi mungkin menambah kos shuffle dan replikasi, dan ia tidak dapat membaiki cantuman banyak-ke-banyak yang salah dari segi logik.

Jika dimensi yang diunjurkan mempunyai statistik yang boleh dipercayai dan benar-benar kecil, nilailah broadcast hash join supaya bahagian fakta tidak melakukan shuffle pada kunci cantuman. 180 GB asal berada jauh di luar belanjawan broadcast biasa. Petunjuk (hint) yang dipaksa boleh menghabiskan memori setiap pelaksana. Nilai bait yang diunjurkan, tugas serentak, heap pelaksana, dan tamat masa broadcast secara bersama.

Apabila AQE tidak dicetuskan atau masih terlepas SLA, kenakan garam secara manual pada kunci panas yang stabil. Kod berikut menganggap bahawa event_id adalah stabil dan unik, product_id adalah unik dalam dimensi, dan hanya UNKNOWN yang perlu dibahagikan. Baris fakta panas dipetakan secara deterministik kepada 32 garam. Hanya baris dimensi sentri yang sepadan direplikasi sebanyak 32 kali. Kunci sejuk kekal pada garam 0, jadi dimensi penuh tidak pernah digandakan.

python
from pyspark.sql import functions as F

SALT_BUCKETS = 32
HOT_KEYS = ["UNKNOWN"]

events_salted = events.withColumn(
    "salt",
    F.when(
        F.col("product_id").isin(*HOT_KEYS),
        F.pmod(F.xxhash64("event_id"), F.lit(SALT_BUCKETS)).cast("int"),
    ).otherwise(F.lit(0)),
)

salt_values = spark.range(SALT_BUCKETS).select(
    F.col("id").cast("int").alias("salt")
)

products_hot = (
    products.filter(F.col("product_id").isin(*HOT_KEYS))
    .crossJoin(salt_values)
)
products_cold = (
    products.filter(~F.col("product_id").isin(*HOT_KEYS))
    .withColumn("salt", F.lit(0))
)
products_salted = products_cold.unionByName(products_hot)

result = (
    events_salted.join(products_salted, ["product_id", "salt"], "left")
    .drop("salt")
)

Tiga puluh dua ialah calon awal di bawah senario temu bual ini. Dapatkan kiraan baldi daripada bait partisi panas, saiz tugas sasaran, keselarian (parallelism) yang tersedia, dan kos replikasi bahagian kecil, kemudian uji pada data wakil. Baldi yang terlalu sedikit mengekalkan ekor panjang. Terlalu banyak menambah overhed penjadualan, fail, dan replikasi. Hanya menjalankan repartition(4000, "product_id") masih meletakkan setiap baris UNKNOWN dalam satu partisi.

Untuk groupBy(product_id), biasanya tiada dimensi untuk direplikasi. Mula-mula lakukan pengagregatan separa mengikut (product_id, salt), kemudian gabungkan hasil separa mengikut product_id. Operasi yang boleh diuraikan secara selamat dengan penggabungan bersekutu (associative) dan kalis tukar tertib (commutative), seperti sum, count, min, dan max, sesuai dengan teknik ini. median tepat, pengagregatan bergantung susunan, dan keadaan UDF yang tidak boleh digabungkan memerlukan algoritma yang berbeza.

Langkah 5: Letakkan ketepatan, prestasi, dan kos dalam satu pintu penerimaan (acceptance gate)

Jalankan garis dasar dan calon terhadap satu snapshot input yang tidak boleh diubah. Ketepatan diutamakan: bandingkan jumlah baris output, event_id unik, baris UNKNOWN, baris tidak sepadan, dan jumlah serta kiraan perniagaan mengikut dimensi yang bermakna. Ambil perbezaan peringkat baris untuk kunci panas, kunci sejuk, null, dan kunci dimensi pendua. Jaminan bahawa satu peristiwa fakta menghasilkan satu baris left-join bergantung pada keunikan kunci dimensi, jadi pantau kekangan itu secara berasingan.

Untuk prestasi, bandingkan p50, p95, dan tempoh tugas maksimum dalam peringkat cantuman, bacaan shuffle maksimum-ke-median, limpahan, GC, OOM, percubaan semula tugas, masa peringkat, dan jumlah masa jalanan. Untuk kos, catat jam-pelaksana (executor-hours), bait shuffle, dan kiraan fail output. Menyelesaikan dalam masa 45 minit hanyalah satu pintu penerimaan. Larian yang memenuhi SLA dengan menggandakan shuffle, mengubah hasil, atau gagal pada titik panas baharu keesokan harinya adalah tidak boleh diterima.

Lepaskan dengan memainkan semula satu tarikh sejarah, kemudian lakukan pemantauan bayang (shadowing) pada tarikh data baharu dan bandingkan hasilnya. Pantau set kunci panas, nisbah input tugas maksimum-ke-median, dan bahagian kunci tidak diketahui. Lonjakan kepada 32% UNKNOWN selepas pelepasan huluan juga harus mencetuskan amaran kualiti data, mendedahkan regresi semantik sebelum ia melambatkan tugasan.

Contoh Jawapan Berkualiti Tinggi

“Mula-mula saya akan mengatribusikan regresi kepada peringkat cantuman tertentu dalam SQL UI. Bukti semasa sangat mencadangkan kepencongan: merentasi 2,000 tugas, median bacaan shuffle ialah 1.1 GiB, satu tugas membaca 720 GiB, dan tugas itu kekal perlahan selepas beralih ke pelaksana lain. Saya akan memeriksa pelan penyesuaian akhir, limpahan, dan GC, kemudian memprofilkan kunci selepas penormalan pengeluaran yang tepat. Saya juga akan menegaskan keunikan kunci dimensi. Pelbagai baris dimensi UNKNOWN akan bermakna simptom tersebut merangkumi letupan output cantuman.

Dengan mengandaikan dimensi unik dan 32% baris fakta UNKNOWN, satu baldi hash-shuffle menerangkan tugas yang lembap. Lebih banyak partisi mencipta baldi tambahan tetapi tidak membahagikan kunci tersebut, dan memori pelaksana yang lebih banyak hanya menangguhkan OOM. Mula-mula saya akan menentukan sama ada pemetaan huluan ialah satu regresi. Jika baris tidak diketahui tidak memerlukan atribut dimensi, saya akan mengasingkannya daripada cantuman dan mengisi atribut null dengan semantik left-join asal. Jika ia mesti sepadan dengan baris sentri, saya akan mengesahkan bahawa AQE skew join benar-benar muncul dalam pelan akhir kerana ia boleh membahagikan partisi sort-merge-join yang pencong menggunakan statistik masa jalanan dan mereplikasi bahagian yang kecil.

Jika AQE masih meninggalkan masa jalanan melebihi 45 minit, saya akan menggunakan salting bersasar. event_id yang stabil akan menetapkan setiap baris fakta UNKNOWN secara deterministik kepada, contohnya, salah satu daripada 32 garam. Saya akan mereplikasi hanya baris UNKNOWN dimensi merentasi 32 garam tersebut; setiap kunci sejuk akan menggunakan garam 0. Setiap peristiwa masih sepadan dengan satu baris dimensi, manakala beberapa tugas berkongsi kerja kunci panas. Saya akan memperoleh kiraan baldi akhir daripada bait titik panas dan saiz tugas sasaran dan bukannya mengekod keras 32 tanpa pengukuran.

Untuk pengesahan, saya akan membandingkan input tidak boleh diubah yang sama dengan garis dasar. Jumlah baris, peristiwa unik, rekod tidak diketahui dan tidak sepadan, serta jumlah perniagaan mesti sepadan. Saya kemudiannya akan membandingkan bacaan shuffle maksimum-ke-median, ekor tempoh tugas, limpahan, OOM, masa peringkat, jam-pelaksana, dan fail output. Akhir sekali, saya akan memainkan semula satu tarikh sejarah, membayangi satu tarikh baharu, dan memberi amaran tentang perkongsian kunci tidak diketahui serta titik panas baharu. Itu membuktikan tugasan memenuhi 45 minit, mengekalkan hasil, dan kekal boleh diperhatikan apabila taburan huluan berubah lagi.”

Kesilapan Biasa

  • Menaikkan partisi shuffle daripada 2,000 kepada 8,000 serta-merta → satu kunci panas masih mencincang ke satu partisi manakala tugas lain menjadi lebih kecil → ukur taburan kunci, kemudian bahagikan kunci dengan AQE, percabangan semantik, atau salting bersasar.
  • Hanya meningkatkan memori pelaksana → ia meningkatkan toleransi satu tugas tetapi meninggalkan 720 GiB kerja dan ekor panjang utuh → kurangkan beban kerja partisi maksimum dahulu, kemudian tentukan saiz sumber daripada tugas yang diukur.
  • Mengisytiharkan kepencongan selepas melihat satu tugas perlahan → nod yang buruk, GC, pengambilan jauh (remote fetch), atau UDF yang perlahan juga boleh mencipta tugas lembap → bandingkan input tugas, lokasi percubaan semula, limpahan, GC, dan pelan pelaksanaan.
  • Mengenakan garam secara rawak pada fakta dan dimensi secara berasingan → garam gagal sepadan dan menghilangkan hasil cantuman, manakala percubaan semula boleh menjadi tidak deterministik → peroleh garam fakta daripada ID baris yang stabil dan enumerasikan garam yang sama pada dimensi.
  • Mereplikasi dimensi penuh sebanyak 32 kali → dimensi 180 GB mencipta kos rangkaian dan memori yang sangat besar → replikasi hanya baris kunci panas yang disahkan dan kekalkan kunci sejuk pada garam 0.
  • Memaksa dimensi 180 GB untuk di-broadcast → setiap pelaksana mesti memegang data broadcast dan mungkin gagal dengan OOM → unjurkan dan ukur dahulu; broadcast hanya selepas belanjawan memori dan keserentakan membuktikannya selamat.
  • Menapis UNKNOWN untuk menjadikan tugasan cepat → semantik output dan metrik hiliran berubah → tetapkan kontrak peristiwa tidak diketahui dan kekalkan hasil left-join walaupun semasa mencabang.
  • Hanya membandingkan jumlah masa jalanan → peningkatan kelajuan yang ketara mungkin datang daripada data yang digugurkan, diduplikasi, atau salah dikira → buktikan invarian baris dan perniagaan sebelum membandingkan taburan tugas, kos, dan SLA.

Soalan Susulan dan Cara Menjawab

AQE didayakan. Mengapakah cantuman yang pencong tidak dibahagikan?

Periksa pelan penyesuaian akhir dan tetapan berkuat kuasa untuk spark.sql.adaptive.enabled, suis skew-join, ambang faktor median, dan ambang bait mutlak. Kedua-dua ambang mesti sepadan. Sahkan bahawa cantuman fizikal mengikut laluan AQE yang disokong, statistik masa jalanan tersedia, dan petunjuk atau penggantian platform tidak mengekang pelan. Uji perubahan ambang atau pengoptimuman kepencongan yang dipaksa pada data wakil sambil mengukur shuffle tambahan. Jika pelan tidak dapat memanfaatkannya, gunakan salting bersasar. Nilai true dalam fail konfigurasi tidak membuktikan bahawa pelan yang dilaksanakan telah membahagikan partisi.

Jika unjuran mengurangkan dimensi kepada 6 GiB, bolehkah anda mem-broadcast-kannya?

Enam GiB masih memerlukan penilaian heap pelaksana, tugas serentak, saiz bersiri, tamat masa broadcast, dan kestabilan kluster. Broadcast boleh membuang shuffle kunci cantuman bahagian besar dan seterusnya mengelakkan titik panas, tetapi ia juga menyalin dimensi ke pelaksana. Gunakan statistik untuk membuktikan bait sebenar, kemudian perhatikan memori puncak dan GC dalam ujian beban berbentuk pengeluaran sebelum menambah petunjuk. “Jauh lebih kecil daripada jadual fakta” bukanlah kriteria broadcast yang mencukupi.

Bagaimana jika kunci panas berubah setiap hari dan HOT_KEYS tidak dapat dikekalkan secara manual?

Utamakan tindak balas masa jalanan AQE. Jika salting eksplisit masih diperlukan, hasilkan jadual kunci panas terikat sebelum tugasan utama menggunakan ambang rekod, bait, atau kos, kemudian broadcast jadual kecil itu untuk memilih laluan bergaram. Versikan senarai mengikut tarikh data dan berikan ia ambang, had kiraan, dan sandaran (fallback). Ini menambah peringkat perancangan dan keadaan operasi, jadi keuntungan SLA yang stabil mesti mewajarkan kerumitan tersebut.

Jika operasi yang perlahan ialah groupBy, adakah anda masih mereplikasi dimensi?

Tidak. Untuk pengagregatan yang boleh digabungkan, kenakan garam pada baris panas, kira agregat separa mengikut (key, salt), kemudian gabungkan separa tersebut mengikut key. Itu mengagihkan input satu kunci panas merentasi tugas, manakala peringkat kedua memproses sebilangan kecil separa. Nyatakan sama ada agregat boleh digabungkan dengan selamat. Keadaan tersusun secara global atau tidak boleh digabungkan tidak boleh menggunakan teknik ini tanpa algoritma yang berbeza.

Bagaimanakah anda memilih 32 baldi garam?

Bahagikan bait partisi panas dengan input tugas sasaran untuk had bawah, kemudian ambil kira teras yang tersedia, replikasi bahagian kecil, overhed penjadual, dan kekangan fail output. Jika 720 GiB sepatutnya jatuh kepada kira-kira 32 GiB setiap tugas, had bawah teori adalah kira-kira 23, jadi 32 ialah eksperimen yang munasabah dalam senario ini. Bandingkan beberapa calon pada input tugas maksimum, masa peringkat, dan jam-pelaksana, serta kekalkan ruang tambahan terhad untuk pertumbuhan titik panas.

Bolehkah pelaksanaan spekulatif (speculative execution) menyelesaikan tugas lembap ini?

Pendua tugas pencong deterministik masih membaca partisi 720 GiB yang sama, biasanya mengulangi kerja yang mahal pada dua pelaksana. Spekulasi lebih berguna untuk nod yang perlahan secara berselang-seli atau kegelisahan sementara (transient jitter). Semak sama ada tugas yang sama kekal perlahan selepas mencuba semula di tempat lain. Jika inputnya kekal sebagai nilai luar biasa, bahagikan kerja data tersebut dan bukannya menduplikasikannya.

Sumber awam

Soalan berkaitan