Làm thế nào để chuyển đổi công việc Linux cron thành “cách Amazon”?


112

Để tốt hơn hay tệ hơn, chúng tôi đã di chuyển toàn bộ ứng dụng web LAMP của mình từ các máy chuyên dụng sang đám mây (máy Amazon EC2). Cho đến nay mọi thứ đã rất tuyệt vời nhưng cách chúng tôi làm crons là chưa tối ưu. Tôi có một câu hỏi dành riêng cho Amazon về cách quản lý tốt nhất các công việc cron trên đám mây bằng cách sử dụng "cách Amazon".

Vấn đề : Chúng tôi có nhiều máy chủ web, và cần chạy các phần mềm cho các công việc hàng loạt như tạo nguồn cấp RSS, kích hoạt email, thực tế là nhiều thứ khác nhau. NHƯNG các công việc cron chỉ cần chạy trên một máy vì chúng thường ghi vào cơ sở dữ liệu nên sẽ trùng lặp kết quả nếu chạy trên nhiều máy.

Cho đến nay, chúng tôi đã chỉ định một trong những máy chủ web là "máy chủ web chính" và nó có một vài nhiệm vụ "đặc biệt" mà các máy chủ web khác không có. Sự đánh đổi của điện toán đám mây là độ tin cậy - chúng tôi không muốn có một "máy chủ web chính" vì đó là một điểm thất bại duy nhất. Chúng tôi muốn tất cả chúng giống hệt nhau và có thể nâng cấp và giảm tỷ lệ mà không cần nhớ rằng không đưa master-webserver ra khỏi cụm.

Làm cách nào chúng ta có thể thiết kế lại ứng dụng của mình để chuyển đổi các công việc cron Linux thành các mục công việc tạm thời mà không có một điểm lỗi nào?

Ý tưởng của tôi cho đến nay:

  • Có một máy chuyên dụng để chỉ chạy crons. Điều này sẽ dễ quản lý hơn một chút nhưng vẫn sẽ là một điểm thất bại duy nhất và sẽ lãng phí một số tiền nếu có thêm một phiên bản.
  • Một số công việc có thể được chuyển từ Linux crons sang MySQL Events, tuy nhiên tôi không phải là một fan hâm mộ lớn của ý tưởng này vì tôi không muốn đưa logic ứng dụng vào lớp cơ sở dữ liệu.
  • Có lẽ chúng ta có thể chạy tất cả các crons trên tất cả các máy nhưng thay đổi các tập lệnh cron của chúng ta để tất cả chúng bắt đầu với một chút logic thực hiện cơ chế khóa để chỉ một máy chủ thực sự thực hiện hành động và các máy chủ khác bỏ qua. Tôi không phải là người yêu thích ý tưởng này vì nó nghe có vẻ có lỗi và tôi muốn sử dụng phương pháp hay nhất của Amazon hơn là áp dụng phương pháp của chúng tôi.
  • Tôi đang tưởng tượng một tình huống mà các công việc được lên lịch ở đâu đó, được thêm vào một hàng đợi và sau đó các máy chủ web có thể là một công nhân, có thể nói "này, tôi sẽ nhận cái này". Dịch vụ Quy trình Công việc Đơn giản của Amazon nghe có vẻ chính xác là loại điều này nhưng tôi hiện không biết nhiều về nó vì vậy mọi chi tiết cụ thể sẽ hữu ích. Nó có vẻ khá nặng đối với một thứ đơn giản như cron? Đó có phải là dịch vụ phù hợp hay có dịch vụ Amazon phù hợp hơn không?

Cập nhật: Kể từ khi đặt câu hỏi, tôi đã xem hội thảo trên web về Dịch vụ quy trình làm việc đơn giản của Amazon trên YouTube và nhận thấy lúc 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ), tôi đã thoáng thấy một slide đề cập đến công việc cron như một ứng dụng mẫu. Trong trang tài liệu của họ, "Các mẫu AWS Flow Framework cho Amazon SWF ", Amazon cho biết họ có mã mẫu cho crons:

... > Các công việc Cron Trong mẫu này, một dòng công việc chạy dài thực hiện định kỳ một hoạt động. Khả năng tiếp tục thực thi dưới dạng thực thi mới để một thực thi có thể chạy trong một khoảng thời gian rất dài được chứng minh. ...

Tôi đã tải xuống AWS SDK cho Java ( http://aws.amazon.com/sdkforjava/ ) và chắc chắn rằng đủ để chôn vùi trong một lớp thư mục vô lý có một số mã java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Vấn đề là, nếu tôi trung thực, điều này không thực sự hữu ích vì nó không phải là thứ tôi có thể dễ dàng hiểu được với bộ kỹ năng của mình. SDK PHP bị thiếu cùng một mẫu và dường như không có hướng dẫn nào hướng dẫn quy trình này. Vì vậy, về cơ bản, tôi vẫn đang tìm kiếm lời khuyên hoặc mẹo.


Câu trả lời:


38

Tôi đã đăng ký hỗ trợ Amazon Gold để hỏi họ câu hỏi này, đây là câu trả lời của họ:

Tom

Tôi đã thực hiện một cuộc thăm dò nhanh một số đồng nghiệp của mình và nhận thấy trống trên cron, nhưng sau khi ngủ trên đó, tôi nhận ra rằng bước quan trọng có thể bị giới hạn ở việc khóa. Vì vậy, tôi đã tìm kiếm "khóa công việc cron phân tán" và tìm thấy một tham chiếu đến Zookeeper, một dự án Apache.

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

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

Ngoài ra, tôi đã thấy tham chiếu đến việc sử dụng memcached hoặc một cơ chế bộ nhớ đệm tương tự như một cách để tạo khóa bằng TTL. Bằng cách này, bạn đặt một cờ, với TTL là 300 giây và không có nhân viên cron nào khác sẽ thực hiện công việc. Khóa sẽ tự động được phát hành sau khi TTL hết hạn. Điều này về mặt khái niệm rất giống với tùy chọn SQS mà chúng ta đã thảo luận ngày hôm qua.

Cũng thấy; Http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf của Google

Hãy cho tôi biết nếu điều này có ích và đừng ngại đặt câu hỏi, chúng tôi nhận thức rõ rằng các dịch vụ của chúng tôi có thể phức tạp và gây khó khăn cho cả người mới bắt đầu và cả những nhà phát triển dày dạn kinh nghiệm. Chúng tôi luôn sẵn lòng đưa ra những lời khuyên về kiến ​​trúc và thực hành tốt nhất.

Trân trọng,

Ronan G. Dịch vụ web của Amazon


13

Tôi nghĩ rằng video này trả lời câu hỏi chính xác của bạn - sử dụng theo cách aws (có thể mở rộng và chịu được lỗi):

Sử dụng Cron trong đám mây với Quy trình làm việc đơn giản của Amazon

Video mô tả dịch vụ SWF sử dụng trường hợp sử dụng cụ thể của việc triển khai cronjobs.

Sự phức tạp tương đối của giải pháp có thể khó nuốt nếu bạn đến thẳng từ crontab. Có một nghiên cứu điển hình ở cuối đã giúp tôi hiểu được điều gì khiến bạn thêm phức tạp. Tôi khuyên bạn nên xem nghiên cứu điển hình và xem xét các yêu cầu của bạn về khả năng mở rộng và khả năng chịu lỗi để quyết định xem bạn có nên chuyển từ giải pháp crontab hiện có của mình hay không.


2
đây là một câu trả lời tuyệt vời vì nó sử dụng một công cụ được hỗ trợ tốt từ AWS và SWF là một sản phẩm mạnh mẽ. Nhược điểm duy nhất, imo, là SWF có một đường cong học tập đáng kể và có thể khó làm những việc phức tạp. Ít nhất thì đó là kinh nghiệm của tôi với các hướng dẫn Java
Don Cheadle

11

Hãy cẩn thận với việc sử dụng SQS cho cronjobs, vì chúng không đảm bảo rằng "chỉ một công việc được nhìn thấy bởi duy nhất một máy". Họ đảm bảo rằng "ít nhất một" sẽ nhận được tin nhắn.

Từ: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

Hỏi: Tôi sẽ nhận được bao nhiêu lần mỗi tin nhắn?

Amazon SQS được thiết kế để cung cấp phân phối “ít nhất một lần” tất cả các thư trong hàng đợi của nó. Mặc dù hầu hết thời gian mỗi thông báo sẽ được gửi đến ứng dụng của bạn chính xác một lần, bạn nên thiết kế hệ thống của mình để việc xử lý một thông báo nhiều lần không tạo ra bất kỳ lỗi hoặc sự mâu thuẫn nào.

Cho đến nay, tôi có thể nghĩ về giải pháp mà bạn có một phiên bản có cài đặt phiên bản Gearman Job Server: http://gearman.org/ . Trên cùng một máy, bạn định cấu hình các công việc cron đang tạo ra lệnh để thực thi tác vụ cronjob của bạn trong nền. Sau đó, một trong các máy chủ web của bạn (công nhân) sẽ bắt đầu thực hiện tác vụ này, nó đảm bảo rằng chỉ một máy chủ sẽ thực hiện nó. Không quan trọng bạn có bao nhiêu công nhân (đặc biệt là khi bạn đang sử dụng tính năng tự động chia tỷ lệ).

Các vấn đề với giải pháp này là:

  • Máy chủ Gearman là một điểm lỗi duy nhất, trừ khi bạn định cấu hình nó với bộ nhớ phân tán, ví dụ: sử dụng memcached hoặc một số cơ sở dữ liệu
  • Sau đó, sử dụng nhiều máy chủ Gearman, bạn phải chọn một máy chủ tạo tác vụ thông qua cronjob, vì vậy một lần nữa chúng ta quay lại vấn đề tương tự. Nhưng nếu bạn có thể sống với loại điểm thất bại duy nhất này bằng cách sử dụng Gearman có vẻ như là một giải pháp khá tốt. Đặc biệt là bạn không cần ví dụ lớn cho điều đó (ví dụ vi mô trong trường hợp của chúng tôi là đủ).

Vâng, các tin nhắn vẫn ở trên máy chủ sau khi chúng được nhận. Nhà phát triển có quyền xóa chúng sau đó. Trong khi chúng đang được xử lý, chúng không thể được truy cập bởi một máy chủ khác.
Frederik Wordenskjold

2
@FrederikWordenskjold Điều đó không chính xác, ngay cả sau khi một tin nhắn đã được trao cho một ứng dụng khách, nó vẫn có thể được đưa cho một ứng dụng khác, vì bản sao của trạng thái SQS là không đồng bộ. Bạn thậm chí có thể được cung cấp một bản sao của một tin nhắn "sau khi" nó bị xóa!
Chris Pitman

Câu trả lời này đã lỗi thời Hiện nay có 2 loại hàng đợi. Sử dụng FIFO để nhận Xử lý chính xác một lần: Một tin nhắn được gửi một lần và vẫn có sẵn cho đến khi người tiêu dùng xử lý và xóa nó. Các bản sao không được đưa vào hàng đợi. aws.amazon.com/sqs/features
Lukas Liesis

10

Amazon vừa phát hành các tính năng mới cho Elastic Beanstalk. Từ các tài liệu :

AWS Elastic Beanstalk hỗ trợ các tác vụ định kỳ cho các
cấp môi trường công nhân trong môi trường chạy cấu hình được xác định trước với ngăn xếp giải pháp có chứa "v1.2.0" trong tên vùng chứa. "

Bây giờ bạn có thể tạo một môi trường chứa một cron.yamltệp định cấu hình các tác vụ lập lịch:

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 * * *"

Tôi sẽ tưởng tượng bảo hiểm của việc chạy nó chỉ một lần trong môi trường được tự động phân cấp được sử dụng thông qua hàng đợi tin nhắn (SQS). Khi trình nền cron kích hoạt một sự kiện, nó sẽ đặt lệnh gọi đó vào hàng đợi SQS và thông báo trong hàng đợi chỉ được đánh giá một lần. Các tài liệu nói rằng việc thực thi có thể bị trì hoãn nếu SQS có nhiều thông báo cần xử lý.


Bạn cũng có thể bao gồm một số nội dung từ các liên kết?
Robert

6

Bây giờ tôi đã gặp câu hỏi này lần thứ ba và nghĩ rằng mình sẽ bắt tay vào. Chúng tôi đã gặp tình huống khó xử này trong một thời gian. Tôi vẫn thực sự cảm thấy AWS đang thiếu một tính năng ở đây.

Trong trường hợp của chúng tôi, sau khi xem xét các giải pháp khả thi, chúng tôi quyết định có hai lựa chọn:

  • Thiết lập một máy chủ cronjob chạy các công việc chỉ nên chạy một lần tại một thời điểm, tự động mở rộng quy mô và đảm bảo nó được thay thế khi một số thống kê CloudWatch nhất định không phải như vậy. Chúng tôi sử dụng cloud-initcác tập lệnh để chạy các cronjobs. Tất nhiên, điều này đi kèm với thời gian chết, dẫn đến việc bỏ lỡ các cronjobs (khi chạy các tác vụ nhất định mỗi phút, giống như chúng tôi làm).
  • Sử dụng logic mà rcronsử dụng. Tất nhiên, điều kỳ diệu không thực sự rcrontự nó, nó nằm trong logic bạn sử dụng để phát hiện một nút bị lỗi (chúng tôi sử dụng keepalivedở đây) và "nâng cấp" một nút khác để làm chủ.

Chúng tôi quyết định đi với tùy chọn thứ hai, đơn giản vì nó cực kỳ nhanh và chúng tôi đã có kinh nghiệm với các máy chủ web chạy các cronjobs này (trong kỷ nguyên trước AWS của chúng tôi).

Tất nhiên, giải pháp này có ý nghĩa đặc biệt để thay thế cách tiếp cận cronjob một nút truyền thống, trong đó thời gian là yếu tố quyết định (ví dụ: "Tôi muốn công việc A chạy một lần mỗi ngày vào lúc 5 giờ sáng" hoặc như trong trường hợp của chúng tôi "Tôi muốn công việc B để chạy một lần mỗi phút " ). Nếu bạn sử dụng cronjobs để kích hoạt logic xử lý hàng loạt, bạn thực sự nên xem xét SQS. Không có tình trạng tiến thoái lưỡng nan chủ động-thụ động, nghĩa là bạn có thể sử dụng một máy chủ duy nhất hoặc toàn bộ lực lượng lao động để xử lý hàng đợi của mình. Tôi cũng khuyên bạn nên xem xét SWFđể mở rộng lực lượng lao động của bạn (mặc dù auto scalingtrong hầu hết các trường hợp, bạn cũng có thể thực hiện thủ thuật này).

Chúng tôi muốn tránh phụ thuộc vào một bên thứ ba khác.




4

Cách "Amazon" là phân phối, có nghĩa là những chiếc máy móc cồng kềnh nên được chia thành nhiều công việc nhỏ hơn và giao cho đúng máy.

Sử dụng hàng đợi SQS với loại được đặt thành FIFO, dán nó lại với nhau để đảm bảo mỗi công việc chỉ được thực hiện bởi một máy. Nó cũng chịu được lỗi vì hàng đợi sẽ đệm cho đến khi máy quay sao lưu.

FIFO Xử lý Chính xác-Một lần : Một tin nhắn được gửi một lần và vẫn có sẵn cho đến khi người tiêu dùng xử lý và xóa nó. Các bản sao không được đưa vào hàng đợi.

Ngoài ra, hãy cân nhắc xem bạn có thực sự cần 'thực hiện hàng loạt' các thao tác này hay không. Điều gì xảy ra nếu các bản cập nhật trong một đêm lớn hơn đáng kể so với dự kiến? Ngay cả với nguồn cung ứng động, quá trình xử lý của bạn có thể bị trì hoãn khi chờ đủ máy. Thay vào đó, hãy lưu trữ dữ liệu của bạn trong SDB, thông báo cho máy về các bản cập nhật qua SQS và tạo nguồn cấp dữ liệu RSS của bạn ngay lập tức (với bộ nhớ đệm).

Các công việc hàng loạt có từ thời mà tài nguyên xử lý còn hạn chế và các dịch vụ 'sống' được ưu tiên hơn. Trong đám mây, đây không phải là trường hợp.


Cảm ơn - Tôi thích hướng mà bạn đang mô tả.
Tom

5
Lưu ý rằng SQS chỉ đảm bảo rằng một máy cuối cùng sẽ nhìn thấy một thông báo, chứ không phải rằng các thông báo sẽ chỉ được nhìn thấy bởi một máy chủ duy nhất. Bất cứ thứ gì bạn đưa vào hàng đợi SQS đều phải là idmpotent.
Richard Hurt

Công việc cron của tôi phải chạy hàng ngày và với SQS, bạn chỉ có thể trì hoãn tối đa 15 phút. Một tùy chọn có thể là thêm thẻ tùy chỉnh vào tin nhắn với thời gian đích để thực thi nó và đưa nó trở lại hàng đợi nếu chưa đến thời gian đó - nhưng điều này thực sự có vẻ ngớ ngẩn. Ngoài ra, tôi vẫn cần một công việc cron để ban đầu điền vào hàng đợi. Có vẻ như một vấn đề gà-trứng :) Nhưng tôi vẫn nghĩ rằng SQS là điều đúng đắn để sử dụng, vì nó đảm bảo khả năng mở rộng và lỗi khoan nhượng
Raffaele Rossi

"Các công việc hàng loạt có từ thời khi tài nguyên xử lý bị hạn chế và các dịch vụ 'trực tiếp' được ưu tiên hơn. Trong đám mây, điều này không đúng như vậy." Điều này đúng với một số nhưng không phải tất cả các hoạt động. Ví dụ: xử lý nhật ký lưu lượng truy cập là một cái gì đó tốt hơn là một quá trình hàng loạt hơn là trực tiếp.
Jordan Reiter

1

Tại sao bạn sẽ xây dựng của riêng bạn? Tại sao không sử dụng một cái gì đó như Quartz (với Lập lịch theo cụm). Xem tài liệu.

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


Tôi đã sử dụng Quartz.NET trong một giải pháp SaaS chủ yếu dựa vào các tác vụ đã lên lịch. Một số nơi thực hiện nhiệm vụ bảo trì hệ thống, nhưng hầu hết là nơi hoạt động do người dùng cuối lên lịch. Tất cả các nhiệm vụ của chúng tôi được viết vào hàng đợi tin nhắn (amq) mà chúng tôi có bất kỳ số lượng dịch vụ Idempotent nào. API rất tốt và cho phép lập lịch trình mạnh mẽ. Chúng tôi đã không phân cụm nhiều phiên bản Quartz, nhưng nó hỗ trợ điều đó.
Jerico Sandhorn

1

Những gì chúng tôi làm là chúng tôi có một máy chủ cụ thể là một phần của cụm ứng dụng web của chúng tôi đằng sau một ELB cũng được gán một tên DNS cụ thể để chúng tôi có thể chạy các công việc trên một máy chủ cụ thể đó. Điều này cũng có lợi ích là nếu công việc đó làm cho máy chủ đó chậm lại, ELB sẽ xóa nó khỏi cụm và sau đó trả lại nó khi công việc kết thúc và nó hoạt động trở lại.

Hoạt động như một nhà vô địch.


1

Một phương pháp để xác minh rằng biểu thức cron của bạn hoạt động theo cách của Amazon là chạy nó thông qua lệnh sự kiện. Ví dụ:

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

Nếu biểu thức lịch biểu của bạn không hợp lệ, thì điều này sẽ không thành công.

Các tài nguyên khác: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html



0

Vì không ai đề cập đến Sự kiện CloudWatch , tôi muốn nói rằng đó là cách AWS thực hiện các công việc cron. Nó có thể chạy nhiều hành động, chẳng hạn như hàm Lambda, tác vụ ECS.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.