Hai, habrozhiteli!
Kami memutuskan untuk berbagi terjemahan bab "Sistem berdasarkan antrian tugas" Dari kebaruan mendatang "Sistem terdistribusi. Pola desain β(sudah ada di percetakan).
Bentuk pemrosesan batch paling sederhana adalah antrian tugas. Dalam sistem dengan antrian tugas, ada satu set tugas yang harus diselesaikan. Setiap tugas sepenuhnya independen dari yang lain dan dapat diproses tanpa interaksi dengan mereka. Dalam kasus umum, tujuan sistem dengan antrian tugas adalah untuk memastikan bahwa setiap tahap pekerjaan diselesaikan dalam periode waktu tertentu. Jumlah alur kerja bertambah atau berkurang sesuai dengan perubahan beban. Skema antrian tugas umum disajikan pada Gambar. 10.1.
Sistem berdasarkan antrian tugas umum
Baris tugas adalah contoh ideal yang menunjukkan kekuatan penuh pola desain sistem terdistribusi. Sebagian besar logika antrian tugas tidak tergantung pada jenis pekerjaan yang dilakukan. Dalam banyak kasus, hal yang sama berlaku untuk pengiriman tugas itu sendiri.
Mari kita menggambarkan pernyataan ini menggunakan antrian tugas yang ditunjukkan pada Gambar. 10.1. Setelah melihatnya lagi, tentukan fungsi apa yang bisa disediakan oleh satu set wadah bersama. Menjadi jelas bahwa sebagian besar implementasi antrian tugas kemas dapat digunakan oleh berbagai pengguna.
Antrian tugas berbasis kontainer membutuhkan antarmuka yang cocok antara kontainer perpustakaan dan kontainer dengan logika pengguna. Dalam antrian tugas kemas, dua antarmuka dibedakan: antarmuka wadah sumber, yang menyediakan aliran tugas yang membutuhkan pemrosesan, dan antarmuka wadah yang mengeksekusi, yang tahu bagaimana menanganinya.
Sumber Kontainer Antarmuka
Antrian tugas apa pun beroperasi berdasarkan serangkaian tugas yang membutuhkan pemrosesan. Bergantung pada aplikasi spesifik yang diterapkan berdasarkan antrian tugas, ada banyak sumber tugas yang termasuk di dalamnya. Tetapi setelah menerima serangkaian tugas, skema operasi antrian cukup sederhana. Oleh karena itu, kita dapat memisahkan logika khusus aplikasi dari sumber tugas dari skema umum pemrosesan antrian tugas. Mengingat pola kelompok wadah yang dibahas sebelumnya, di sini Anda dapat melihat penerapan pola Duta Besar. Wadah tugas antrian umum adalah wadah aplikasi utama, dan wadah sumber khusus aplikasi adalah permintaan penyiaran duta besar dari wadah pengirim antrian ke pelaksana tugas tertentu. Kelompok wadah ini ditunjukkan pada Gambar. 10.2.

By the way, meskipun duta kontainer adalah khusus aplikasi (yang jelas), ada juga beberapa implementasi umum dari sumber API. Misalnya, sumber dapat berupa daftar foto yang terletak di beberapa penyimpanan cloud, sekumpulan file pada drive jaringan, atau bahkan antrian dalam sistem yang beroperasi dengan prinsip "publikasikan / berlangganan", seperti Kafka atau Redis. Terlepas dari kenyataan bahwa pengguna dapat memilih duta wadah yang paling cocok untuk tugas mereka, mereka harus menggunakan implementasi "perpustakaan" umum dari wadah itu sendiri. Ini akan meminimalkan jumlah pekerjaan dan memaksimalkan penggunaan kembali kode.
API Antrian Tugas Mengingat mekanisme interaksi antara antrian tugas dan wadah yang bergantung pada aplikasi, kita harus merumuskan definisi formal antarmuka antara dua kontainer. Ada banyak protokol berbeda, tetapi HTTP RESTful APIs mudah diimplementasikan dan merupakan standar de facto untuk antarmuka semacam itu. Antrean tugas mengharapkan URL berikut untuk diimplementasikan dalam wadah setelah:
Mengapa menambahkan v1 ke definisi API Anda, Anda bertanya? Akankah ada versi antarmuka yang kedua? Itu terlihat tidak masuk akal, tetapi biaya versi API ketika awalnya didefinisikan minimal. Melakukan refactoring yang sesuai nantinya akan sangat mahal. Buat aturan untuk menambahkan versi ke semua API, bahkan jika Anda tidak yakin apakah akan pernah berubah. Tuhan menyelamatkan yang aman.
URL / item / mengembalikan daftar semua tugas:
{ kind: ItemList, apiVersion: v1, items: [ "item-1", "item-2", β¦. ] }
URL / item / <item-name> memberikan informasi terperinci tentang tugas tertentu:
{ kind: Item, apiVersion: v1, data: { "some": "json", "object": "here", } }
Harap perhatikan bahwa API tidak menyediakan mekanisme apa pun untuk memperbaiki fakta tugas. Seseorang dapat mengembangkan API yang lebih kompleks dan mengalihkan sebagian besar implementasinya ke duta kontainer. Ingat, bagaimanapun, bahwa tujuan kami adalah untuk memusatkan sebanyak mungkin implementasi keseluruhan dalam manajer antrian tugas. Dalam hal ini, manajer antrian tugas itu sendiri harus memantau tugas mana yang sudah diproses dan yang belum diproses.
Dari API ini kami mendapatkan informasi tentang tugas tertentu, dan kemudian meneruskan nilai bidang item.data dari antarmuka kontainer pelaksana.
Menjalankan Antarmuka Kontainer
Segera setelah manajer antrian menerima tugas berikutnya, ia harus mempercayakannya kepada beberapa pelaksana. Ini adalah antarmuka kedua dalam antrian tugas umum. Wadah itu sendiri dan antarmuka-nya sedikit berbeda dari antarmuka wadah sumber karena beberapa alasan. Pertama, ini adalah API satu kali. Pekerjaan pelaksana dimulai dengan satu panggilan, dan selama siklus hidup wadah, tidak ada lagi panggilan yang dilakukan. Kedua, wadah pelaksana dan pengelola antrian tugas berada dalam grup wadah yang berbeda. Eksekutor kontainer diluncurkan melalui API orkestra wadah dalam grupnya sendiri. Ini berarti bahwa manajer antrian tugas harus membuat panggilan jarak jauh untuk memulai wadah eksekusi. Ini juga berarti bahwa Anda harus lebih berhati-hati tentang masalah keamanan, karena pengguna jahat cluster dapat memuatnya dengan pekerjaan yang tidak perlu.
Dalam wadah sumber, kami menggunakan panggilan HTTP sederhana untuk mengirim daftar tugas ke pengelola tugas. Ini dilakukan dengan asumsi bahwa panggilan API ini perlu dilakukan beberapa kali, dan masalah keamanan tidak diperhitungkan, karena semuanya bekerja dalam kerangka localhost. API kontainer harus dipanggil hanya sekali dan penting untuk memastikan bahwa pengguna lain dari sistem tidak dapat menambahkan pekerjaan ke pelaksana, bahkan secara tidak sengaja atau dengan niat jahat. Karenanya, untuk wadah pelaksana, kami akan menggunakan file API. Setelah membuat, kami akan mengirimkan variabel lingkungan wadah yang disebut WORK_ITEM_FILE, yang nilainya merujuk ke file di sistem file internal wadah. File ini berisi data tentang tugas yang harus diselesaikan. Jenis API ini, seperti yang ditunjukkan di bawah ini, dapat diimplementasikan oleh objek ConfigMap Kubernetes. Itu dapat dipasang dalam kelompok wadah sebagai file (Gbr. 10.3).

Mekanisme API file seperti itu lebih mudah diimplementasikan menggunakan wadah. Seorang pelaksana dalam antrian tugas sering kali adalah skrip shell sederhana yang mengakses beberapa alat. Tidak praktis untuk meningkatkan seluruh server web untuk manajemen tugas - ini mengarah pada komplikasi arsitektur. Seperti halnya dengan sumber tugas, sebagian besar wadah-pelaksana akan menjadi wadah khusus untuk tugas-tugas tertentu, tetapi ada juga pelaksana umum yang berlaku untuk menyelesaikan beberapa tugas yang berbeda.
Pertimbangkan contoh wadah pelaksana yang mengunduh file dari penyimpanan cloud, menjalankan skrip shell di atasnya, dan kemudian menyalin hasilnya kembali ke penyimpanan cloud. Kontainer seperti itu bisa untuk sebagian besar umum, tetapi skenario tertentu dapat diteruskan sebagai parameter. Dengan demikian, sebagian besar kode penanganan file dapat digunakan kembali oleh banyak pengguna / antrian tugas. Pengguna akhir hanya perlu menyediakan skrip yang berisi spesifikasi pemrosesan file.
Infrastruktur antrian tugas umum
Apa yang masih harus diimplementasikan dalam implementasi antrian yang dapat digunakan kembali jika Anda sudah memiliki implementasi dari dua antarmuka kontainer yang dijelaskan sebelumnya? Algoritma dasar dari tugas antrian cukup sederhana.
- Unduh tugas yang saat ini tersedia dari wadah sumber.
- Perjelas status antrian tugas untuk tugas-tugas apa yang telah selesai atau masih dilakukan.
- Untuk setiap tugas yang belum terselesaikan, buat wadah penampung dengan antarmuka yang sesuai.
- Setelah berhasil menyelesaikan wadah pelaksana, catat bahwa tugas telah selesai.
Algoritma ini sederhana dalam kata-kata, tetapi dalam kenyataannya tidak begitu mudah untuk diterapkan. Untungnya, orkestra Kubernetes memiliki beberapa fitur yang sangat menyederhanakan implementasinya. Yaitu: Kubernetes memiliki objek Pekerjaan yang memastikan operasi antrian tugas yang andal. Anda dapat mengkonfigurasi objek Ayub sehingga mulai menjalankan wadah yang sesuai baik sekali atau sampai tugas berhasil diselesaikan. Jika Anda mengonfigurasi wadah pelaksana sehingga dijalankan sebelum tugas selesai, maka bahkan ketika mesin di gugus gagal, tugas akhirnya akan berhasil diselesaikan.
Dengan demikian, tugas antrian sangat disederhanakan, karena orkestra mengambil tanggung jawab untuk pelaksanaan tugas yang andal.
Selain itu, Kubernetes memungkinkan Anda untuk membuat anotasi tugas, yang memungkinkan kami menandai setiap objek tugas dengan nama elemen antrian tugas yang diproses. Menjadi lebih mudah untuk membedakan antara tugas yang diproses dan diselesaikan baik dengan sukses maupun dengan kesalahan.
Ini berarti bahwa kita dapat mengimplementasikan antrian tugas di atas orkestra Kubernetes tanpa menggunakan repositori kita sendiri. Semua ini sangat menyederhanakan tugas membangun infrastruktur antrian tugas.
Oleh karena itu, algoritme terperinci untuk pengoperasian wadah, pengelola antrian tugas, adalah sebagai berikut.
Ulangi tanpa henti.
- Dapatkan daftar tugas melalui antarmuka wadah - sumber tugas.
- Dapatkan daftar tugas yang melayani antrian tugas ini.
- Atas dasar daftar ini, pilih daftar tugas yang belum diproses.
- Untuk setiap tugas yang tidak diproses, buat objek Ayub yang memunculkan wadah eksekusi yang sesuai.
Berikut ini adalah skrip Python yang mengimplementasikan antrian ini:
import requests import json from kubernetes import client, config import time namespace = "default" def make_container(item, obj): container = client.V1Container() container.image = "my/worker-image" container.name = "worker" return container def make_job(item): response = requests.get("http://localhost:8000/items/{}".format(item)) obj = json.loads(response.text) job = client.V1Job() job.metadata = client.V1ObjectMeta() job.metadata.name = item job.spec = client.V1JobSpec() job.spec.template = client.V1PodTemplate() job.spec.template.spec = client.V1PodTemplateSpec() job.spec.template.spec.restart_policy = "Never" job.spec.template.spec.containers = [ make_container(item, obj) ] return job def update_queue(batch): response = requests.get("http://localhost:8000/items") obj = json.loads(response.text) items = obj['items'] ret = batch.list_namespaced_job(namespace, watch=False) for item in items: found = False for i in ret.items: if i.metadata.name == item: found = True if not found: # Job, # job = make_job(item) batch.create_namespaced_job(namespace, job) config.load_kube_config() batch = client.BatchV1Api() while True: update_queue(batch) time.sleep(10)
Bengkel Implementasi generator thumbnail untuk file video
Sebagai contoh penggunaan antrian tugas, pertimbangkan tugas membuat thumbnail file video. Berdasarkan thumbnail ini, pengguna memutuskan video mana yang ingin mereka tonton.
Untuk mengimplementasikan thumbnail, Anda memerlukan dua wadah. Yang pertama adalah untuk sumber tugas. Akan lebih mudah untuk menempatkan tugas pada drive jaringan bersama yang terhubung, misalnya, melalui NFS (Sistem File Jaringan, sistem file jaringan). Sumber tugas menerima daftar file dalam direktori ini dan meneruskannya ke pemanggil.
Saya akan memberikan program sederhana tentang NodeJS:
const http = require('http'); const fs = require('fs'); const port = 8080; const path = process.env.MEDIA_PATH; const requestHandler = (request, response) => { console.log(request.url); fs.readdir(path + '/*.mp4', (err, items) => { var msg = { 'kind': 'ItemList', 'apiVersion': 'v1', 'items': [] }; if (!items) { return msg; } for (var i = 0; i < items.length; i++) { msg.items.push(items[i]); } response.end(JSON.stringify(msg)); }); } const server = http.createServer(requestHandler); server.listen(port, (err) => { if (err) { return console.log(' ', err); } console.log(` ${port}`) });
Sumber ini mendefinisikan daftar film yang akan diproses. Utilitas ffmpeg digunakan untuk mengekstrak thumbnail.
Anda dapat membuat wadah yang menjalankan perintah berikut:
ffmpeg -i ${INPUT_FILE} -frames:v 100 thumb.png
Perintah mengekstrak satu dari setiap 100 frame (-frame: parameter v 100) dan menyimpannya dalam format PNG (misalnya, thumb1.png, thumb2.png, dll.).
Jenis pemrosesan ini dapat diimplementasikan berdasarkan pada gambar Docker ffmpeg yang ada.
Gambar jrottenberg / ffmpeg populer.
Dengan mendefinisikan wadah sumber sederhana dan wadah pelaksanaan yang lebih sederhana, mudah untuk melihat manfaat dari sistem manajemen antrian yang berorientasi wadah. Ini secara signifikan mengurangi waktu antara desain dan implementasi antrian tugas.
Penskalaan seniman yang dinamis
Antrian tugas yang dipertimbangkan sebelumnya sangat cocok untuk memproses tugas-tugas saat tersedia, tetapi dapat menyebabkan beban mendadak pada sumber daya orkestra kluster wadah. Ini bagus ketika Anda memiliki banyak jenis tugas yang membuat puncak beban pada waktu yang berbeda dan dengan demikian mendistribusikan beban pada kluster dari waktu ke waktu.
Tetapi jika Anda tidak memiliki jenis beban yang cukup, pendekatan "lalu tebal, lalu kosong" untuk penskalaan antrean tugas mungkin memerlukan cadangan sumber daya tambahan untuk mendukung semburan beban. Sisa waktu, sumber daya akan menganggur, tidak perlu mengosongkan dompet Anda.
Untuk mengatasi masalah ini, Anda bisa membatasi jumlah total objek Pekerjaan yang dihasilkan oleh antrian tugas. Ini secara alami akan membatasi jumlah pekerjaan yang diproses secara paralel dan, akibatnya, mengurangi penggunaan sumber daya selama beban puncak. Di sisi lain, durasi masing-masing tugas individu akan meningkat dengan beban tinggi pada cluster.
Jika bebannya spasmodik, ini tidak menakutkan, karena interval waktu henti dapat digunakan untuk menyelesaikan tugas yang terakumulasi. Namun, jika beban tetap terlalu tinggi, antrian tugas tidak akan punya waktu untuk memproses tugas yang masuk dan semakin banyak waktu akan dihabiskan untuk pelaksanaannya.
Dalam situasi seperti itu, Anda harus secara dinamis menyesuaikan jumlah maksimum tugas paralel dan, dengan demikian, sumber daya komputasi yang tersedia untuk mempertahankan tingkat kinerja yang diperlukan. Untungnya, ada rumus matematika yang memungkinkan Anda untuk menentukan kapan perlu untuk skala antrian tugas untuk memproses lebih banyak permintaan.
Pertimbangkan antrean tugas di mana tugas baru muncul rata-rata satu menit sekali, dan penyelesaiannya membutuhkan rata-rata 30 detik. Antrian seperti itu mampu mengatasi aliran tugas yang masuk ke dalamnya. Bahkan jika paket besar tugas tiba sekaligus, menciptakan kemacetan lalu lintas, maka kemacetan lalu lintas akan dihilangkan seiring waktu, karena sebelum tugas berikutnya tiba, antrian berhasil memproses rata-rata dua tugas.
Jika tugas baru tiba setiap menit dan dibutuhkan rata-rata 1 menit untuk memproses satu tugas, maka sistem seperti itu idealnya seimbang, tetapi tidak merespon dengan baik terhadap perubahan beban. Dia mampu mengatasi semburan beban, tetapi itu akan menghabiskan banyak waktu. Sistem tidak akan menganggur, tetapi tidak akan ada cadangan waktu komputer untuk mengimbangi peningkatan jangka panjang dalam kecepatan penerimaan tugas baru. Untuk menjaga stabilitas sistem, perlu memiliki cadangan jika terjadi pertumbuhan beban jangka panjang atau keterlambatan tak terduga dalam tugas pemrosesan.
Akhirnya, pertimbangkan sistem di mana satu tugas per menit tiba, dan pemrosesan tugas memakan waktu dua menit. Sistem seperti itu akan terus-menerus kehilangan kinerja. Panjang antrian tugas akan bertambah seiring dengan penundaan antara penerimaan dan pemrosesan tugas (dan tingkat gangguan pengguna).
Nilai kedua indikator ini harus terus dipantau. Dengan rata-rata waktu antara penerimaan tugas untuk jangka waktu yang lama, misalnya, berdasarkan jumlah tugas per hari, kami memperoleh perkiraan interval antar-tugas. Anda juga perlu memantau waktu pemrosesan rata-rata tugas (tidak termasuk waktu yang dihabiskan dalam antrian). Dalam antrian tugas yang stabil, waktu pemrosesan tugas rata-rata harus kurang dari interval antar-tugas. Untuk memastikan bahwa kondisi ini terpenuhi, perlu untuk menyesuaikan secara dinamis jumlah antrian sumber daya komputasi yang tersedia. Jika pekerjaan diproses secara paralel, maka waktu pemrosesan harus dibagi dengan jumlah pekerjaan yang diproses secara paralel. Misalnya, jika satu tugas diproses satu menit, tetapi empat tugas diproses secara paralel, maka waktu pemrosesan efektif satu tugas adalah 15 detik, yang berarti bahwa interval antar-tugas minimal 16 detik.
Pendekatan ini memungkinkan Anda untuk dengan mudah membuat modul untuk meningkatkan antrian tugas ke atas. Penurunan skala agak lebih bermasalah. Namun demikian, dimungkinkan untuk menggunakan perhitungan yang sama seperti sebelumnya, selain meletakkan cadangan sumber daya komputasi yang ditentukan oleh cara heuristik. Misalnya, Anda dapat mengurangi jumlah tugas paralel hingga waktu pemrosesan untuk satu tugas adalah 90% dari interval antar-tugas.
Pola Multi-Pekerja
Salah satu topik utama buku ini adalah penggunaan wadah untuk merangkum dan menggunakan kembali kode. Ini juga relevan untuk pola antrian tugas yang dijelaskan dalam bab ini. Selain kontainer yang mengelola antrian itu sendiri, Anda dapat menggunakan kembali grup kontainer yang membentuk pelaksanaan pemain. Misalkan Anda perlu memproses setiap tugas dalam antrian dengan tiga cara berbeda. Misalnya, untuk mendeteksi wajah dalam sebuah foto, cocokkan dengan orang-orang tertentu, dan kemudian memburamkan bagian gambar yang sesuai. Anda bisa meletakkan semua pemrosesan dalam satu wadah eksekusi, tetapi ini adalah solusi satu kali yang tidak dapat digunakan kembali. Untuk menutupi hal lain, seperti mobil, di foto, Anda harus membuat wadah seniman dari awal.
Kemungkinan penggunaan kembali semacam ini dapat dicapai dengan menerapkan pola Multi-Worker, yang sebenarnya merupakan kasus khusus dari pola Adaptor yang dijelaskan di awal buku. Pola Multi-Pekerja mengubah seperangkat wadah menjadi satu wadah umum dengan antarmuka perangkat lunak wadah pelaksana. Kontainer bersama ini memproses untuk beberapa wadah terpisah yang dapat digunakan kembali. Proses ini secara skematis ditunjukkan pada Gambar. 10.4.
Dengan menggunakan kembali kode dengan menggabungkan wadah yang dapat dieksekusi, tenaga orang yang merancang sistem pemrosesan batch terdistribusi berkurang.
Β»Informasi lebih lanjut tentang buku ini dapat ditemukan di
situs web penerbitΒ»
IsiΒ»
KutipanUntuk habrozhitelami, diskon 20% pada kupon -
Sistem terdistribusi .