2012-10-17 31 views
6

Hệ thống của chúng tôi có mô hình có cấu trúc (khoảng 30 thực thể khác nhau với một số loại quan hệ) được lưu giữ hoàn toàn trong bộ nhớ (khoảng 10 Gb) vì lý do hiệu suất. Theo mô hình này, chúng tôi phải làm 3 loại hoạt động:Nên sử dụng Disruptor (LMAX) với mô hình lớn trong bộ nhớ và CQRS?

  1. cập nhật một hoặc một vài đơn vị
  2. truy vấn cho một dữ liệu cụ thể (điều này thường đòi hỏi phải đọc hàng ngàn đơn vị)
  3. có được số liệu thống kê (dung lượng bộ nhớ được sử dụng, số lượng truy vấn cho loại, v.v.)

Hiện tại kiến ​​trúc là một tiêu chuẩn khá, với một nhóm chủ đề cho các servlet sử dụng mô hình được chia sẻ. Bên trong mô hình có rất nhiều bộ sưu tập đồng thời, nhưng vẫn còn nhiều chờ đợi vì một số thực thể là "nóng" hơn và chủ yếu là các chủ đề muốn đọc/ghi chúng. Cũng lưu ý rằng các truy vấn thường có nhiều cpu và tốn thời gian hơn viết.

Tôi đang nghiên cứu khả năng chuyển sang kiến ​​trúc Disruptor giữ mô hình trong một chuỗi đơn lẻ, di chuyển mọi thứ có thể (kiểm tra tính hợp lệ, kiểm tra, v.v.) ra khỏi mô hình trong một người tiêu dùng riêng biệt.

Câu hỏi đầu tiên tất nhiên là: nó có hợp lý không?

Câu hỏi thứ hai là: các yêu cầu viết lý tưởng nên được ưu tiên hơn các lượt đọc. Đó là cách tốt nhất để có một ưu tiên trong disruptor? Tôi đã suy nghĩ về 2 vòng đệm và sau đó cố gắng để đọc từ một trong những cao hơn một thường xuyên hơn từ một ưu tiên thấp.

Để làm rõ câu hỏi có nhiều kiến ​​trúc hơn về mã thực tế của LMAX Disruptor.

Cập nhật với các chi tiết

dữ liệu là một lĩnh vực phức tạp, với nhiều thực thể (> 100k) của nhiều loại khác nhau (~ 20) liên kết giữa chúng trong một cấu trúc cây với nhiều bộ sưu tập khác nhau.

Truy vấn thường liên quan đến việc vượt qua hàng nghìn thực thể để tìm dữ liệu chính xác. Cập nhật thường xuyên nhưng khá hạn chế như 10 thực thể tại thời điểm, vì vậy trong toàn bộ dữ liệu không thay đổi nhiều (như 20% cho giờ).

Tôi đã thực hiện một số bài kiểm tra sơ bộ và nó xuất hiện những ưu điểm về tốc độ truy vấn mô hình song song vượt quá thời gian trễ khóa ghi thường xuyên.

+0

Xin chào Uberto - Bạn có thể thêm một số chi tiết không. Bạn đang chạy loại truy vấn nào? Và cập nhật các thực thể đang xảy ra trên cùng một vài thực thể hoặc trên nhiều thực thể khác nhau? Các thực thể được liên kết với nhau hay chủ yếu là độc lập và chúng có liên quan như thế nào? – jasonk

+0

Về câu hỏi 2: precendance của đọc qua viết, Lmax tự nhiên là thích hợp cho tìm nguồn cung ứng sự kiện, trong đó nói rằng bạn giữ các sự kiện không phải là những mô hình, mô hình hiện tại của bạn (hoặc người được tối ưu hóa hơn là siêu nhanh về hoạt động đọc) vẫn sẽ có mặt ở đó nhưng bạn không bao giờ thay đổi mà thậm chí đã xảy ra khi nào, nếu bạn có một hoạt động đọc trước khi ghi, bạn nên xử lý nó theo thứ tự bạn nhận được nó, để có tình trạng tương tự reproducable nếu bạn phát lại chuỗi sự kiện ... Vì vậy, trong trường hợp này tôi ưu tiên này là sai ở đây, bạn làm điều đó khi hai luồng viết trong bộ sưu tập có lẽ ... – vach

Trả lời

2

"yêu cầu viết lý tưởng sẽ được ưu tiên hơn so với yêu cầu đọc".

Tại sao? Hầu hết các ổ khóa nhanh như C# ReaderWriterLockSlim làm ngược lại .. Một viết cần chặn tất cả các lần đọc để tránh đọc một phần. Vì vậy, khóa như vậy cho phép nhiều đồng thời đọc hy vọng mọi thứ có được "khá" và sau đó làm việc viết .. (Viết không chạy ở số của nó trong hàng đợi nhưng rất có khả năng đọc nhiều của nó mà đến sau khi nó được xử lý trước khi nó khóa) ..

Ưu tiên viết là cách tốt để tiêu diệt đồng thời ..

Có phải là tùy chọn đồng thời cuối cùng/CQRS không?

+0

giả định dòng chảy của truy vấn đọc được ít nhiều liên tục, không có lợi ích trong việc trì hoãn ghi. Cập nhật mô hình trước khi đọc có một số lợi thế kinh doanh. – Uberto

+0

Có - khóa lý do làm điều đó là họ hy vọng sự bùng nổ đọc chết xuống mà nó thường làm, dòng chảy liên tục đến một thực thể duy nhất là khá hiếm (nó có thể là bạn có một khóa bảng mà không phải là một ý tưởng tốt cho hiệu suất cao), nếu dòng chảy là contious hơn bạn có tắc nghẽn lớn vào thời điểm này và nên nhìn vào những thứ khác như phục vụ đọc bản sao/spinlocks, vv Chúng tôi đang nói mili đến 1/10 của một giây nào đó quan trọng mà nhiều cho các doanh nghiệp, hầu hết các doanh nghiệp thậm chí sống với các vấn đề viết một phần khi một thực thể từ một lớp ORM được sửa đổi và phục vụ cùng một lúc. – user1496062

+0

Cách dễ nhất để làm điều đó có lẽ chỉ có một hàng đợi lệnh bộ nhớ và cứ mỗi 1-10 ms đặt chúng vào bộ đệm vòng với tất cả các ghi đầu tiên. Disruptors không nhiều đến nhiều (tôi chưa bao giờ thấy ai sử dụng chúng như vậy nên id muốn xem điểm chuẩn) ..đó là họ đọc từ nhiều bộ đệm vòng, mỗi người tiêu dùng (miền) đọc từ một bộ đệm vòng .. mặc dù bạn có thể có nhiều tên miền đọc từ một bộ đệm đơn – user1496062

2

Lmax có thể thích hợp ..

Những người Lmax đầu tiên thực hiện truyền thống, sau đó họ thực hiện các diễn viên (với hàng đợi) và thấy diễn viên dành hầu hết thời gian trong hàng đợi. Sau đó, họ đã đi đến kiến ​​trúc ren duy nhất .. Bây giờ các disruptor không phải là chìa khóa để kiến ​​trúc chính là một BL đơn luồng. Với 1 người viết (một chủ đề) và các đối tượng nhỏ, bạn sẽ nhận được một bộ nhớ cache cao và không có tranh chấp. Để làm điều này họ phải di chuyển tất cả các mã chạy dài ra khỏi lớp kinh doanh (bao gồm IO). Bây giờ để làm điều này họ sử dụng họ sử dụng các disruptor về cơ bản của nó chỉ là một bộ đệm vòng với một nhà văn duy nhất như đã được sử dụng trong mã trình điều khiển thiết bị trong một thời gian nhưng ở một quy mô tin nhắn rất lớn.

Trước tiên tôi có một sự không đồng ý với điều này, LMAX là hệ thống diễn viên .. Bạn có 1 diễn viên cho tất cả BL (và các gián đoạn kết nối các diễn viên khác) ..Họ có thể cải thiện hệ thống diễn viên có ý nghĩa thay vì nhảy tới 1 diễn viên cho BL, cụ thể là

  1. Không có nhiều dịch vụ/diễn viên, cố gắng sử dụng các thành phần thường dùng trong một dịch vụ. (điều này cũng xuất hiện nhiều lần trong các hệ thống SOA/phân phối)
  2. Khi giao tiếp giữa các tác nhân sử dụng các hàng đợi điểm đến điểm không nhiều đến 1. (giống như tất cả các dịch vụ xe buýt!)
  3. Khi bạn có điểm đến điểm đảm bảo đuôi là con trỏ đến vùng bộ nhớ riêng biệt. Với 2 và 3 bạn có thể sử dụng hàng đợi không khóa và hàng đợi/chủ đề chỉ có 1 người viết (và bạn thậm chí có thể sử dụng không phải thời gian 256 nhưng bit YMM ghi vào hàng đợi). Tuy nhiên, hệ thống hiện có nhiều luồng hơn (và nếu bạn đã thực hiện 1 chính xác một lượng thông điệp tương đối nhỏ giữa các tác nhân). Các hàng đợi tương tự như các disruptors và có thể xử lý hàng loạt nhiều mục và có thể sử dụng kiểu đệm vòng.

Với những diễn viên bạn có một hệ thống nhiều mô-đun (và do đó chính-bảng) (và hệ thống có thể khởi động nhiều diễn viên để xử lý hàng đợi - lưu ý 1 nhà văn!)

lại trường hợp của bạn tôi nghĩ rằng 20 % các thay đổi trong một giờ là rất lớn ... Các truy vấn luôn có trong các đối tượng bộ nhớ không? Bạn có trong bảng băm bộ nhớ/chỉ mục? Bạn có thể sử dụng các bộ sưu tập chỉ đọc không? Liệu nó có quan trọng nếu dữ liệu của bạn cũ như Ebay sử dụng 1 giờ làm mới trên bộ sưu tập các vật phẩm của nó để bản thân bộ sưu tập vật phẩm là tĩnh. Với một bộ sưu tập tĩnh và tóm tắt các mục tĩnh, chúng có một chỉ mục tĩnh và bạn có thể tìm kiếm và tìm các mục nhanh và tất cả trong bộ nhớ. Mỗi giờ nó được xây dựng lại và khi hoàn thành (nó có thể mất vài phút để xây dựng lại) hệ thống chuyển sang dữ liệu mới. Lưu ý rằng bản thân các mục không tĩnh.

trong trường hợp của bạn với một miền khổng lồ thread duy nhất có thể có được một hit Cache lowish đồi khế, đồi khác với Lmax người có một miền nhỏ hơn cho mỗi tin nhắn để vượt qua ..

Một đại lý dựa trên hệ thống có thể đặt cược tốt nhất là vì một nhóm các thực thể có thể được nhóm lại và do đó có một bộ nhớ cache cao hit. Nhưng tôi cần biết nhiều hơn. ví dụ như di chuyển kiểm tra tính hợp lệ, kiểm toán, ghi nhật ký vv có lẽ là một kế hoạch tốt. Ít mã = ​​đối tượng nhỏ hơn = hit cache cao hơn và đối tượng LMAX nhỏ.

Hy vọng sự kết xuất nhanh này sẽ giúp ích cho bạn nhưng khó khăn chỉ trong nháy mắt.

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