2011-11-30 36 views
5

Tôi đang cố gắng xây dựng một hệ thống phân phối hiệu suất cao với Akka và Scala.Hỗ trợ khung Akka để tìm các thư trùng lặp

Nếu một thông báo yêu cầu tính toán tốn kém (và tác dụng phụ) đến, và tính toán chính xác như nhau đã được yêu cầu trước đó, tôi muốn tránh tính toán kết quả lần nữa. Nếu tính toán được yêu cầu trước đó đã hoàn thành và kết quả có sẵn, tôi có thể lưu trữ nó và sử dụng lại nó.

Tuy nhiên, cửa sổ thời gian có thể yêu cầu tính toán trùng lặp có thể nhỏ tùy ý. ví dụ. Tôi có thể nhận được một nghìn hoặc một triệu tin nhắn yêu cầu cùng một tính toán đắt tiền tại cùng một thời điểm cho tất cả các mục đích thực tế.

Có một sản phẩm thương mại được gọi là Gigaspaces được cho là xử lý tình huống này.

Tuy nhiên, dường như không có hỗ trợ khung để xử lý các yêu cầu công việc trùng lặp trong Akka tại thời điểm này. Do khung công tác Akka đã có quyền truy cập vào tất cả các thông điệp được định tuyến thông qua khung công tác, có vẻ như một giải pháp khung có thể tạo ra nhiều ý nghĩa ở đây.

Dưới đây là những gì tôi đang đề xuất cho khung công tác Akka: 1. Tạo một đặc điểm để chỉ ra một loại thông báo (nói "ExpensiveComputation") hoặc một cái gì đó tương tự) phải tuân theo phương pháp bộ nhớ đệm sau. 2. Thông minh (băm, v.v.) xác định các thông điệp giống nhau nhận được bởi (cùng hoặc khác nhau) các tác nhân trong một cửa sổ thời gian có thể định cấu hình người dùng. Các tùy chọn khác: chọn kích thước bộ đệm tối đa của bộ nhớ được sử dụng cho mục đích này, tùy thuộc vào (thay thế LRU) vv Akka cũng có thể chọn chỉ lưu vào bộ nhớ cache kết quả của các thông điệp quá tốn kém; các thư mất quá ít thời gian để xử lý có thể được xử lý lại nếu cần; không cần phải lãng phí dung lượng bộ nhớ đệm quý giá của chúng và kết quả của chúng. 3. Khi các thông báo giống nhau (nhận được trong cửa sổ thời gian đó, có thể là "cùng một lúc") được xác định, tránh tính toán trùng lặp không cần thiết. Khung làm việc sẽ tự động thực hiện điều này và về cơ bản, các thông điệp trùng lặp sẽ không bao giờ được nhận bởi một diễn viên mới để xử lý; họ sẽ âm thầm biến mất và kết quả của việc xử lý nó một lần (cho dù tính toán đã được thực hiện trong quá khứ hoặc đang diễn ra ngay) sẽ được gửi đến tất cả người nhận thích hợp (ngay lập tức nếu đã có sẵn và sau khi hoàn thành tính toán nếu không). Lưu ý rằng các thư phải được coi là giống nhau ngay cả khi các trường "trả lời" khác nhau, miễn là ngữ nghĩa/tính toán mà chúng đại diện giống hệt nhau ở mọi khía cạnh khác. Cũng lưu ý rằng tính toán phải hoàn toàn có chức năng, tức là không có tác dụng phụ, cho tối ưu hóa bộ nhớ đệm được đề xuất để hoạt động và không thay đổi ngữ nghĩa của chương trình.

Nếu những gì tôi đề xuất không tương thích với cách làm việc của Akka và/hoặc nếu bạn thấy một số lý do chính đáng tại sao đây là một ý tưởng tồi, hãy cho tôi biết.

Cảm ơn, Is Awesome, Scala

Trả lời

10

gì bạn đang yêu cầu là không phụ thuộc vào khuôn khổ Akkanó là cách bạn kiến ​​trúc sư diễn viên và tin nhắn của bạn. Trước tiên, đảm bảo rằng các thư của bạn là không thay đổi và có một danh tính được xác định phù hợp thông qua các phương thức equals/hashCode. Trường hợp các lớp học cung cấp cho bạn cả hai miễn phí tuy nhiên nếu bạn có actorRefs nhúng trong tin nhắn cho mục đích trả lời, bạn sẽ phải ghi đè lên các phương pháp nhận dạng. Các tham số lớp vỏ cũng nên có cùng thuộc tính đệ quy (danh tính không thay đổi và đúng).

Thứ hai, bạn cần tìm hiểu cách các diễn viên sẽ xử lý việc lưu trữ và xác định các tính toán hiện tại/quá khứ.Cách đơn giản nhất là yêu cầu yêu cầu bản đồ duy nhất cho diễn viên. Bằng cách này diễn viên và chỉ diễn viên đó sẽ xử lý yêu cầu cụ thể đó. Điều này có thể được thực hiện dễ dàng với một bộ cố định các tác nhân và hashCode của yêu cầu. Điểm thưởng nếu bộ diễn viên được giám sát nơi người giám sát đang quản lý cân bằng tải/ánh xạ và thay thế các diễn viên không thành công (Akka làm cho phần này trở nên dễ dàng).

Cuối cùng, chính diễn viên có thể duy trì hoạt động bộ nhớ đệm phản hồi dựa trên tiêu chí bạn đã mô tả. Tất cả mọi thứ là thread an toàn trong bối cảnh của các diễn viên để một bộ nhớ cache LRU keyed bởi yêu cầu chính nó (đặc tính nhận dạng tốt nhớ) là dễ dàng với bất kỳ loại hành vi mà bạn muốn.

+0

có một biến thể của điều này phụ thuộc vào việc đảm bảo rằng thông điệp cuối cùng là thông điệp được xử lý không phải là những cái trước đó trong hàng đợi. tức là tôi không muốn bắt đầu tính toán đắt tiền cho đến khi tôi đảm bảo rằng tất cả các tin nhắn đã được nhận. Tôi nghĩ rằng cách tiếp cận trên có thể được sửa đổi với FSM để đạt được kết quả tương tự. – dres

5

Như Neil nói, đây không phải là chức năng khung thực sự, nó khá tầm thường để thực hiện điều này và thậm chí trừu tượng nó thành đặc điểm riêng của nó.

trait CachingExpensiveThings { self: Actor => 
    val cache = ... 
    def receive: Actor.Receive = { 
    case s: ExpensiveThing => cachedOrCache(s) 
    } 

    def cacheOrCached(s: ExpensiveThing) = cache.get(s) match { 
    case null => val result = compute(s) 
       cache.put(result) 
       self.reply_?)(result) 
    case cached => self.reply_?)(cached) 
    } 
    def compute(s: ExpensiveThing): Any 
} 


class MyExpensiveThingCalculator extends Actor with CachingExpensiveThings { 
    def compute(s: ExpensiveThing) = { 
    case l: LastDigitOfPi => ... 
    case ts: TravellingSalesman => ... 
    } 
} 
+0

Tôi cũng đã tính số cuối của Pi, bạn đã làm gì? ; p –

+1

Cái cuối cùng là π –

0

Tôi không biết tất cả những trách nhiệm này chỉ nên được xử lý bởi Akka. Như thường lệ, tất cả phụ thuộc vào quy mô và đặc biệt là số lượng thuộc tính xác định tính duy nhất của thông điệp.

Trong trường hợp cơ chế bộ nhớ cache, cách tiếp cận đã đề cập với yêu cầu ánh xạ duy nhất cho diễn viên là cách để đặc biệt là nó có thể được hỗ trợ bởi sự kiên trì.

Trong trường hợp sắc, thay vì kiểm tra bình đẳng đơn giản (có thể là nút cổ chai) Tôi sẽ thay vì sử dụng đồ thuật toán dựa nhưsignal-collect.

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