Bagaimana cara mengonversi pekerjaan cron Linux ke "cara Amazon"?


112

Baik atau buruk, kami telah memigrasikan seluruh aplikasi web LAMP kami dari mesin khusus ke cloud (mesin Amazon EC2). Sejauh ini hasilnya bagus, tetapi cara kami membuat crons kurang optimal. Saya memiliki pertanyaan khusus Amazon tentang cara terbaik mengelola pekerjaan cron di cloud menggunakan "cara Amazon".

Masalahnya : Kami memiliki banyak server web, dan perlu menjalankan crons untuk pekerjaan batch seperti membuat RSS feed, memicu email, banyak hal berbeda sebenarnya. TETAPI tugas cron hanya perlu dijalankan di satu mesin karena sering menulis ke database sehingga akan menduplikasi hasil jika dijalankan di beberapa mesin.

Sejauh ini, kami menetapkan salah satu server web sebagai "master-webserver" dan memiliki beberapa tugas "khusus" yang tidak dimiliki server web lain. Kompromi untuk komputasi awan adalah keandalan - kami tidak menginginkan "server web master" karena ini adalah satu titik kegagalan. Kami ingin semuanya identik dan dapat meningkatkan dan menurunkan skala tanpa mengingat untuk tidak mengeluarkan server web master dari cluster.

Bagaimana kita dapat mendesain ulang aplikasi kita untuk mengonversi pekerjaan cron Linux menjadi item pekerjaan sementara yang tidak memiliki satu titik kegagalan?

Ide saya sejauh ini:

  • Miliki mesin yang didedikasikan hanya untuk menjalankan cron. Ini akan menjadi sedikit lebih mudah dikelola tetapi masih akan menjadi titik kegagalan tunggal, dan akan membuang-buang uang dengan memiliki contoh tambahan.
  • Beberapa pekerjaan mungkin dapat dipindahkan dari Linux crons ke MySQL Events namun saya bukan penggemar ide ini karena saya tidak ingin memasukkan logika aplikasi ke dalam lapisan database.
  • Mungkin kita dapat menjalankan semua cron di semua mesin tetapi mengubah skrip cron kita sehingga semuanya dimulai dengan sedikit logika yang menerapkan mekanisme penguncian sehingga hanya satu server yang benar-benar mengambil tindakan dan yang lainnya langsung saja. Saya bukan penggemar ide ini karena kedengarannya berpotensi buggy dan saya lebih suka menggunakan praktik terbaik Amazon daripada menjalankan praktik kami sendiri.
  • Saya membayangkan situasi di mana pekerjaan dijadwalkan di suatu tempat, ditambahkan ke antrean dan kemudian server web masing-masing bisa menjadi pekerja, yang dapat berkata "hei, saya ambil yang ini". Amazon Simple Workflow Service terdengar persis seperti ini, tetapi saat ini saya tidak tahu banyak tentangnya sehingga informasi spesifik apa pun akan membantu. Tampaknya cukup berat untuk sesuatu yang sederhana seperti cron? Apakah ini layanan yang tepat atau apakah ada layanan Amazon yang lebih cocok?

Pembaruan: Sejak mengajukan pertanyaan, saya telah menonton webinar Amazon Simple Workflow Service di YouTube dan memperhatikan pada 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ) saya melihat sekilas slide yang menyebutkan tugas cron sebagai aplikasi sampel. Di halaman dokumentasi mereka, " Sampel AWS Flow Framework untuk Amazon SWF ", Amazon mengatakan mereka memiliki kode sampel untuk cron:

... > Cron job Dalam contoh ini, alur kerja yang berjalan lama secara berkala menjalankan aktivitas. Kemampuan untuk melanjutkan eksekusi sebagai eksekusi baru sehingga eksekusi bisa berjalan untuk waktu yang sangat lama ditunjukkan. ...

Saya mendownload AWS SDK untuk Java ( http://aws.amazon.com/sdkforjava/ ) dan cukup yakin terkubur di dalam lapisan folder yang konyol ada beberapa kode java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Masalahnya adalah, jika saya jujur, ini tidak terlalu membantu karena ini bukan sesuatu yang dapat dengan mudah saya cerna dengan keahlian saya. Contoh yang sama hilang dari PHP SDK dan sepertinya tidak ada tutorial yang menjelaskan prosesnya. Jadi intinya, saya masih mencari nasehat atau tips.


Jawaban:


38

Saya mendaftar ke dukungan Amazon Gold untuk menanyakan pertanyaan ini kepada mereka, berikut adalah tanggapan mereka:

Tom

Saya melakukan polling cepat terhadap beberapa rekan saya dan mendapatkan hasil kosong di cron, tetapi setelah tidur di atasnya, saya menyadari langkah penting mungkin terbatas pada penguncian. Jadi saya mencari "penguncian pekerjaan cron terdistribusi" dan menemukan referensi ke Zookeeper, sebuah proyek Apache.

http://zookeeper.apache.org/doc/r3.2.2/recipes.html

http://highscalability.com/blog/2010/3/22/7-secrets-to-successfully-scaling-with-scalr-on-amazon-by-se.html

Saya juga telah melihat referensi untuk menggunakan memcache atau mekanisme cache serupa sebagai cara untuk membuat kunci dengan TTL. Dengan cara ini Anda menyetel tanda, dengan TTL 300 detik dan tidak ada pekerja cron lain yang akan menjalankan tugas. Kunci akan secara otomatis dibuka setelah TTL kedaluwarsa. Ini secara konseptual sangat mirip dengan opsi SQS yang kita diskusikan kemarin.

Lihat juga; Google gemuk http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

Beri tahu saya jika ini membantu, dan jangan ragu untuk mengajukan pertanyaan, kami sangat sadar bahwa layanan kami dapat menjadi rumit dan menakutkan baik bagi pemula maupun developer berpengalaman. Kami selalu dengan senang hati menawarkan arsitektur dan saran praktik terbaik.

Salam Hormat,

Layanan Web Ronan G. Amazon


13

Saya pikir video ini menjawab pertanyaan tepat Anda - cronjobs dengan cara aws (terukur dan toleran terhadap kesalahan):

Menggunakan Cron di Cloud dengan Amazon Simple Workflow

Video tersebut menjelaskan layanan SWF menggunakan kasus penggunaan khusus dalam mengimplementasikan cronjobs.

Kompleksitas relatif dari solusi bisa sulit untuk diterima jika Anda datang langsung dari crontab. Ada studi kasus di bagian akhir yang membantu saya memahami apa yang dibeli dengan kerumitan ekstra itu untuk Anda. Saya akan menyarankan untuk menonton studi kasus dan mempertimbangkan persyaratan Anda untuk skalabilitas dan toleransi kesalahan untuk memutuskan apakah Anda harus bermigrasi dari solusi crontab yang ada.


2
ini adalah jawaban yang bagus karena menggunakan alat yang didukung dengan baik dari AWS, dan SWF adalah produk yang hebat. Satu-satunya downside, imo, adalah bahwa SWF memiliki kurva pembelajaran yang signifikan dan sulit untuk melakukan hal-hal yang rumit. Setidaknya itulah pengalaman saya dengan tutorial Java
Don Cheadle

11

Berhati-hatilah saat menggunakan SQS untuk cronjobs, karena SQS tidak menjamin bahwa hanya "satu pekerjaan dilihat oleh satu mesin saja". Mereka menjamin bahwa "setidaknya satu" akan mendapatkan pesan tersebut.

Dari: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

T: Berapa kali saya akan menerima setiap pesan?

Amazon SQS direkayasa untuk menyediakan "setidaknya satu kali" pengiriman semua pesan dalam antreannya. Meskipun sebagian besar waktu setiap pesan akan dikirim ke aplikasi Anda tepat satu kali, Anda harus merancang sistem Anda sehingga memproses pesan lebih dari sekali tidak membuat kesalahan atau ketidakkonsistenan.

Sejauh ini saya dapat memikirkan solusi di mana Anda memiliki satu instance dengan instance Gearman Job Server yang diinstal: http://gearman.org/ . Pada mesin yang sama Anda mengonfigurasi tugas cron yang menghasilkan perintah untuk menjalankan tugas cronjob Anda di latar belakang. Kemudian salah satu server web Anda (pekerja) akan mulai menjalankan tugas ini, ini menjamin bahwa hanya satu yang akan menerimanya. Tidak masalah berapa banyak pekerja yang Anda miliki (terutama saat Anda menggunakan penskalaan otomatis).

Masalah dengan solusi ini adalah:

  • Server Gearman adalah satu titik kegagalan, kecuali Anda mengonfigurasinya dengan penyimpanan terdistribusi, misalnya menggunakan memcache atau beberapa database
  • Kemudian menggunakan beberapa server Gearman Anda harus memilih salah satu yang membuat tugas melalui cronjob, jadi sekali lagi kita kembali ke masalah yang sama. Tetapi jika Anda dapat hidup dengan titik kegagalan tunggal seperti ini menggunakan Gearman sepertinya solusi yang cukup baik. Apalagi Anda tidak perlu contoh besar untuk itu (contoh mikro dalam kasus kami sudah cukup).

Nah, pesan tetap ada di server setelah diterima. Terserah pengembang untuk menghapusnya setelah itu. Saat sedang diproses, mereka tidak dapat diakses oleh server lain.
Frederik Wordkjold

2
@FrederikWordenskjold Itu tidak benar, bahkan setelah pesan telah diberikan ke satu klien, itu masih dapat diberikan ke klien lain, karena replikasi status SQS adalah asynchronous. Anda bahkan dapat diberi salinan pesan "setelah" itu dihapus!
Chris Pitman

Jawaban ini sudah usang. Ada 2 jenis antrian sekarang. Gunakan FIFO untuk mendapatkan Pemrosesan Tepat-Sekali: Sebuah pesan dikirim satu kali dan tetap tersedia sampai konsumen memproses dan menghapusnya. Duplikat tidak dimasukkan ke dalam antrian. aws.amazon.com/sqs/features
Lukas Liesis

10

Amazon baru saja merilis fitur baru untuk Elastic Beanstalk. Dari dokumen :

AWS Elastic Beanstalk mendukung tugas berkala untuk
tingkatan lingkungan pekerja di lingkungan yang menjalankan konfigurasi yang telah ditentukan sebelumnya dengan tumpukan solusi yang berisi "v1.2.0" dalam nama penampung. "

Sekarang Anda dapat membuat lingkungan yang berisi cron.yamlfile yang mengonfigurasi tugas penjadwalan:

version: 1
cron:
- name: "backup-job"          # required - unique across all entries in this file
  url: "/backup"              # required - does not need to be unique
  schedule: "0 */12 * * *"    # required - does not need to be unique
- name: "audit"
  url: "/audit"
   schedule: "0 23 * * *"

Saya membayangkan asuransi menjalankannya hanya sekali dalam lingkungan skala otomatis digunakan melalui antrian pesan (SQS). Ketika daemon cron memicu suatu peristiwa, ia menempatkan panggilan itu dalam antrian SQS dan pesan dalam antrian hanya dievaluasi sekali. Dokumen mengatakan bahwa eksekusi mungkin tertunda jika SQS memiliki banyak pesan untuk diproses.


Bisakah Anda juga memasukkan beberapa konten dari tautan?
Robert

6

Saya menemukan pertanyaan ini untuk ketiga kalinya sekarang dan berpikir saya akan ikut campur. Kita sudah lama mengalami dilema ini. Saya masih benar-benar merasa AWS hilang fitur di sini.

Dalam kasus kami, setelah melihat solusi yang mungkin, kami memutuskan bahwa kami memiliki dua opsi:

  • Siapkan server cronjob yang menjalankan pekerjaan yang hanya boleh dijalankan sekali dalam satu waktu, skala otomatis dan pastikan itu diganti ketika statistik CloudWatch tertentu tidak sesuai dengan yang seharusnya. Kami menggunakan cloud-initskrip untuk menjalankan cronjobs. Tentu saja, ini disertai dengan waktu henti, yang menyebabkan cronjobs terlewat (saat menjalankan tugas tertentu setiap menit, seperti yang kami lakukan).
  • Gunakan logika yang rcronmenggunakan. Tentu saja, sihir tidak benar-benar dalam rcrondirinya sendiri, itu dalam logika yang Anda gunakan untuk mendeteksi node yang gagal (kami gunakan di keepalivedsini) dan "mengupgrade" node lain ke master.

Kami memutuskan untuk menggunakan opsi kedua, hanya karena sangat cepat dan kami sudah memiliki pengalaman dengan server web yang menjalankan cronjobs ini (di era pra-AWS kami).

Tentu saja, solusi ini dimaksudkan khusus untuk menggantikan pendekatan cronjob satu node tradisional, di mana waktu adalah faktor penentu (misalnya, "Saya ingin pekerjaan A dijalankan sekali sehari pada jam 5 pagi" , atau seperti dalam kasus kami "Saya ingin pekerjaan B berjalan sekali setiap menit " ). Jika Anda menggunakan cronjobs untuk memicu logika pemrosesan batch, Anda harus benar - benar memeriksanya SQS. Tidak ada dilema aktif-pasif, artinya Anda dapat menggunakan satu server atau seluruh tenaga kerja untuk memproses antrian Anda. Saya juga menyarankan untuk mencari SWFpenskalaan tenaga kerja Anda (meskipun auto scalingmungkin bisa melakukan trik juga dalam banyak kasus).

Bergantung pada pihak ketiga lain adalah sesuatu yang ingin kami hindari.




4

Cara "Amazon" adalah untuk didistribusikan, yang berarti crons besar harus dibagi menjadi banyak pekerjaan yang lebih kecil dan diserahkan ke mesin yang tepat.

Menggunakan antrean SQS dengan tipe disetel ke FIFO, rekatkan untuk memastikan setiap pekerjaan dijalankan hanya oleh satu mesin. Ini juga mentolerir kegagalan karena antrian akan buffer sampai mesin berputar kembali.

FIFO Exactly-Once Processing : Sebuah pesan dikirim satu kali dan tetap tersedia sampai konsumen memproses dan menghapusnya. Duplikat tidak dimasukkan ke dalam antrian.

Juga pertimbangkan apakah Anda benar-benar perlu melakukan 'batch' operasi ini. Apa yang terjadi jika pembaruan satu malam jauh lebih besar dari yang diharapkan? Bahkan dengan sumber daya dinamis, pemrosesan Anda dapat tertunda menunggu mesin yang cukup untuk berputar. Sebagai gantinya, simpan data Anda di SDB, beri tahu mesin tentang pembaruan melalui SQS, dan buat umpan RSS Anda dengan cepat (dengan cache).

Pekerjaan batch berasal dari saat sumber daya pemrosesan terbatas dan layanan 'langsung' lebih diutamakan. Di cloud, bukan itu masalahnya.


Terima kasih - Saya suka arah yang Anda gambarkan.
Tom

5
Berhati-hatilah karena SQS hanya menjamin bahwa sebuah pesan pada akhirnya akan dilihat oleh mesin, bukan pesan hanya akan dilihat oleh satu server. Apa pun yang Anda masukkan ke antrean SQS harus idempoten.
Richard Hurt

Tugas cron saya seharusnya berjalan setiap hari dan dengan SQS Anda hanya dapat menunda hingga 15 menit. Salah satu opsi dapat menambahkan tag kustom ke pesan dengan waktu target untuk mengeksekusinya dan memasukkannya kembali ke antrean jika waktu itu belum tercapai - tetapi ini benar-benar terlihat bodoh. Saya juga masih memerlukan tugas cron untuk mengisi antrian pada awalnya. Sepertinya masalah telur ayam :) Tapi saya masih berpikir bahwa SQS adalah hal yang tepat untuk digunakan, karena menjamin skalabilitas dan toleransi kesalahan
Raffaele Rossi

"Pekerjaan batch berasal dari masa ketika sumber daya pemrosesan terbatas dan layanan 'langsung' lebih diutamakan. Di cloud, ini tidak terjadi." Ini benar untuk beberapa tetapi tidak semua aktivitas. Misalnya, memproses log lalu lintas adalah sesuatu yang lebih baik sebagai proses batch daripada langsung.
Jordan Reiter

1

Mengapa Anda membangun sendiri? Mengapa tidak menggunakan sesuatu seperti Quartz (dengan Clustered Scheduling). Lihat dokumentasi.

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering


Saya menggunakan Quartz.NET dalam solusi SaaS yang sangat bergantung pada tugas terjadwal. Beberapa tugas pemeliharaan sistem, tetapi sebagian besar aktivitas dijadwalkan oleh pengguna akhir. Semua tugas kami menulis ke antrian pesan (amq) di mana kami memiliki sejumlah layanan idempoten. API-nya sangat bagus dan memungkinkan adanya jadwal yang kuat. Kami tidak mengelompokkan beberapa instance Quartz, tetapi mendukungnya.
Jerico Sandhorn

1

Apa yang kami lakukan adalah kami memiliki satu server tertentu yang merupakan bagian dari cluster aplikasi web kami di belakang ELB juga diberi nama DNS tertentu sehingga kami dapat menjalankan pekerjaan di satu server tertentu itu. Ini juga memiliki keuntungan bahwa jika pekerjaan itu menyebabkan server itu melambat, ELB akan menghapusnya dari cluster dan kemudian mengembalikannya setelah pekerjaan selesai dan berfungsi kembali.

Bekerja seperti juara.


1

Salah satu metode untuk memverifikasi bahwa ekspresi cron Anda berfungsi dengan cara Amazon adalah dengan menjalankannya melalui perintah peristiwa. Sebagai contoh:

aws events put-rule --name "DailyLambdaFunction" --schedule-expression "<your_schedule_expression>

Jika ekspresi jadwal Anda tidak valid, ini akan gagal.

Sumber daya lainnya: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html



0

Karena tidak ada yang menyebutkan CloudWatch Event , menurut saya ini adalah cara AWS dalam melakukan pekerjaan cron. Ini dapat menjalankan banyak tindakan, seperti fungsi Lambda, tugas ECS.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.