thảo luận Cách áp dụng LMAX Disruptor với spring

  • Người tạo chủ đề Người tạo chủ đề Mắm Cá Linh
  • Ngày bắt đầu Ngày bắt đầu

Mắm Cá Linh

Senior Member
P/s title bị lỗi.

Cách áp dụng LMAX Disruptor với spring​


Có bác nào Apply cái này cho việc thao tác với DB chưa. Không biết có khả thi hay không. Có apply được với API hay không.
 
Thằng này liên quan gì tới DB đâu my friend? Còn áp dụng thì đầy. Ví dụ cần sync dữ liệu từ A sang B hoặc pass data qua các pipeline với latency thấp đến rất thấp. Một vài use case đấy.

via theNEXTvoz for iPhone
 
Sửa lần cuối:
Thằng này liên quan gì tới DB đâu my friend? Còn áp dụng thì đầy. Ví dụ càn sync dữ liệu từ A sang B hoặc pass data qua các pipeline với latency thấp đến rất thấp. Một vài use case đấy.

via theNEXTvoz for iPhone
ví dụ mô hình gồm controller , service , repository thì dùng cái này để chuyển data giữa 3 class trên có khả thi không. tốc độ có cải thiện không
 
ví dụ mô hình gồm controller , service , repository thì dùng cái này để chuyển data giữa 3 class trên có khả thi không. tốc độ có cải thiện không
Không. Và cũng không ai làm thế cả, nếu my friend muốn thí nghiệm thì cứ tầng controller tương cho nó cái @RequestBoby InputStream stream xong nhét cái stream ấy vào RingBuffer. Ở đầu service thì cứ listen có RingBuffer trên rồi bóc dữ liệu ra xử lý. Nhưng, chả ai làm thế, vì:
  • Request Body quá nhỏ (Nếu dùng RESTful) không đáng để dùng, trừ khi my fiend upload cái file lớn thì hợp lý hơn.
  • Sẽ phải tạo N RingBuffer tương ứng với N service method, trong khi gọi thẳng method ở service nhanh hơn nhiều.
  • Depend: Computation ở từng step có tạ tốn không? Chứ request lên xong query rồi trả về thì ...

Còn từ service -> repository thì không liên quan gì luôn. Cái repository nó không chơi đc dạng ByteArray và nó là edge of operation boundary rồi.
 
Sửa lần cuối:
Thằng này liên quan gì tới DB đâu my friend? Còn áp dụng thì đầy. Ví dụ cần sync dữ liệu từ A sang B hoặc pass data qua các pipeline với latency thấp đến rất thấp. Một vài use case đấy.

via theNEXTvoz for iPhone
Mai fen có thể nói rõ hơn về use case trên đc k. Trc đây t cũng tìm hiểu các case sử dụng cái này mà ít người biết quá, có vẻ như là sử dụng để giao tiếp giữa các thread. T có biết bọn Axon Framework dùng cái này mà đọc code ko hiểu lắm
 
Mai fen có thể nói rõ hơn về use case trên đc k. Trc đây t cũng tìm hiểu các case sử dụng cái này mà ít người biết quá, có vẻ như là sử dụng để giao tiếp giữa các thread. T có biết bọn Axon Framework dùng cái này mà đọc code ko hiểu lắm
k bạn, để latency thấp, cái này bá cháy lắm. Nhưng xem bạn config ntn. Biết fortna với tiki đang xài :)
 
k bạn, để latency thấp, cái này bá cháy lắm. Nhưng xem bạn config ntn. Biết fortna với tiki đang xài :)
Tất nhiên là để latency thấp r mai fen nhưng ý t là nó dùng trong trường hợp các service tương tác vs nhau hay các thread tương tác với nhau ấy
 
Tất nhiên là để latency thấp r mai fen nhưng ý t là nó dùng trong trường hợp các service tương tác vs nhau hay các thread tương tác với nhau ấy
em có xem 1 video thì thấy tiki cũng dùng vào đầu API. em nghĩ cách này mình tận dụng chia nhỏ công việc thành các phần có thể chạy độc lập. dùng disruptor để chuyển data giữa các thành phần để đạt được hiệu suất cao.

ví dụ như câu hỏi bên trên em nghĩ là có thể chia phần insert DB thành một thành phần riêng. phần xử lý riêng. và phần tiếp nhận controller riêng. như vậy ngay đầu controller sẽ tiếp nhận cực nhanh. và cơ chế response api phải là bất đồng bộ

tham khảo:
 
em có xem 1 video thì thấy tiki cũng dùng vào đầu API. em nghĩ cách này mình tận dụng chia nhỏ công việc thành các phần có thể chạy độc lập. dùng disruptor để chuyển data giữa các thành phần để đạt được hiệu suất cao.

ví dụ như câu hỏi bên trên em nghĩ là có thể chia phần insert DB thành một thành phần riêng. phần xử lý riêng. và phần tiếp nhận controller riêng. như vậy ngay đầu controller sẽ tiếp nhận cực nhanh. và cơ chế response api phải là bất đồng bộ

tham khảo:
thread thôi vì nó là data structure mà,
Tuy nhiên, bạn đã đọc qua False Sharing của CPU chưa. Nó đảm bảo false sharing giữa các processor của CPU nhé. Quan trọng hơn, nó giải quyết 1 vấn đề CAS gặp phải (quên issue)
Bạn xem thêm video này :
Topic hay, tuy nhiên lâu rồi mình k động vào thằng này nên không nhớ nhiều
 
em có xem 1 video thì thấy tiki cũng dùng vào đầu API. em nghĩ cách này mình tận dụng chia nhỏ công việc thành các phần có thể chạy độc lập. dùng disruptor để chuyển data giữa các thành phần để đạt được hiệu suất cao.

ví dụ như câu hỏi bên trên em nghĩ là có thể chia phần insert DB thành một thành phần riêng. phần xử lý riêng. và phần tiếp nhận controller riêng. như vậy ngay đầu controller sẽ tiếp nhận cực nhanh. và cơ chế response api phải là bất đồng bộ

tham khảo:
Chỗ insert DB không dùng được do lúc này con JPA Provider không có khả năng deserialize dữ liệu. Mà cái này cũng không làm cho việc insert DB nhanh lên được. Nếu muốn bulk insert nhanh thì bật cái reWriteBatchedInserts lên (Nó là 1 yếu tố để giúp cho việc bulk insert nhanh hơn).

như vậy ngay đầu controller sẽ tiếp nhận cực nhanh
Sai. Request -> Dispatcher -> Controller. Không có chỗ phù hợp để sử dụng RingBuffer cả. Và flow trên nó đã vốn nhanh rồi. Nhanh trong ngữ cảnh sử dụng RingBuffer là pass dữ kiệu qua lại các pipeline nhanh kia kìa.

Ví dụ 1 use case nhé, tôi cần sync đơn hàng của Shopify để từ đó place orders ở các trang khác (Esty, Ebay, Amazon ...), vì tôi không muốn bị thằng khác tranh mất nên tôi muốn tốc độ sử lý từ khi pull orders từ Shopify cho đến khi place orders phải là nhanh nhất. Bỏ qua vấn đề latency của external dependencies, thì tôi sẽ có các stage:

(1) Pull order -> RawOrderQueue.
(2) RawOrderQueue -> OrderValidator -> CleanOrderQueue
(3) CleanOrderQueue -> OrderDispatcher -> PlacedOrderQueue
(4) PlacedOrderQueue -> Notification

RawOrderQueue: Là 1 cái RingBuffer chưa data từ Shopify.

OrderValidator: 1 Thread Group đọc RawOrderQueue để xử lý theo logic đc định sẵn (Chỗ này là stateful do đó cần inter-thread communication), thằng nào pass thi ghi xuống CleanOrderQueue.

OrderDispatcher: 1 Thread Group khác, đọc CleanOrderQueue và đẩy order đến các trang đích cần place order và ghi xuống PlacedOrderQueue.

Notification thì không cần nhanh, đọc PlacedOrderQueue rồi bắn email thôi.

Right tools for right jobs.

@gaconkute , @martin98 tôi trả lời my friend ở trên luôn nhé.
 
Chỗ insert DB không dùng được do lúc này con JPA Provider không có khả năng deserialize dữ liệu. Mà cái này cũng không làm cho việc insert DB nhanh lên được. Nếu muốn bulk insert nhanh thì bật cái reWriteBatchedInserts lên (Nó là 1 yếu tố để giúp cho việc bulk insert nhanh hơn).


Sai. Request -> Dispatcher -> Controller. Không có chỗ phù hợp để sử dụng RingBuffer cả. Và flow trên nó đã vốn nhanh rồi. Nhanh trong ngữ cảnh sử dụng RingBuffer là pass dữ kiệu qua lại các pipeline nhanh kia kìa.

Ví dụ 1 use case nhé, tôi cần sync đơn hàng của Shopify để từ đó place orders ở các trang khác (Esty, Ebay, Amazon ...), vì tôi không muốn bị thằng khác tranh mất nên tôi muốn tốc độ sử lý từ khi pull orders từ Shopify cho đến khi place orders phải là nhanh nhất. Bỏ qua vấn đề latency của external dependencies, thì tôi sẽ có các stage:

(1) Pull order -> RawOrderQueue.
(2) RawOrderQueue -> OrderValidator -> CleanOrderQueue
(3) CleanOrderQueue -> OrderDispatcher -> PlacedOrderQueue
(4) PlacedOrderQueue -> Notification

RawOrderQueue: Là 1 cái RingBuffer chưa data từ Shopify.

OrderValidator: 1 Thread Group đọc RawOrderQueue để xử lý theo logic đc định sẵn (Chỗ này là stateful do đó cần inter-thread communication), thằng nào pass thi ghi xuống CleanOrderQueue.

OrderDispatcher: 1 Thread Group khác, đọc CleanOrderQueue và đẩy order đến các trang đích cần place order và ghi xuống PlacedOrderQueue.

Notification thì không cần nhanh, đọc PlacedOrderQueue rồi bắn email thôi.

Right tools for right jobs.

@gaconkute , @martin98 tôi trả lời my friend ở trên luôn nhé.
có source code liên quan k đại ka, kiến thức đc tiếp thu mặc dù lâu k động thằng này. Nhưng nhue em kể, có 1 vấn đề : Barrier, ví dụ đại ka cấu hình 1048 slot ở Ring buffer thì phải nhận đủ 1048 requests vào cho full buffer rồi mới chạy :(
 
có source code liên quan k đại ka, kiến thức đc tiếp thu mặc dù lâu k động thằng này. Nhưng nhue em kể, có 1 vấn đề : Barrier, ví dụ đại ka cấu hình 1048 slot ở Ring buffer thì phải nhận đủ 1048 requests vào cho full buffer rồi mới chạy :(
À, tôi chạy cron. Nên cái buffer allocate trước khi pull chứ không fixed. Nhưng đâu phải đủ buffer mới chạy? Tuỳ lúc publish chứ.

via theNEXTvoz for iPhone
 
1 đặc điểm nữa của Disruptor là đảm bảo thứ tự xử lý message trên cùng 1 pipeline, thì sẽ không sợ race condition như lập trình đa luồng và vẫn đảm bảo hiệu năng.
Tiki hình như dùng để kiểm soát số dư trong các chương trình khuyến mại kiểu big sale, để số lượng KH đặt đơn thành công không vượt quá số lượng setup khuyến mại.
 
À, tôi chạy cron. Nên cái buffer allocate trước khi pull chứ không fixed. Nhưng đâu phải đủ buffer mới chạy? Tuỳ lúc publish chứ.

via theNEXTvoz for iPhone
là trigger à bác, ví dụ request này vào buffer -> chạy luôn hay như nào nhỉ, bác cụ thể hoá em với
1 đặc điểm nữa của Disruptor là đảm bảo thứ tự xử lý message trên cùng 1 pipeline, thì sẽ không sợ race condition như lập trình đa luồng và vẫn đảm bảo hiệu năng.
Tiki hình như dùng để kiểm soát số dư trong các chương trình khuyến mại kiểu big sale, để số lượng KH đặt đơn thành công không vượt quá số lượng setup khuyến mại.
đúng rồi, nó solve các issue của đa luồng : Lock, race condition, deadlock... vì nó chỉ có 1 luồng
 
Chỗ insert DB không dùng được do lúc này con JPA Provider không có khả năng deserialize dữ liệu. Mà cái này cũng không làm cho việc insert DB nhanh lên được. Nếu muốn bulk insert nhanh thì bật cái reWriteBatchedInserts lên (Nó là 1 yếu tố để giúp cho việc bulk insert nhanh hơn).


Sai. Request -> Dispatcher -> Controller. Không có chỗ phù hợp để sử dụng RingBuffer cả. Và flow trên nó đã vốn nhanh rồi. Nhanh trong ngữ cảnh sử dụng RingBuffer là pass dữ kiệu qua lại các pipeline nhanh kia kìa.

Ví dụ 1 use case nhé, tôi cần sync đơn hàng của Shopify để từ đó place orders ở các trang khác (Esty, Ebay, Amazon ...), vì tôi không muốn bị thằng khác tranh mất nên tôi muốn tốc độ sử lý từ khi pull orders từ Shopify cho đến khi place orders phải là nhanh nhất. Bỏ qua vấn đề latency của external dependencies, thì tôi sẽ có các stage:

(1) Pull order -> RawOrderQueue.
(2) RawOrderQueue -> OrderValidator -> CleanOrderQueue
(3) CleanOrderQueue -> OrderDispatcher -> PlacedOrderQueue
(4) PlacedOrderQueue -> Notification

RawOrderQueue: Là 1 cái RingBuffer chưa data từ Shopify.

OrderValidator: 1 Thread Group đọc RawOrderQueue để xử lý theo logic đc định sẵn (Chỗ này là stateful do đó cần inter-thread communication), thằng nào pass thi ghi xuống CleanOrderQueue.

OrderDispatcher: 1 Thread Group khác, đọc CleanOrderQueue và đẩy order đến các trang đích cần place order và ghi xuống PlacedOrderQueue.

Notification thì không cần nhanh, đọc PlacedOrderQueue rồi bắn email thôi.

Right tools for right jobs.

@gaconkute , @martin98 tôi trả lời my friend ở trên luôn nhé.
Tks bác :smile:
Trc đây em từng vọc cái open source này https://github.com/exchange-core/exchange-core và biết đc mấy thư viện như Lmax Disruptor vs Chronicle Software đc dùng cho các hệ thống low latency. Đây là 1 matching engine (công cụ khớp lệnh) có thể sử dụng cho các sàn crypto, theo như e tìm hiểu đc thì nó gồm các bước:

Receive event -> EventQueue -> Validate Order -> Matching Engine -> Other Business Logic

(1) Receive event -> EventQueue -> Validate Order : Đầu tiên nó sẽ nhận các event từ bên ngoài vào rồi đặt vào trong EventQueue - chính là ringBuffer của Lmax Disruptor. Validate Order là 1 thread sẽ lấy các event từ ringBuffer ra để xử lý, đảm bảo các order là hợp lệ.
(2) Validate Order -> Matching Engine: Sau khi các order được valid là hợp lệ, chúng sẽ đc đẩy đến Matching Engine - là 1 thread chính chuyên thực hiện công việc khớp lệnh và tổng hợp tất cả thành 1 sổ lệnh (orderbook)
(3) Matching Engine -> Other Business Logic: Sau khi lệnh được khớp thì sẽ được chuyển tới Other Business logic - cũng là 1 thread khác đảm nhiệm các nghiệp vụ có liên quan như cập nhật số dư khách hàng, ghi log...

Như vậy thì Lmax Disruptor giúp triển khai được 1 pipeline có 3 thread riêng biệt Validate Order, Matching Engine, Other Business Logic chạy song song nhưng có thứ tự, ngoài ra thì ringBuffer giúp cho việc đọc ghi giữa "Receive Event" và "Validate Order" không bị block lẫn nhau giúp giảm latency. Cách triển khai này khá giống use case bác đề cập đến ở trên :smile:

em có xem 1 video thì thấy tiki cũng dùng vào đầu API. em nghĩ cách này mình tận dụng chia nhỏ công việc thành các phần có thể chạy độc lập. dùng disruptor để chuyển data giữa các thành phần để đạt được hiệu suất cao.
Trong video mà mình xem thì bên Tiki họ không áp dụng Lmax Disruptor ở đầu vào API đâu mà sử dụng trong quá trình giao tiếp giữa các thread giống như mình và bác @Hellscream đề cập ở trên cơ :shame: Link ở đây
Bắt đầu từ phút 29 nhé. Đại khái vấn đề của Tiki là thế này, họ có 1 cái luồng như sau:

Kafka -> Pull event -> Unmarshall -> Business Logic

(1) Kafka -> Pull event : Họ dùng 1 thread để pull event từ Kafka về
(2) Pull event -> Unmarshall: Sau khi pull event từ Kafka, họ cần 1 bước xử lý các side effect, tức là gọi đến DB hoặc các service khác để lấy data tương ứng. Vì sử dụng nhiều side effect nên họ cần phải tách ra thành nhiều thread, tức là đoạn này sử dụng Multhreading và các thread phải ko đc block lẫn nhau.
(3) Unmarshall -> Business Logic: Sau khi đã xử lý xong các bước side effect ở Unmarshal thì tất cả data sẽ được đẩy vào 1 thread duy nhất để xử lý Business logic

Tóm lại là chúng ta có 1 pipeline gồm 3 statge chính: SIngle Thread -> Multithread -> Single Thead

Cách xử lý trên có 1 vấn đề cần là không thể đảm bảo được thứ tự data ở bước Business Logic cuối cùng do trước đó là 1 bước sử dụng Multithreading (Unmarshall). Đấy là còn chưa kể đến câu chuyện là, thông thường các Thread sẽ giao tiếp với nhau bằng LinkedBlockingQueue chỉ cho phép hoặc đọc, hoặc ghi tại 1 thời điểm, dẫn đến tăng độ trễ (latency) :boss:

Về vấn đề thứ 2, liên quan đến giao tiếp giữa các thread thì bên Tiki họ sử dụng ringBuffer trong Lmax Disruptor cho phép nhiều thread đọc, ghi tại cùng 1 thời điểm. Còn vấn đề thứ nhất liên quan đến thứ tự của data thì họ cũng sử dụng Lmax Disruptor, tuy nhiên mình không hiểu cách xử lý của họ lắm vì khi trình bày đoạn này thì họ bê nguyên cái sơ đồ của Lmax Disruptor ở trên mạng chứ ko tự tay vẽ lại như lúc đặt vấn đề :confuse: Dựa theo sự hiểu biết của mình khi vọc cái open source exchange-core ở trên thì mình nghĩ vấn đề này có thể giải quyết như sau:

Bước Unmarshall ở trên thay vì sử dụng Multithread chạy cùng 1 lúc thì có thể tách thành nhiều stage có thứ tự, mỗi statge có 1 thread, stage này chạy xong thì mới đến lượt stage sau, ta có thể sử dụng Memory Barrier trong Lmax Disruptor để thực hiện điều này. Ví dụ ở cách tiếp cận ban đầu Unmarshal có 3 thread chạy cùng lúc

Kafka -> Pull event -> Unmarshall (3 thread) -> Business Logic

thì bây giờ nó sẽ trở thành:

Kafka -> Pull event -> Unmarshall 1 -> Unmarshall 2 -> Unmarshall 3 -> Business Logic

Bên tiki nói rằng cách làm này là Single thread, nhưng mình thấy nó không phải là single thread mà là multi thread nhưng chạy theo thứ tự và không block lẫn nhau

Không biết bác @Hellscream đã tìm hiểu cách triển khai của bên tiki chưa, có thể cho e chút ý kiến đc k :smile:
 
Tks bác :smile:
Trc đây em từng vọc cái open source này https://github.com/exchange-core/exchange-core và biết đc mấy thư viện như Lmax Disruptor vs Chronicle Software đc dùng cho các hệ thống low latency. Đây là 1 matching engine (công cụ khớp lệnh) có thể sử dụng cho các sàn crypto, theo như e tìm hiểu đc thì nó gồm các bước:

Receive event -> EventQueue -> Validate Order -> Matching Engine -> Other Business Logic

(1) Receive event -> EventQueue -> Validate Order : Đầu tiên nó sẽ nhận các event từ bên ngoài vào rồi đặt vào trong EventQueue - chính là ringBuffer của Lmax Disruptor. Validate Order là 1 thread sẽ lấy các event từ ringBuffer ra để xử lý, đảm bảo các order là hợp lệ.
(2) Validate Order -> Matching Engine: Sau khi các order được valid là hợp lệ, chúng sẽ đc đẩy đến Matching Engine - là 1 thread chính chuyên thực hiện công việc khớp lệnh và tổng hợp tất cả thành 1 sổ lệnh (orderbook)
(3) Matching Engine -> Other Business Logic: Sau khi lệnh được khớp thì sẽ được chuyển tới Other Business logic - cũng là 1 thread khác đảm nhiệm các nghiệp vụ có liên quan như cập nhật số dư khách hàng, ghi log...

Như vậy thì Lmax Disruptor giúp triển khai được 1 pipeline có 3 thread riêng biệt Validate Order, Matching Engine, Other Business Logic chạy song song nhưng có thứ tự, ngoài ra thì ringBuffer giúp cho việc đọc ghi giữa "Receive Event" và "Validate Order" không bị block lẫn nhau giúp giảm latency. Cách triển khai này khá giống use case bác đề cập đến ở trên :smile:


Trong video mà mình xem thì bên Tiki họ không áp dụng Lmax Disruptor ở đầu vào API đâu mà sử dụng trong quá trình giao tiếp giữa các thread giống như mình và bác @Hellscream đề cập ở trên cơ :shame: Link ở đây
Bắt đầu từ phút 29 nhé. Đại khái vấn đề của Tiki là thế này, họ có 1 cái luồng như sau:

Kafka -> Pull event -> Unmarshall -> Business Logic

(1) Kafka -> Pull event : Họ dùng 1 thread để pull event từ Kafka về
(2) Pull event -> Unmarshall: Sau khi pull event từ Kafka, họ cần 1 bước xử lý các side effect, tức là gọi đến DB hoặc các service khác để lấy data tương ứng. Vì sử dụng nhiều side effect nên họ cần phải tách ra thành nhiều thread, tức là đoạn này sử dụng Multhreading và các thread phải ko đc block lẫn nhau.
(3) Unmarshall -> Business Logic: Sau khi đã xử lý xong các bước side effect ở Unmarshal thì tất cả data sẽ được đẩy vào 1 thread duy nhất để xử lý Business logic

Tóm lại là chúng ta có 1 pipeline gồm 3 statge chính: SIngle Thread -> Multithread -> Single Thead

Cách xử lý trên có 1 vấn đề cần là không thể đảm bảo được thứ tự data ở bước Business Logic cuối cùng do trước đó là 1 bước sử dụng Multithreading (Unmarshall). Đấy là còn chưa kể đến câu chuyện là, thông thường các Thread sẽ giao tiếp với nhau bằng LinkedBlockingQueue chỉ cho phép hoặc đọc, hoặc ghi tại 1 thời điểm, dẫn đến tăng độ trễ (latency) :boss:

Về vấn đề thứ 2, liên quan đến giao tiếp giữa các thread thì bên Tiki họ sử dụng ringBuffer trong Lmax Disruptor cho phép nhiều thread đọc, ghi tại cùng 1 thời điểm. Còn vấn đề thứ nhất liên quan đến thứ tự của data thì họ cũng sử dụng Lmax Disruptor, tuy nhiên mình không hiểu cách xử lý của họ lắm vì khi trình bày đoạn này thì họ bê nguyên cái sơ đồ của Lmax Disruptor ở trên mạng chứ ko tự tay vẽ lại như lúc đặt vấn đề :confuse: Dựa theo sự hiểu biết của mình khi vọc cái open source exchange-core ở trên thì mình nghĩ vấn đề này có thể giải quyết như sau:

Bước Unmarshall ở trên thay vì sử dụng Multithread chạy cùng 1 lúc thì có thể tách thành nhiều stage có thứ tự, mỗi statge có 1 thread, stage này chạy xong thì mới đến lượt stage sau, ta có thể sử dụng Memory Barrier trong Lmax Disruptor để thực hiện điều này. Ví dụ ở cách tiếp cận ban đầu Unmarshal có 3 thread chạy cùng lúc

Kafka -> Pull event -> Unmarshall (3 thread) -> Business Logic

thì bây giờ nó sẽ trở thành:

Kafka -> Pull event -> Unmarshall 1 -> Unmarshall 2 -> Unmarshall 3 -> Business Logic

Bên tiki nói rằng cách làm này là Single thread, nhưng mình thấy nó không phải là single thread mà là multi thread nhưng chạy theo thứ tự và không block lẫn nhau

Không biết bác @Hellscream đã tìm hiểu cách triển khai của bên tiki chưa, có thể cho e chút ý kiến đc k :smile:
Chưa bao giờ để tâm đến Tiki luôn bác ạ. Tôi không ưa đội này cho lắm, gió nhiều, làm ít, và tỏ ra nguy hiểm.

Thêm tý cho các friend là anh nào thích hoặc đang viết FP (functional programming) sẽ rất thích thằng disruptor này vì nó rất hợp để đi cùng nhau do bản chất của FP là pure function + composition.
 
Chỗ insert DB không dùng được do lúc này con JPA Provider không có khả năng deserialize dữ liệu. Mà cái này cũng không làm cho việc insert DB nhanh lên được. Nếu muốn bulk insert nhanh thì bật cái reWriteBatchedInserts lên (Nó là 1 yếu tố để giúp cho việc bulk insert nhanh hơn).


Sai. Request -> Dispatcher -> Controller. Không có chỗ phù hợp để sử dụng RingBuffer cả. Và flow trên nó đã vốn nhanh rồi. Nhanh trong ngữ cảnh sử dụng RingBuffer là pass dữ kiệu qua lại các pipeline nhanh kia kìa.

Ví dụ 1 use case nhé, tôi cần sync đơn hàng của Shopify để từ đó place orders ở các trang khác (Esty, Ebay, Amazon ...), vì tôi không muốn bị thằng khác tranh mất nên tôi muốn tốc độ sử lý từ khi pull orders từ Shopify cho đến khi place orders phải là nhanh nhất. Bỏ qua vấn đề latency của external dependencies, thì tôi sẽ có các stage:

(1) Pull order -> RawOrderQueue.
(2) RawOrderQueue -> OrderValidator -> CleanOrderQueue
(3) CleanOrderQueue -> OrderDispatcher -> PlacedOrderQueue
(4) PlacedOrderQueue -> Notification

RawOrderQueue: Là 1 cái RingBuffer chưa data từ Shopify.

OrderValidator: 1 Thread Group đọc RawOrderQueue để xử lý theo logic đc định sẵn (Chỗ này là stateful do đó cần inter-thread communication), thằng nào pass thi ghi xuống CleanOrderQueue.

OrderDispatcher: 1 Thread Group khác, đọc CleanOrderQueue và đẩy order đến các trang đích cần place order và ghi xuống PlacedOrderQueue.

Notification thì không cần nhanh, đọc PlacedOrderQueue rồi bắn email thôi.

Right tools for right jobs.

@gaconkute , @martin98 tôi trả lời my friend ở trên luôn nhé.

Cho mình hỏi phát, CleanOrderQueue có thể dùng 1 RingBuffer khác không nhỉ? (dùng 2 Disruptor)
 

Thống kê chủ đề

Ngày tạo
Mắm Cá Linh,
Người trả lời cuối
quangtung2912,
Trả lời
37
Lượt xem
5.534
Quay lại
Lên đầu trang