2012-12-24 32 views
6

Một người bạn của tôi đã được hỏi về vấn đề này trong một cuộc phỏng vấn. Tôi muốn thảo luận vấn đề này tại đâyThiết kế/Người điều phối mã cho Hệ thống đăng ký xuất bản

Điều gì có thể thực hiện hiệu quả cho vấn đề này?

Một ý tưởng đơn giản mà đến với tôi là memqueue bình thường, sử dụng máy Memcache để mở rộng một số yêu cầu, với một công việc của người tiêu dùng chạy mà sẽ viết những thứ từ memcache để DB. và sau đó cho phần thứ hai, chúng tôi chỉ có thể chạy truy vấn sql để tìm danh sách người đăng ký phù hợp.

VẤN ĐỀ: -

Sự kiện được xuất bản lên hệ thống này. Mỗi sự kiện có thể được coi là chứa một số cố định (N) của các cột chuỗi được gọi là C1, C2,… CN. Mỗi sự kiện do đó có thể được truyền xung quanh như là một mảng của các chuỗi (C1 là phần tử thứ 0 trong mảng, C2 ngày 1 và vv).

Có M thuê bao - S1, ... SM

Mỗi thuê bao đăng ký một vị chỉ rõ những gì tập hợp con của các sự kiện đó là quan tâm đến mỗi vị có thể chứa:

Equality clause on columns, for example: (C1 == “US”) 
Conjunctions of such clauses, example: 
    (C1 == “IN”) && (C2 == “home.php”) 
    (C1 == “IN”) && (C2 == “search.php”) && (C3 == “nytimes.com”) 

(Trong ví dụ trên. , C1 là viết tắt của mã quốc gia của một sự kiện và C2 là viết tắt của trang web của trang web và C3 là mã liên kết giới thiệu.)

tức là. - mỗi vị từ là một kết hợp của một số điều kiện bình đẳng. Lưu ý rằng biến vị ngữ không nhất thiết phải có một mệnh đề bình đẳng cho tất cả các cột (ví dụ - một vị từ có thể không quan tâm đến giá trị của một số hoặc tất cả các cột). (Trong ví dụ trên: #a không quan tâm đến các cột C3,… CN).

Chúng tôi phải thiết kế và mã hóa Người điều phối có thể khớp các sự kiện đến với người đăng ký đã đăng ký. Tỷ lệ sự kiện đến là hàng triệu mỗi giây. Số lượng người đăng ký là hàng nghìn người đăng ký. Vì vậy, điều phối viên này phải rất hiệu quả. Nói một cách đơn giản:

When the system boots, all the subscribers register their predicates to the dispatcher 
After this events start coming to the dispatcher 
For each event, the dispatcher has to emit the id of the matching subscribers. 

trong điều khoản của một đặc tả giao diện, sau đây có thể được tạm nêu ra (trong Java):

Class Dispatcher { 

    public Dispatcher(int N /* number of columns in each event – fixed up front */); 

    public void registerSubscriber(String subscriberId /* assume no conflicts */, 
            String predicate /* predicate for this subscriberid */); 

    public List<String> findMatchingIds(String[] event /* assume each event has N Strings */); 

} 

Ie .: Cơ sở điều phối được xây dựng, sau đó một loạt các registerSubscriber cuộc gọi được thực hiện. Sau đó, chúng ta liên tục gọi phương thức findMatchingIds() và mục đích của bài tập này là làm cho hàm này hiệu quả nhất có thể.

+0

'Vị từ chuỗi/* vị ngữ cho người đăng ký này * /' - Không phải là biến này là 'predicate]' String? – JimmyB

+0

Không, bạn sẽ phải phân tích cú pháp chính mình – Peter

+0

Xin chào, câu hỏi thực sự thú vị. và hình thành những gì tôi đọc trong [Manning mahout in action] vấn đề của bạn phù hợp với Công cụ đề xuất. và tôi trích dẫn: > Công cụ khuyến nghị là máy học tập dễ nhận biết nhất ngay lập tức kỹ thuật được sử dụng hôm nay nó tương tự như những gì amazon khi chúng giới thiệu sách cho bạn. Nếu bạn thích tôi có thể gửi cho bạn những gì đã được giải pháp của mình cho một vấn đề như vậy. –

Trả lời

1

Như Hanno Binder ngụ ý, vấn đề được thiết lập rõ ràng để cho phép xử lý trước các đăng ký để có được một cấu trúc tra cứu hiệu quả. Hanno nói rằng tra cứu phải là một bản đồ

(N, K) -> set of subscribers who specified K in field N  
(N, "") -> set of subscribers who omitted a predicate for field N 

Khi một sự kiện đến, chỉ cần tra cứu tất cả các bộ thích hợp và tìm giao lộ của chúng. Lỗi tra cứu trả về tập trống. Tôi chỉ tóm lại câu trả lời tốt của Hanno để chỉ ra rằng một bảng băm là O (1) và có lẽ nhanh hơn trong ứng dụng này hơn là một cái cây. Mặt khác, cây giao nhau có thể nhanh hơn, O (S + log N) trong đó S là kích thước giao nhau. Vì vậy, nó phụ thuộc vào bản chất của bộ.

Alternative

Dưới đây là cấu trúc tra cứu thay thế của tôi, một lần nữa tạo ra chỉ một lần trong tiền xử lý. Bắt đầu bằng cách biên soạn bản đồ

(N, K) -> unique token T (small integer) 

Cũng có một mã vạch phân biệt là "không quan tâm".

Bây giờ mọi biến vị ngữ đều có thể được xem như là một mẫu giống như biểu thức chính quy với mã thông báo N, đại diện cho một chuỗi chuỗi sự kiện cụ thể hoặc "không quan tâm".

Chúng tôi hiện có thể xây dựng cây quyết định trước. Bạn cũng có thể nghĩ cây này là một Automaton hữu hạn xác định (DFA) để nhận ra các mẫu. Các cạnh được gắn nhãn bằng các thẻ, bao gồm cả "không quan tâm". Một cạnh không quan tâm được thực hiện nếu không có cạnh khác phù hợp. Trạng thái chấp nhận chứa tập hợp người đăng ký tương ứng.

Xử lý sự kiện bắt đầu bằng cách chuyển đổi khóa thành mẫu mã thông báo. Nếu điều này không thành công do thiếu mục nhập bản đồ thì không có người đăng ký nào. Nếu không, hãy cung cấp mẫu cho DFA. Nếu DFA tiêu thụ mẫu mà không gặp sự cố, trạng thái cuối cùng chứa tập hợp người đăng ký. Trả lại cái này.

Ví dụ, chúng ta sẽ có bản đồ:

(1, "IN") -> 1 
(2, "home.php") -> 2 
(2, "search.php") -> 3 
(3, "nytimes.com") -> 4 

Đối với N = 4, DFA sẽ trông như thế này:

o --1--> o --2--> o --0--> o --0--> o 
      \ 
      -3--> o --4--> o --0--> o 

Lưu ý rằng vì không có thuê bao người don' t quan tâm ví dụ C1, trạng thái bắt đầu không có chuyển tiếp không quan tâm. Bất kỳ sự kiện nào không có "IN" trong C1 sẽ gây ra sự cố và bộ null sẽ được trả lại đúng.

Chỉ với hàng nghìn người đăng ký, kích thước của DFA này phải hợp lý.

Thời gian xử lý ở đây tất nhiên là O (N) và có thể rất nhanh trong thực tế. Đối với tốc độ thực, quá trình tiền xử lý có thể tạo và biên dịch một tổ hợp các câu lệnh chuyển đổi C. Trong thời trang này bạn thực sự có thể nhận được hàng triệu sự kiện mỗi giây với một số lượng nhỏ các bộ vi xử lý.

Bạn thậm chí có thể coax một công cụ chuẩn như the flex scanner generator để thực hiện hầu hết công việc cho bạn.

+0

Một nitpick trong câu trả lời của bạn: DFA là xác định hữu hạn Automaton, không rời rạc hữu hạn Automaton – Arvind

+0

Cảm ơn. Tôi trân trọng điều đó. Nhập quá nhiều mà không cần suy nghĩ ... – Gene

1

Một giải pháp mà nói đến cái tâm của tôi sẽ là:

Đối với mỗi Cn chúng tôi có một ánh xạ từ các giá trị cho bộ thuê bao đối với những thuê bao đăng ký với giá trị giao Cn. Ngoài ra, đối với mỗi Cn, chúng tôi có một nhóm người đăng ký không quan tâm đến giá trị của Cn ('BẤT K' ').

Khi nhận được sự kiện, chúng tôi tra cứu tất cả người đăng ký có đăng ký phù hợp cho Cn và nhận bộ có từ 0 người đăng ký trở lên. Để thiết lập này, chúng tôi thêm những người đăng ký từ 'ANY' cho Cn này.

Chúng tôi thực hiện việc này cho mỗi n < = N, cho ra n bộ người đăng ký. Giao điểm của tất cả các bộ n là tập hợp người đăng ký phù hợp với sự kiện này.

Ánh xạ từ Cn tới người đăng ký có thể được lưu trữ hiệu quả dưới dạng cây, cung cấp độ phức tạp O (k) = log (k) để tìm kiếm người đăng ký cho một Cn duy nhất. .

Vì vậy, đối với giá trị n, chúng tôi có độ phức tạp của O (n, k) = n * log (k).

Bộ giao nhau cũng có thể được thực hiện trong O (n, m) = n * nhật ký (m), để chúng ta kết thúc với độ phức tạp lôgarít, không quá tệ.

1

Thú vị.

Suy nghĩ ban đầu của tôi. Tôi cảm thấy sẽ dễ dàng hơn nếu người đăng ký dự đoán ví dụ:

(C1 == “IN”) & & (C2 == “search.php”) & & (C3 == “nytimes.com”)

rằng đến dispatcher

public void registerSubscriber

phương pháp cần phải được được làm phẳng để có hiệu suất rất thân thiện để so sánh. Một cái gì đó như dưới đây (hoang dã đoán)

C1IN | C2search.php | C3nytimes.com

Sau đó, một bản đồ cần phải được duy trì trong bộ nhớ với chuỗi sự kiện và thuê bao id

Trong

findMatchingIds

phương pháp - mảng chuỗi các sự kiện cũng cần phải phẳng với các quy tắc tương tự để cho một cái nhìn lên có thể được thực hiện cho id phù hợp thuê bao

Bằng cách này, điều phối có thể được thu nhỏ theo chiều ngang phục vụ nhiều sự kiện song song

1

Tôi nghĩ rằng đây là một câu hỏi thiết kế - Tôi không nghĩ rằng người phỏng vấn sẽ tìm kiếm mã làm việc. Các vấn đề chung được gọi là Content based Publish Subscribe, và nếu bạn tìm kiếm giấy tờ trong cùng khu vực, bạn sẽ nhận được rất nhiều kết quả: Đối instance- this paper also

Dưới đây là vài điều hệ thống sẽ cần

1) dữ liệu lưu trữ cho các mục đăng ký mà cần phải lưu trữ: a) lưu trữ danh sách các thuê bao b) lưu trữ danh sách các thuê bao

2) Phương tiện để xác thực các yêu cầu đăng ký và các nút tự a) Server- Người đăng ký giao tiếp qua ssl. Trong trường hợp máy chủ xử lý hàng nghìn kết nối SSL - Đó là một nhiệm vụ chuyên sâu của CPU, đặc biệt nếu nhiều kết nối được thiết lập trong các cụm.
b) Nếu tất cả các nút thuê bao nằm trong cùng một mạng tin cậy, không cần phải có ssl.

3) Cho dù chúng ta muốn có một Đẩy hoặc Kéo mô hình dựa trên:

a) Server có thể duy trì một timestamp mới nhất được xem mỗi nút, mỗi bộ lọc phù hợp. Khi sự kiện phù hợp với bộ lọc, hãy gửi thông báo cho người đăng ký. Hãy để khách hàng sau đó gửi yêu cầu. Máy chủ sau đó bắt đầu gửi các sự kiện phù hợp.

b) Kết hợp máy chủ và gửi bộ lọc cho khách hàng tại một lần chụp.

Sự khác biệt giữa (a) và (b) là, trong (a) bạn có nhiều trạng thái được duy trì ở phía khách hàng hơn. Dễ dàng mở rộng logic dành riêng cho người đăng ký sau này. Trong (b) khách hàng là câm. Nó không có bất kỳ phương tiện để nói nếu nó không muốn nhận các sự kiện vì lý do gì. (nói, làm tắc nghẽn mạng).

4) Các sự kiện được duy trì trong bộ nhớ ở phía máy chủ như thế nào?

a)The logical model here is table with columns of strings (C1..CN), and each new row added is a new event. 
b)We could have A hash-table per column storing a tupple of (timestamp, pointer to event structure). And each event is given a unique id. With different data-structures,we can come up with different schemes. 
c) Events here are considered as infinite stream. If we have a 32-bit eventId, we have chances of integer-overflow. 
d) If we have a timer function on the server, matching and dispatching events,what is the actual resolution of the system timer? Does that have any implication? 
    e) Memory allocation is a very expensive operation. If your filter-matching logic is going to do frequent allocations/ freeing, it will adversely affect performance. How can we manage the memory-pool for this particular operation? Would we different size-buckets of page-aligned memory? 

5) Điều gì sẽ xảy ra nếu nút thuê bao mất kết nối hoặc đi xuống? (a) Có thể chấp nhận cho khách hàng mất các sự kiện trong thời gian này hay máy chủ nên đệm mọi thứ? (b) Nếu người đăng ký ngừng hoạt động, cho đến thời điểm lịch sử nào trong quá khứ, họ có thể yêu cầu sự kiện phù hợp.

6) Thông tin chi tiết về lớp nhắn tin giữa (Máy chủ, Người đăng ký) (a) Giao tiếp giữa máy chủ và thuê bao có đồng bộ hoặc không đồng bộ không?
(b) Chúng ta có cần giao thức nhị phân hoặc giao thức dựa trên văn bản giữa máy khách/máy chủ không? (Có sự cân bằng trong cả hai)

7) Chúng ta có cần bất kỳ logic giới hạn tốc độ nào ở phía máy chủ không? Chúng ta nên làm gì nếu chúng ta bỏ đói một số khách hàng trong khi phục vụ dữ liệu cho vài người khác?

8) Thay đổi đăng ký sẽ được quản lý như thế nào? Nếu một số khách hàng muốn thay đổi đó là subsciption sau đó, nó nên được cập nhật trong bộ nhớ đầu tiên trước khi cập nhật dữ liệu lưu trữ vĩnh viễn? Hoặc ngược lại? Điều gì sẽ xảy ra nếu máy chủ bị hỏng, trước khi kho dữ liệu được ghi vào? Làm cách nào chúng tôi đảm bảo tính nhất quán của kho dữ liệu - danh sách đăng ký/máy chủ?

9) Điều này giả định rằng chúng tôi có một máy chủ duy nhất- Điều gì xảy ra nếu chúng tôi cần một cụm máy chủ mà người đăng ký có thể kết nối? (Toàn bộ các vấn đề ở đây:) a) Phân vùng mạng có thể được xử lý như thế nào? (ví dụ: nói 5 nút, 3 nút có thể truy cập được từ nhau và 2 nút khác chỉ có thể đạt được khác?) b) Sự kiện/khối lượng công việc được phân phối giữa các thành viên của cụm sao như thế nào?

10) Độ chính xác tuyệt đối của thông tin được gửi đến người đăng ký có yêu cầu hay không, tức là khách hàng có thể nhận thêm thông tin, rằng quy tắc đăng ký của nó cho biết? Điều này có thể xác định lựa chọn ví dụ về cấu trúc dữ liệu bằng cách sử dụng cấu trúc dữ liệu xác suất như bộ lọc Bloom ở phía máy chủ, trong khi thực hiện lọc

11) Thứ tự thời gian của các sự kiện được duy trì ở phía máy chủ như thế nào? (Thời gian được sắp xếp danh sách liên kết? Dấu thời gian?)

12) Trình phân tích cú pháp logic vị ngữ cho các đăng ký có cần hỗ trợ unicode không?

Kết luận, pub-sub dựa trên nội dung là một khu vực khá rộng lớn và nó là hệ thống phân tán liên quan đến sự tương tác của cơ sở dữ liệu, mạng, thuật toán, hành vi nút (hệ thống bị trục trặc, đĩa bị hỏng, hệ thống hết bộ nhớ vì rò rỉ bộ nhớ vv) - Chúng ta phải xem xét tất cả các khía cạnh này. Và quan trọng nhất, chúng ta phải xem xét thời gian có sẵn để thực hiện thực tế, và sau đó xác định cách chúng ta muốn giải quyết vấn đề này.

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