Home » None » Bài toán tối ưu performance và memory cùng với Akka (Phần II)

Bài toán tối ưu performance và memory cùng với Akka (Phần II)

Trong phần 1 đã đề cập đến Akka Actor và cách sử dụng chúng trong bài toán cụ thể. Cũng như nhắc đến những ưu điểm và nhược điểm trong việc xử lý concurrency và parallelism.

Đến với phần 2 chúng ta sẽ giải quyết bài toán “tắc nghẽn cổ chai” gặp phải khi sử dụng Akka Actor trong bài toán Batch processing

Problem

Nhắc lại một chút từ phần 1, chúng ta có



 

Khi sử dụng Akka Actor chúng ta gặp phải vấn đề “tắc nghẽn cổ chai”

Solution

Cốt lõi để xử lý hiện tượng “tắc nghẽn cổ chai” là

Producer đẩy số lượng công việc lớn hơn số công việc consumer có thể xử lý



Ở siêu thị nếu mỗi nhân viên bán hàng chỉ xử lý được 10 khách/phút thì việc 20 khách vào 1 hàng không những không làm tăng tốc độ được thanh toán mà còn gây “rảnh rỗi” không cần thiết ở những hàng chờ khác.

Lý do là khách hàng(Producer) không biết tốc độ bán hàng của nhân viên(consumer) là bao nhiêu? Vậy nếu như ở mỗi line bán hàng, thông báo :


  • Come In: nếu số lượng khách hàng (rate of producer) < tốc độ xử lý của nhân viên bán hàng(rate of consumer)
  • Full: nếu số lượng khách hàng (rate of producer) >tốc độ xử lý của nhân viên bán hàng(rate of consumer)

Và đây chính là nguyên tắc xử lý của “Work pulling pattern”

Tuy nhiên từ vấn đề này khiến mình nhìn ra nhiều vấn đề khi sử dụng Akka Actor trong bài toán Batch processing:


  • Actors do not compose well: Việc gửi message từ Actor A đến Actor B sẽ được hard-code trong Actor A, điều này làm giảm tính linh hoạt khi thiết kế hệ thống và sử dụng lại Actor
  • Actors thường không minh bạch: ngay trong bài toán của mình, khi 1 người mới nhìn vào 1 đống những Actors, họ sẽ không thể hiểu/tưởng tượng ra một cách tổng quát những Actors nào đang giao tiếp với Actors nào. Chỉ có cách đọc từng actor một, việc này gây lãnh phí thời gian 1 cách không cần thiết.
  • Actors cần tối ưu hóa rất nhiều: how to tối ưu hóa 😥

Akka Streams — Reactive Streams way

Back-Pressure —Heart of Reactive Streams

Cốt lõi của Back-pressure chính là xử lý problem của chúng ta bên trên


Producer đẩy số lượng công việc lớn hơn số công việc consumer có thể xử lý


Consumer sẽ yêu cầu số lượng mình mong muốn cho Producer, và producer sẽ đáp ứng con số đấy. Con số này sẽ phụ thuộc hoàn toàn vào consumer ở những thời điểm khác nhau.

Điều ngày ngược hoẳn hoàn toàn với cách với Actor ở phần I




Account process xử lý rất nhanh, nó đổ messages liên tục vào Mailbox của Campaign Actor, tượng tự với Campaign actor đổ messages vào mailbox của Keyword actor. Mà không cần quan tâm process sau mình đang xử lý ở tốc độ nào. Với việc Mailbox tăng nhanh, mà actor ở process đấy có hạn(đang busy xử lý) => memory dùng cho Mailboxs tăng cao một cách không cần thiết.

Let The Code Speak For Itself

Let the picture make you understand easier



Công việc của bạn là xây dựng các Source, Flow, Sink sau đó sắp xếp chúng với nhau như ghép lego vậy!

In-depth

Đây là kết quả khi chạy đoạn code trên



Cùng dispatcher-2 => không parallelism?


Bạn để ý data sẽ được print theo chiều dọc, theo chiều của vòng tròn màu đỏ, sau đó chuyển sang hàng dọc tiếp theo => Synchronous?

Vậy có vẻ như đoạn code trên với Akka Streams chúng ta không đạt được điều ta mong muốn như khi dùng với Akka Actors.

Điều chúng ta thiếu ở đây là làm cho Flow asynchronous, và akka streams có cung cấp cho chúng ta:



Và đây là kết quả sao đó




Data đã được print một cách asynchronous theo hàng ngang như ở hình trên.

Và mỗi Flow cũng được dispatcher đặt ở các thread khác nhau!


What next?

Xét cho cùng Akka Streams chỉ là một tool/framework để xử lý các trường hợp phù hợp

Giữa Akka Actor — Akka Streams đều có những điểm mạnh/điểm yếu phù hợp với từng trường hợp:


  • Akka Actor: mang lại cho chúng ta distribution và location transparency
  • Akka Streams: mang lại cho chúng ta Back-Pressure và rất nhiều blueprint

Phía trên mới chỉ là cách sử dụng Akka streams một cách cơ bản, trong phần tiếp theo, mình sẽ trình bày thêm về cách sử dụng, Akka Streams Graph, cách limit rate, cách parallelism trong 1 Flow

Tham khảo

Understanding Akka Streams, Back Pressure, and Asynchronous Architectures

Akka Streams docs


Tagged width:,