Xem bài viết gốc: https://martinfowler.com/articles/lmax.html

Đối với một ứng dụng phần mềm, việc scale ứng dụng để vừa tăng tốc độ thực thi vừa đảm bảo tính ổn định để đáp ứng số lượng lớn truy cập lên đến hàng nghìn request/s là điều không hề dễ dàng, nhất là với những công ty có Business Logic ngày càng phức tạp.

Trong những năm gần đây, chúng ta thường nghe thấy những câu nói như: "the free lunch is over" - để nói về việc tăng trưởng về khả năng xử lý của CPU đang dần chậm lại và bắt đầu chạm ngưỡng giới hạn. Vì vậy, để ứng dụng có thể tăng tốc độ xử lý, concurrent cũng là một giải pháp mà các engineer hướng tới. Nhưng trong thực tế, điều này thực sự không dễ dàng để triển khai hoặc test. Ví dụ điển hình là hai model: Actors, Software Transactional Memory. Hai Model này sinh ra để giúp các engineer làm việc dễ dàng hơn với concurrent nhưng trong thực tế lại dẫn đến nhiều bug và các vấn đề phức tạp khác. LMAX - một platform về tài chính hàng ngày phải xử lý hàng triệu giao dịch và yêu cầu về latency phải cực thấp để không ảnh hưởng đến trải nghiệm người dùng đã có chia sẻ rất thú vị về kiến trúc của họ ở QCon Conf London.

Về mặt tổng quan, hệ thống của LMAX bao gồm 1 số thành phần chính:

  1. Business Logic Processor: là nơi xử lý tất cả các logic về business của ứng dụng, và điều đặc biệt ở đây là team LMAX chỉ sử dụng Java - dùng single-threaded là chủ đạo cho các cả các action liên quan đến input/output event. Một số các thuộc tính trong Business Logic:
  • Keeping it all in memory: Business Logic là nơi xử lý tất cả các input message, xử lý logic theo business và đưa ra một output event. Trong quá trình xử lý này, tất cả đều được lưu in-memory không sử dụng bất kì database nào hay một persistent store nào khác. Việc này mang lại 2 ưu điểm: Việc không sử dụng database làm tăng tốc độ xử lý, không có bất cứ transaction nào được thực thi và tất cả mọi process trong đó đều được xử lý tuần tự, và ưu điểm thứ 2 là không có bất kì object/relational mapping nào đến database, việc này sẽ giảm thiểu tính phức tạp đi rất nhiều. Nhưng không phải hệ thống lúc nào cũng hoạt động ổn định và điều gì xảy ra nếu như hệ thống gặp sự cố?. Và Event Sourcing là giải pháp để giải quyết vấn đề này, nơi mà toàn bộ các state của Business Logic được lưu trữ dựa trên các input message, và khi gặp sự cố, bạn hoàn toàn có thể chạy lại event đó, nhưng trong thực tế, việc này thường tốn mất khá nhiều thời gian, việc backup các state của Business Logic vào Snapshot và replicate Event Source thành nhiều node là việc nên làm để tăng tốc độ xử lý, và tránh việc downtime.
  • Tuning performance: Từ những ưu điểm về việc xử lý Business Logic ở trên, việc có thể đạt được 10 TPS đến 100 TPS nếu chú trọng việc optimizing là điều hoàn toàn có thể đạt được. Và để tăng performance, việc viết tests first cũng là một giải pháp rất hữu ích
  • Programming Model: Áp dụng LMAX architecture cũng có một số nhược điểm trong business logic như: khi hệ thống của bạn phải gọi đến 1 dịch vụ của bên thứ 3 để thực hiện thanh toán, và việc đợi response trả về quá lâu sẽ dẫn đến toàn bộ order đó bị hủy. Để giải quyết vấn đề này, khi đó, việc đẩy ra một output event và đợi một input event khác để tiếp tục gọi lại để xử lý là một giải pháp không quá tồi. Ở trong các model truyền thống, hầu hết các database transaction, session đều hỗ trợ rất tốt việc xử lý lỗi khi có xung đột xảy ra, nhưng đối với LMAX architecture, mọi thứ đều được lưu in-memory, chính vì vậy, khi có lỗi xảy ra, hệ thống không có cơ chế tự động rollback. Do đó, phải đảm bảo tuyệt đối input event trước khi lưu state.
  1. Input and Output Disruptors: thông thường, Business Logic chỉ được xử lý với single thread, Event Sourcing sẽ lưu tất cả các event đó xuống disk và đồng thời replicate Input và Output dựa trên các Business Model, nhưng việc này cũng không cải thiện quá nhiều về mặt Performance, chính vì thế,các Engineer ở LMAX đã phát triển một component gọi là Disruptor. Nó cho phép một Producer có thể gửi message tới nhiều Consumer và không giới hạn số Producer. Ưu điểm của thiết kế này là các Consumer có thể xử lý kịp thời khi có lỗi xảy ra trong hệ thống. Trong Disruptor có 3 khái niệm chính là: journaler, replicator, unmarshaler. Các thành phần này hoạt động đồng thời với nhau. Journaler sẽ lưu tất cả các event không đổi dựa trên các slots trống, replicator là việc scale ra thành nhiều node để tránh việc downtime, các node này đồng bộ với nhau, giao tiếp với nhau thông qua địa chỉ IP, và chỉ có duy nhất 1 node master. Khi node master chết, các node còn lại sẽ tự phân bổ một node để thành node master. Unmarshaler là việc thay đổi data để xử lý trong Business Logic và ở tại một thời điểm, chỉ có duy nhất một consumer được chỉnh sửa data đó.