2010-11-21 33 views
11

Sau khi nói chuyện với một người bạn của tôi từ Google, tôi muốn triển khai một số kiểu Job/Worker để cập nhật tập dữ liệu của mình.Tôi có nên học/sử dụng MapReduce hoặc một số loại song song khác cho tác vụ này không?

Tập dữ liệu này phản ánh dữ liệu của dịch vụ bên thứ 3, do đó, để thực hiện cập nhật, tôi cần thực hiện một số cuộc gọi từ xa đến API của họ. Tôi nghĩ rằng rất nhiều thời gian sẽ được chi tiêu chờ đợi phản hồi từ dịch vụ bên thứ 3 này. Tôi muốn tăng tốc mọi thứ và tận dụng tốt hơn thời gian tính toán của mình, bằng cách song song các yêu cầu này và giữ cho nhiều người trong số họ mở cùng một lúc, khi họ chờ phản hồi cá nhân của họ.

Trước khi tôi giải thích số liệu cụ thể của tôi và nhận được vào vấn đề, tôi muốn làm rõ những gì câu trả lời tôi đang tìm:

  1. Đây có phải là một dòng chảy đó sẽ là rất phù hợp với parallelizing với MapReduce?
  2. Nếu , điều này có hiệu quả về chi phí để chạy trên mô đun Mapreduce của Amazon, hóa đơn theo giờ và làm tròn giờ khi công việc hoàn tất? (Tôi không chắc chính xác số tiền được tính là "Công việc", vì vậy tôi không biết chính xác mình sẽ bị lập hoá đơn như thế nào)
  3. Nếu no, Có hệ thống/mẫu khác nào tôi nên sử dụng không? Có thư viện nào giúp tôi làm điều này trong python (Trên AWS, EC2 + EBS)?
  4. Có bất kỳ vấn đề nào bạn thấy với cách tôi đã thiết kế quy trình công việc này không?

Ok, bây giờ vào các chi tiết:

Bộ dữ liệu bao gồm những người dùng có các mục yêu thích và những người đi theo những người dùng khác. Mục đích là để có thể cập nhật hàng đợi của từng người dùng - danh sách các mục mà người dùng sẽ thấy khi họ tải trang, dựa trên các mục yêu thích của người dùng mà cô ấy theo dõi. Tuy nhiên, trước khi tôi có thể thu thập dữ liệu và cập nhật hàng đợi của người dùng, tôi cần đảm bảo rằng tôi có dữ liệu cập nhật nhất, là nơi các cuộc gọi API đến.

Có hai cuộc gọi tôi có thể thực hiện :

  • Get người dùng tiếp theo - trả về tất cả những người sử dụng bị theo dõi bởi người sử dụng yêu cầu, và
  • Get mục yêu thích - trả về tất cả các mục yêu thích của người sử dụng yêu cầu.

Sau khi tôi gọi để người dùng được theo dõi cho người dùng được cập nhật, tôi cần cập nhật các mục yêu thích cho từng người dùng đang được theo dõi. Chỉ khi tất cả các mục yêu thích được trả lại cho tất cả người dùng được theo dõi, tôi có thể bắt đầu xử lý hàng đợi cho người dùng ban đầu đó. dòng chảy này trông giống như:

Updating UserX's Queue

Jobs trong dòng này bao gồm:

  • Bắt đầu cập nhật Queue cho người dùng - Khai mạc quá trình này bằng cách lấy những người sử dụng tiếp theo người dùng được cập nhật, lưu trữ chúng và sau đó tạo Nhận các yêu thích công việc cho mỗi người dùng.
  • Nhận yêu thích cho người dùng - Yêu cầu và cửa hàng, danh sách mục yêu thích cho người dùng được chỉ định, từ dịch vụ của bên thứ 3.
  • Tính hàng đợi mới cho người dùng - Xử lý hàng đợi mới, bây giờ tất cả dữ liệu đã được tìm nạp, sau đó lưu trữ kết quả trong bộ nhớ cache được lớp ứng dụng sử dụng.

Vì vậy, một lần nữa, câu hỏi của tôi là:

  1. Đây có phải là một dòng chảy đó sẽ là rất phù hợp với parallelizing với MapReduce? Tôi không biết nếu nó sẽ cho phép tôi bắt đầu quá trình cho UserX, lấy tất cả các dữ liệu liên quan, và trở lại để xử lý hàng đợi của UserX chỉ sau khi tất cả đã xong.
  2. Nếu , điều này có hiệu quả về chi phí để chạy trên mô đun Mapreduce của Amazon, hóa đơn theo giờ và làm tròn giờ khi công việc hoàn tất? Có giới hạn về số lượng "chuỗi" mà tôi có thể chờ đợi trên các yêu cầu API mở nếu tôi sử dụng mô-đun của mình không?
  3. Nếu không, Tôi có nên sử dụng hệ thống/mẫu khác không? Có thư viện nào giúp tôi thực hiện điều này trong python (Trên AWS, EC2 + EBS không?)?
  4. Có bất kỳ vấn đề nào bạn thấy với cách tôi đã thiết kế quy trình công việc này không?

Cảm ơn bạn đã đọc, tôi mong được thảo luận với tất cả các bạn.

Sửa, để đáp ứng với JimR:

Cám ơn bài trả lời rắn. Trong bài đọc của tôi kể từ khi tôi viết câu hỏi ban đầu, tôi đã từ bỏ việc sử dụng MapReduce. Tôi chưa quyết định chắc chắn cách tôi muốn xây dựng điều này, nhưng tôi bắt đầu cảm thấy MapReduce là tốt hơn cho việc phân phối/song song tải máy tính khi tôi thực sự chỉ tìm cách song song các yêu cầu HTTP.

Tác vụ "giảm" của tôi là gì, phần mất tất cả dữ liệu được tìm nạp và đưa dữ liệu vào kết quả, không phải là tính toán chuyên sâu. Tôi khá chắc chắn nó sẽ gió lên được một truy vấn SQL lớn thực hiện cho một hoặc hai giây cho mỗi người dùng.

Vì vậy, những gì tôi đang nghiêng về phía là:

  • Một phi MapReduce Job/Worker mô hình, viết bằng Python . Một người bạn Google của tôi đã biến tôi thành học Python vì điều này là do chi phí thấp và quy mô tốt.
  • Sử dụng Amazon EC2 làm lớp tính toán. Tôi nghĩ điều này có nghĩa là tôi cũng cần một lát EBS để lưu trữ cơ sở dữ liệu của mình.
  • Có thể sử dụng hàng đợi Tin nhắn đơn giản của Amazon. Có vẻ như phụ tùng amazon thứ 3 này được thiết kế để theo dõi hàng đợi công việc, di chuyển kết quả từ một nhiệm vụ sang đầu vào của một công cụ khác và xử lý một cách duyên dáng các tác vụ không thành công. Nó rất rẻ. Có thể đáng thực hiện thay vì hệ thống xếp hàng công việc tùy chỉnh.
+0

Tôi đã sử dụng công cụ ứng dụng của google cho các yêu cầu cao song song và xử lý thời gian thực gần với loại vấn đề này. MapReduce có chi phí khởi động và chu kỳ công việc cao hơn nhiều so với tôi đang tìm kiếm. – kevpie

+0

Thú vị. Tôi biết công cụ ứng dụng có thể sử dụng python, đó là những gì tôi đã được homing trong ngày để viết những công việc này, nhưng tôi không rõ ràng về cách khác tôi muốn sử dụng GAE cho việc này. Tôi không quen thuộc với cách GAE hoạt động, cũng không phải với cách để cụm từ vấn đề này, vì vậy tôi đang ở một mất mát để tìm câu trả lời của tôi. Bạn có bất kỳ tài nguyên nào khác mà tôi nên xem xét ở đây không? Cảm ơn vì tiền hỗ trợ! –

+0

Tôi thực sự đã viết một quá trình python sử dụng các luồng và xếp hàng để thực hiện các yêu cầu web song song và xử lý dữ liệu. Nó hoạt động tốt, nhưng tôi đã không "hoàn toàn thông thạo" trong lập trình python, hoặc chủ đề, để làm cho nó thực sự đáng tin cậy, hoặc thực hiện tốt. Sau rất nhiều googling, và một số thất vọng, và các nhiệm vụ khác cần ưu tiên - tôi từ bỏ làm việc trên đó. Tôi có thể nhặt nó lên một lần nữa. Tôi đã đi đến kết luận tương tự về làm việc với MapReduce, vì tôi sẽ không thực sự tận dụng bất cứ điều gì nhưng song song được xây dựng thành hadoop. Dù sao, nếu bạn muốn trò chuyện thêm về phương pháp tiếp cận và giải pháp, lmk! –

Trả lời

1

Dường như chúng ta đang đi với Node.js và thư viện điều khiển luồng Seq. Rất dễ dàng di chuyển từ bản đồ/sơ đồ quy trình của tôi đến mã nguồn của mã, và bây giờ nó chỉ là việc điền mã để nối vào đúng API.

Cảm ơn câu trả lời, họ rất nhiều trợ giúp tìm giải pháp mà tôi đang tìm kiếm.

0

Tôi đang làm việc với một vấn đề tương tự mà tôi cần phải giải quyết. Tôi cũng đang xem xét MapReduce và sử dụng dịch vụ Elastic MapReduce từ Amazon.

Tôi khá thuyết phục rằng MapReduce sẽ làm việc cho vấn đề này. Việc thực hiện là nơi tôi đang bị treo lên, bởi vì tôi không chắc chắn giảm tốc của tôi thậm chí cần phải làm bất cứ điều gì.

Tôi sẽ trả lời các câu hỏi của bạn khi tôi hiểu vấn đề của bạn (và của tôi), và hy vọng điều đó sẽ hữu ích.

  1. Vâng tôi nghĩ nó sẽ rất phù hợp. Bạn có thể xem xét tận dụng tùy chọn nhiều bước của dịch vụ Elastic MapReduce. Bạn có thể sử dụng 1 Bước để tìm nạp người mà người dùng đang theo dõi và một bước khác để biên soạn danh sách các bản nhạc cho từng người theo dõi đó và trình giảm tốc cho bước thứ hai đó có thể sẽ là bộ đệm để tạo bộ nhớ cache.

  2. Phụ thuộc vào mức độ tập dữ liệu của bạn và mức độ thường xuyên bạn sẽ chạy. Thật khó để nói mà không biết làm thế nào lớn tập dữ liệu là (hoặc sẽ nhận được) nếu nó sẽ có hiệu quả chi phí hay không. Ban đầu, nó có thể sẽ khá hiệu quả về chi phí, vì bạn sẽ không phải quản lý cụm Hadoop của riêng bạn, cũng như không phải trả tiền cho các trường hợp EC2 (giả sử đó là những gì bạn sử dụng) để luôn luôn hoạt động. Một khi bạn đạt đến điểm mà bạn đang thực sự crunching dữ liệu này trong một thời gian dài, nó có thể sẽ làm cho ít hơn và ít ý nghĩa hơn để sử dụng dịch vụ MapReduce của Amazon, bởi vì bạn sẽ liên tục có các nút trực tuyến tất cả các thời gian.

Công việc cơ bản là nhiệm vụ MapReduce của bạn. Nó có thể bao gồm nhiều bước (mỗi tác vụ MapReduce là một bước). Khi dữ liệu của bạn đã được xử lý và tất cả các bước đã được hoàn thành, công việc của bạn đã hoàn tất. Vì vậy, bạn đang trả tiền hiệu quả cho thời gian CPU cho mỗi nút trong cụm Hadoop. vì vậy, T * n trong đó T là Thời gian (tính theo giờ) cần để xử lý dữ liệu của bạn, và n là số lượng nút bạn yêu cầu Amazon quay lên.

Tôi hy vọng điều này sẽ giúp, chúc may mắn. Tôi muốn nghe cách bạn kết thúc triển khai Mappers và Reducers của bạn, vì tôi đang giải quyết một vấn đề rất giống nhau và tôi không chắc chắn cách tiếp cận của tôi thực sự là tốt nhất.

+0

Trả lời tốt. Tôi đã đăng phản hồi trong bài viết chính giải thích những gì tôi đang hướng tới và tại sao. Hy vọng rằng sẽ giúp, và may mắn! –

5

Công việc bạn mô tả có thể phù hợp với hàng đợi hoặc kết hợp hàng đợi và máy chủ công việc. Nó chắc chắn có thể hoạt động như một tập hợp các bước MapReduce.

Đối với máy chủ công việc, tôi khuyên bạn nên xem Gearman. Tài liệu không phải là tuyệt vời, nhưng các bài thuyết trình làm một công việc tuyệt vời ghi lại nó, và mô-đun Python là khá tự giải thích quá.

Về cơ bản, bạn tạo các chức năng trong máy chủ công việc và các chức năng này được khách hàng gọi thông qua API. Các hàm có thể được gọi là đồng bộ hoặc không đồng bộ. Trong ví dụ của bạn, bạn có thể muốn thêm không đồng bộ công việc "Bắt đầu cập nhật". Điều đó sẽ làm bất kỳ nhiệm vụ chuẩn bị nào, và sau đó gọi không đồng bộ cho công việc "Nhận người dùng đã theo dõi". Công việc đó sẽ tìm nạp người dùng và sau đó gọi lệnh "Cập nhật người dùng đã theo dõi". Điều đó sẽ gửi tất cả các "Nhận yêu thích cho UserA" và công việc bạn bè cùng nhau trong một lần, và đồng bộ chờ kết quả của tất cả chúng. Khi tất cả được trả lại, nó sẽ gọi công việc "Tính toán hàng đợi mới".

Phương pháp tiếp cận công việc-máy chủ này ban đầu sẽ kém hiệu quả hơn một chút, vì đảm bảo rằng bạn xử lý lỗi và bất kỳ máy chủ nào cũng như sự kiên trì đúng đắn sẽ trở nên thú vị.

Đối với hàng đợi, SQS là lựa chọn hiển nhiên. Nó là đá rắn, và rất nhanh chóng truy cập từ EC2, và giá rẻ. Và cách dễ dàng hơn để thiết lập và duy trì hơn các hàng đợi khác khi bạn mới bắt đầu.

Về cơ bản, bạn sẽ đặt một thông báo lên hàng đợi, giống như bạn sẽ gửi công việc đến máy chủ công việc ở trên, ngoại trừ bạn có thể sẽ không thực hiện bất kỳ điều gì một cách đồng bộ.Thay vì làm cho "Nhận yêu thích cho UserA" và vv cuộc gọi đồng bộ, bạn sẽ làm cho họ không đồng bộ, và sau đó có một thông báo nói để kiểm tra xem tất cả chúng đã được hoàn thành. Bạn sẽ cần một số loại kiên trì (một cơ sở dữ liệu SQL mà bạn quen thuộc, hoặc SimpleDB của Amazon nếu bạn muốn hoàn toàn AWS) để theo dõi xem công việc đã hoàn thành chưa - bạn không thể kiểm tra tiến độ của một công việc trong SQS (mặc dù bạn có thể trong hàng đợi khác). Thông báo kiểm tra xem liệu chúng có được hoàn thành hay không sẽ thực hiện kiểm tra - nếu chúng không hoàn tất, không làm gì cả, và sau đó thông báo sẽ được thử lại sau vài phút (dựa trên visibility_timeout). Nếu không, bạn có thể đặt thông báo tiếp theo trên hàng đợi.

Cách tiếp cận chỉ xếp hàng này phải mạnh mẽ, giả sử bạn không sử dụng thông điệp xếp hàng do nhầm lẫn mà không thực hiện công việc. Thực hiện một sai lầm như thế là khó để làm với SQS - bạn thực sự phải cố gắng. Không sử dụng hàng đợi hoặc giao thức tự động - nếu bạn bị lỗi, bạn có thể không đảm bảo rằng bạn đặt một thông điệp thay thế trở lại trên hàng đợi.

Kết hợp hàng đợi và máy chủ công việc có thể hữu ích trong trường hợp này. Bạn có thể lấy đi với không có một cửa hàng kiên trì để kiểm tra tiến độ công việc - máy chủ công việc sẽ cho phép bạn theo dõi tiến độ công việc. Thông điệp "yêu thích cho người dùng" của bạn có thể đặt tất cả công việc "yêu thích cho UserA/B/C" vào máy chủ công việc. Sau đó, đặt một "kiểm tra tất cả yêu thích tìm nạp xong" tin nhắn trên hàng đợi với một danh sách các nhiệm vụ cần phải được hoàn thành (và đủ thông tin để khởi động lại bất kỳ công việc bí ẩn biến mất).

Đối với điểm thưởng:

Làm điều này như một MapReduce nên khá dễ dàng.

Thông tin nhập của công việc đầu tiên của bạn sẽ là danh sách tất cả người dùng của bạn. Bản đồ sẽ đưa mỗi người dùng, nhận người dùng theo dõi và dòng đầu ra cho mỗi người dùng và người dùng được theo dõi của họ:

"UserX" "UserA" 
"UserX" "UserB" 
"UserX" "UserC" 

Một bước giảm nhận dạng sẽ không thay đổi. Điều này sẽ tạo thành đầu vào của công việc thứ hai. Bản đồ cho công việc thứ hai sẽ nhận được yêu thích cho mỗi dòng (bạn có thể muốn sử dụng memcached để ngăn tìm nạp mục ưa thích cho UserX/UserA combo và UserY/UserA thông qua API) và xuất một dòng cho mỗi mục yêu thích:

"UserX" "UserA" "Favourite1" 
"UserX" "UserA" "Favourite2" 
"UserX" "UserA" "Favourite3" 
"UserX" "UserB" "Favourite4" 

Các giảm bước cho việc làm này sẽ chuyển đổi này để:

"UserX" [("UserA", "Favourite1"), ("UserA", "Favourite2"), ("UserA", "Favourite3"), ("UserB", "Favourite4")] 

Tại thời điểm này, bạn có thể có một công việc MapReduce để cập nhật cơ sở dữ liệu của bạn cho mỗi người dùng với những giá trị này, hoặc bạn có thể sử dụng một số các công cụ liên quan đến Hadoop như Pig, Hive và HBase để quản lý cơ sở dữ liệu của bạn cho bạn.

Tôi khuyên bạn nên sử dụng Phân phối của Cloudera cho các lệnh quản lý ec2 của Hadoop để tạo và xé cụm Hadoop của bạn trên EC2 (AMI của họ có cài đặt Python) và sử dụng một cái gì đó như Dumbo (trên PyPI) để tạo MapReduce của bạn các công việc, vì nó cho phép bạn kiểm tra các công việc MapReduce của bạn trên máy cục bộ/dev của bạn mà không cần truy cập vào Hadoop.

Chúc may mắn!

+1

Cảm ơn bạn đã phản hồi rất kỹ lưỡng. Sẽ phải ngồi xuống và đi qua cái này đúng cách. –

Các vấn đề liên quan