Tepat satu kali di Dataflow

Dataflow mendukung pemrosesan data tepat satu kali. Halaman ini menjelaskan cara Dataflow menerapkan pemrosesan tepat satu kali sekaligus memastikan latensi rendah.

Ringkasan

Pipeline batch selalu menggunakan pemrosesan tepat satu kali. Pipeline streaming menggunakan pemrosesan tepat satu kali secara default, tetapi juga dapat menggunakan pemrosesan minimal satu kali.

Pemrosesan tepat satu kali memberikan jaminan tentang hasil pemrosesan data, termasuk hasil dari setiap tahap pipeline. Secara khusus, untuk setiap data yang masuk ke pipeline dari sumber, atau tiba di tahap dari tahap sebelumnya, Dataflow memastikan hal berikut:

  • Kumpulan data diproses dan tidak hilang.
  • Setiap hasil pemrosesan yang tetap berada dalam pipeline paling banyak akan ditampilkan satu kali.

Dengan kata lain, data diproses minimal sekali, dan hasilnya di-commit tepat satu kali.

Pemrosesan tepat satu kali memastikan bahwa hasilnya akurat, tanpa data duplikat dalam output. Dataflow dioptimalkan untuk meminimalkan latensi sekaligus mempertahankan semantik tepat satu kali. Namun, pemrosesan tepat satu kali masih memerlukan biaya untuk melakukan penghapusan duplikat. Untuk kasus penggunaan yang dapat menerima data duplikasi, Anda sering kali dapat mengurangi biaya dan meningkatkan latensi dengan mengaktifkan mode setidaknya sekali. Untuk mengetahui informasi selengkapnya tentang cara memilih antara streaming tepat satu kali dan setidaknya satu kali, lihat Menetapkan mode streaming pipeline.

Data terlambat

Pemrosesan tepat satu kali memastikan akurasi pipeline: Jika pipeline memproses data, Dataflow akan memastikan bahwa data tersebut ditampilkan dalam output, dan bahwa data tersebut tidak diduplikasi.

Namun, dalam pipeline streaming, pemrosesan exactly-once tidak dapat menjamin bahwa hasilnya selesai, karena data mungkin terlambat. Misalnya, misalnya pipeline Anda melakukan agregasi selama jangka waktu, seperti Count. Dengan pemrosesan tepat sekali, hasilnya akurat untuk data yang tiba dalam periode waktu tepat waktu, tetapi data yang terlambat mungkin dihapus.

Umumnya, tidak ada cara untuk menjamin kelengkapan dalam pipeline streaming, karena secara teori, data dapat tiba terlambat secara arbitrer. Dalam kasus batas, Anda harus menunggu selamanya untuk menghasilkan hasil. Secara lebih praktis, Apache Beam memungkinkan Anda mengonfigurasi nilai minimum untuk menghapus data yang terlambat dan kapan harus menampilkan hasil gabungan. Untuk informasi selengkapnya, lihat Watermark dan data terlambat dalam dokumentasi Apache Beam.

Efek samping

Efek samping tidak dijamin memiliki semantik tepat satu kali. Yang penting, hal ini mencakup penulisan output ke penyimpanan eksternal, kecuali jika sink juga menerapkan semantik tepat satu kali.

Secara khusus, Dataflow tidak menjamin bahwa setiap data akan melalui setiap transformasi tepat satu kali. Karena percobaan ulang atau kegagalan pekerja, Dataflow dapat mengirim data melalui transformasi beberapa kali, atau bahkan secara bersamaan di beberapa pekerja.

Sebagai bagian dari pemrosesan tepat satu kali, Dataflow menghapus duplikat output. Namun, jika kode dalam transformasi memiliki efek samping, efek tersebut mungkin terjadi beberapa kali. Misalnya, jika transformasi melakukan panggilan layanan jarak jauh, panggilan tersebut dapat dilakukan beberapa kali untuk data yang sama. Efek samping bahkan dapat menyebabkan hilangnya data dalam beberapa situasi. Misalnya, anggaplah bahwa transformasi membaca file untuk menghasilkan output, lalu segera menghapus file tanpa menunggu output di-commit. Jika terjadi error saat melakukan commit pada hasil, Dataflow akan mencoba lagi transformasi, tetapi sekarang transformasi tidak dapat membaca file yang dihapus.

Logging

Output log dari pemrosesan menunjukkan bahwa pemrosesan terjadi, tetapi tidak menunjukkan apakah data di-commit. Oleh karena itu, file log mungkin menunjukkan bahwa data diproses beberapa kali meskipun hasil data yang diproses hanya di-commit ke penyimpanan persisten satu kali. Selain itu, log tidak selalu mencerminkan data yang diproses dan di-commit. Log mungkin dihapus karena pembatasan atau hilang karena masalah layanan logging lainnya.

Streaming tepat satu kali

Bagian ini menjelaskan cara Dataflow menerapkan pemrosesan tepat sekali untuk tugas streaming, termasuk cara Dataflow mengelola kompleksitas seperti pemrosesan non-deterministik, data terlambat, dan kode kustom.

Shuffle streaming dataflow

Tugas Streaming Dataflow berjalan di banyak pekerja yang berbeda secara paralel dengan menetapkan rentang tugas ke setiap pekerja. Meskipun tugas dapat berubah dari waktu ke waktu sebagai respons terhadap kegagalan pekerja, penskalaan otomatis, atau peristiwa lainnya, setelah setiap transformasi GroupByKey, semua data dengan kunci yang sama akan diproses di pekerja yang sama. Transformasi GroupByKey sering digunakan oleh transformasi gabungan, seperti Count, FileIO, dan sebagainya. Untuk memastikan bahwa data untuk kunci tertentu berakhir di pekerja yang sama, pekerja Dataflow mengacak data di antara mereka sendiri menggunakan panggilan prosedur jarak jauh (RPC).

Untuk menjamin bahwa data tidak hilang selama pengacakan, Dataflow menggunakan pencadangan upstream. Dengan pencadangan upstream, pekerja yang mengirim data akan mencoba ulang RPC hingga menerima konfirmasi positif bahwa data telah diterima. Efek samping pemrosesan data di-commit ke penyimpanan persisten di downstream. Jika pekerja yang mengirim data tidak tersedia, Dataflow akan terus mencoba ulang RPC, yang memastikan bahwa setiap data dikirim setidaknya sekali.

Karena percobaan ulang ini dapat membuat duplikat, setiap pesan diberi tag dengan ID unik. Setiap penerima menyimpan katalog semua ID yang telah dilihat dan diproses. Saat data diterima, Dataflow akan mencari ID-nya di katalog. Jika ID ditemukan, data telah diterima dan di-commit, dan dihapus sebagai duplikat. Untuk memastikan ID kumpulan data stabil, setiap output dari langkah ke langkah akan di-checkpoint ke penyimpanan. Akibatnya, jika pesan yang sama dikirim beberapa kali karena panggilan RPC berulang, pesan tersebut hanya di-commit ke penyimpanan sekali.

Memastikan latensi rendah

Agar pemrosesan exactly-once dapat dilakukan, I/O harus dikurangi, terutama dengan mencegah I/O pada setiap data. Untuk mencapai tujuan ini, Dataflow menggunakan filter Bloom dan pembersihan sampah.

Filter bloom

Filter Bloom adalah struktur data ringkas yang memungkinkan pemeriksaan keanggotaan set dengan cepat. Di Dataflow, setiap pekerja menyimpan filter Bloom dari setiap ID yang dilihatnya. Saat ID data baru tiba, pekerja akan mencari ID tersebut di filter. Jika filter menampilkan nilai salah, berarti kumpulan data ini bukan duplikat, dan pekerja tidak mencari ID dalam penyimpanan stabil.

Dataflow menyimpan kumpulan filter Bloom bergulir yang dikelompokkan berdasarkan waktu. Saat data tiba, Dataflow akan memilih filter yang sesuai untuk diperiksa berdasarkan stempel waktu sistem. Langkah ini mencegah filter Bloom jenuh saat filter dikumpulkan sampahnya, dan juga membatasi jumlah data yang perlu dipindai saat memulai.

Pembersihan sampah memori

Untuk menghindari pengisian penyimpanan dengan ID data, Dataflow menggunakan pengumpulan sampah untuk menghapus data lama. Dataflow menggunakan stempel waktu sistem untuk menghitung watermark pembersihan sampah.

Stempel waktu ini didasarkan pada jumlah waktu fisik yang dihabiskan untuk menunggu di tahap tertentu. Oleh karena itu, laporan ini juga memberikan informasi tentang bagian pipeline mana yang lambat. Metadata ini adalah dasar untuk metrik jeda sistem yang ditampilkan di Antarmuka pemantauan Dataflow.

Jika data tiba dengan stempel waktu yang lebih lama dari stempel waktu, dan jika ID untuk waktu ini telah dihapus, data akan diabaikan. Karena stempel waktu rendah yang memicu pengumpulan sampah tidak maju hingga pengiriman data dikonfirmasi, data yang terlambat tiba ini merupakan duplikat.

Sumber non-deterministik

Dataflow menggunakan Apache Beam SDK untuk membaca data ke dalam pipeline. Jika pemrosesan gagal, Dataflow mungkin akan mencoba kembali pembacaan dari sumber. Dalam situasi tersebut, Dataflow perlu memastikan bahwa setiap data unik yang dihasilkan oleh sumber dicatat tepat satu kali. Untuk sumber deterministik, seperti Pub/Sub Lite atau Kafka, data dibaca berdasarkan offset yang dicatat, sehingga mengurangi kebutuhan akan langkah ini.

Karena Dataflow tidak dapat menetapkan ID data secara otomatis, sumber non-deterministik harus memberi tahu Dataflow ID datanya untuk menghindari duplikasi. Saat sumber memberikan ID unik untuk setiap data, konektor menggunakan pengacakan dalam pipeline untuk menghapus duplikat. Data dengan ID yang sama akan difilter. Untuk contoh cara Dataflow menerapkan pemrosesan tepat satu kali saat menggunakan Pub/Sub sebagai sumber, lihat bagian Pemrosesan tepat satu kali di halaman Streaming dengan Pub/Sub.

Saat Anda mengeksekusi DoFn kustom sebagai bagian dari pipeline, Dataflow tidak menjamin bahwa kode ini hanya dijalankan satu kali per data. Untuk menjamin pemrosesan setidaknya satu kali jika pekerja gagal, Dataflow dapat menjalankan kumpulan data tertentu melalui transformasi beberapa kali, atau dapat menjalankan kumpulan data yang sama secara bersamaan di beberapa pekerja. Jika Anda menyertakan kode dalam pipeline yang melakukan hal-hal seperti menghubungi layanan luar, tindakan tersebut mungkin dijalankan lebih dari sekali untuk data tertentu.

Untuk membuat pemrosesan non-deterministik secara efektif deterministik, gunakan checkpointing. Saat Anda menggunakan checkpointing, setiap output dari transformasi akan di-checkpoint ke penyimpanan stabil dengan ID uniknya sebelum dikirim ke tahap berikutnya. Percobaan ulang dalam pengiriman shuffle Dataflow akan meneruskan output yang telah di-checkpoint. Meskipun kode Anda mungkin berjalan beberapa kali, Dataflow memastikan bahwa output hanya dari salah satu operasi tersebut yang disimpan. Dataflow menggunakan penyimpanan konsisten yang mencegah duplikat ditulis ke penyimpanan stabil.

Pengiriman output tepat satu kali

Apache Beam SDK menyertakan sink bawaan yang dirancang untuk memastikan bahwa sink tersebut tidak menghasilkan duplikat. Jika memungkinkan, gunakan salah satu sink bawaan ini.

Jika Anda perlu menulis sink sendiri, pendekatan terbaiknya adalah membuat objek fungsi Anda idempoten sehingga dapat dicoba ulang sesering yang diperlukan tanpa menyebabkan efek samping yang tidak diinginkan. Namun, sering kali beberapa komponen transformasi yang mengimplementasikan fungsi sink bersifat non-deterministik dan dapat berubah jika dicoba lagi.

Misalnya, dalam agregasi berbingkai, kumpulan data dalam jendela mungkin non-deterministik. Secara khusus, jendela mungkin mencoba diaktifkan dengan elemen e0, e1, e2. Pekerja mungkin mengalami error sebelum melakukan pemrosesan jendela, tetapi tidak sebelum elemen tersebut dikirim sebagai efek samping. Saat pekerja dimulai ulang, jendela akan diaktifkan lagi, dan elemen terlambat e3 akan tiba. Karena elemen ini tiba sebelum jendela di-commit, elemen ini tidak dihitung sebagai data terlambat, sehingga DoFn dipanggil lagi dengan elemen e0, e1, e2, e3. Elemen ini kemudian dikirim ke operasi efek samping. Idempotency tidak membantu dalam skenario ini, karena kumpulan data logis yang berbeda dikirim setiap kali.

Untuk mengatasi ketidakpastian di Dataflow, gunakan transformasi Reshuffle bawaan. Saat mengacak data, Dataflow akan menulis data secara permanen sehingga setiap elemen yang dihasilkan secara non-deterministik akan stabil jika operasi dicoba lagi setelah pengurutan acak terjadi. Penggunaan transformasi Reshuffle menjamin bahwa hanya satu versi output DoFn yang dapat melewati batas pengacakan. Pola berikut memastikan bahwa operasi efek samping selalu menerima data deterministik untuk output:

c.apply(Window.<..>into(FixedWindows.of(Duration.standardMinutes(1))))
 .apply(GroupByKey.<..>.create())
 .apply(new PrepareOutputData())
 .apply(Reshuffle.<..>of())
 .apply(WriteToSideEffect());

Untuk memastikan bahwa runner Dataflow mengetahui bahwa elemen harus stabil sebelum menjalankan DoFn, tambahkan anotasi RequiresStableInput ke DoFn.

Pelajari lebih lanjut