+12

Khám Phá Công Nghệ Bí Mật Giúp Canva Dẫn Đầu Trong Lĩnh Vực Thiết Kế Trực Tuyến

Trong thế giới ngày càng số hóa, nhu cầu về công cụ thiết kế đơn giản nhưng đầy đủ tính năng ngày càng trở nên phổ biến. Canva, một nền tảng thiết kế trực tuyến ra đời vào năm 2013, đã nhanh chóng trở thành giải pháp yêu thích của hàng triệu người dùng trên toàn thế giới.


Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về thiết kế hệ thống nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng System Design Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng System Design Việt Nam: https://www.facebook.com/groups/sydexa

Kênh TikTok: https://www.tiktok.com/@sydexa.com



Một trong những tính năng nổi bật của Canvakhả năng cộng tác thời gian thực, cho phép nhiều người cùng chỉnh sửa một thiết kế đồng thời. Điều này giúp tối ưu hóa quy trình làm việc nhóm, tiết kiệm thời gian và nâng cao hiệu quả.

image.png

Với hơn 135 triệu người dùng hàng tháng, Canva đã chứng minh được sự thành công của mình trong việc cung cấp một giải pháp thiết kế toàn diện và dễ tiếp cận. Nhưng làm thế nào Canva có thể mở rộng hệ thống của mình để hỗ trợ khả năng cộng tác thời gian thực cho số lượng người dùng khổng lồ này? Câu trả lời nằm ở giao thức RSocket.

Tại sao lại là RSocket?

Trong việc thiết kế hệ thống hỗ trợ cộng tác thời gian thực cho nhiều người dùng đồng thời, mô hình request-response qua giao thức HTTP truyền thống không phải là một lựa chọn tốt. Để tương tác thực sự là thời gian thực, cần có một giao thức song hướng cho phép gửi dữ liệu liên tục đến client ngay khi có bất kỳ thay đổi nào.

Tuy nhiên, triển khai các giao thức song hướng tại quy mô lớn là một thách thức không nhỏ. Khi số lượng người dùng tăng lên hàng triệu, hệ thống sẽ phải duy trì một lượng kết nối đồng thời rất lớn. Điều này không chỉ tốn nhiều tài nguyên mà còn dẫn đến các vấn đề về độ tin cậy và khả năng phục hồi của hệ thống.

Long polling là một cách tiếp cận phổ biến, nó sẽ gửi yêu cầu mới sau mỗi phản hồi. Điều này gây ra độ trễ đáng kể, đồng thời làm phức tạp thêm việc quản lý trạng tháikhả năng xử lý đồng thời trên máy chủ.


image.png


Server-Sent Events (SSE) trên HTTP/2 đã cải thiện bằng cách cho phép server gửi dữ liệu đến client mà không cần yêu cầu. Tuy nhiên, SSE vẫn chỉ là giao thức một chiều, vì vậy cần kết hợp với một giao thức bổ sung để có được tính năng song hướng hoàn chỉnh.


image.png


WebSockets tuy đáp ứng được nhu cầu giao tiếp song hướng, nhưng lại bộc lộ nhiều hạn chế khi triển khai trong microservices. Khi số lượng người dùng tăng lên, hệ thống phải duy trì một lượng kết nối WebSockets cực lớn đồng thời. Điều này không chỉ gây áp lực lên máy chủ, mà còn khiến cho khả năng mở rộng quy mô bị giới hạn.

Cuối cùng, bản chất của WebSockets là một giao thức transport layer khiến việc xác định luồng dữ liệu cho một ứng dụng back-end cụ thể trở nên khó khăn. Với những hạn chế này, rõ ràng cần có một giải pháp mới, được thiết kế đặc biệt cho bài toán cộng tác thời gian thực tại quy mô lớn. Và RSocket chính là câu trả lời.

RSocket

Để đáp ứng nhu cầu xây dựng các hệ thống microservices có khả năng phục hồi cao và phản hồi nhanh, một nhóm các công ty hàng đầu đã cùng nhau phát triển giao thức RSocket.

image.png

RSocket được thiết kế ở application layer và tích hợp sâu các nguyên lý của Reactive Streams. Điều này cho phép RSocket xử lý luồng dữ liệu một cách linh hoạt, bất đồng bộ và đảm bảo khả năng phục hồi cao trong trường hợp xảy ra sự cố.

Không chỉ hỗ trợ giao tiếp Client - Server, RSocket còn mở rộng sang kết nối Server - Server, phù hợp với kiến trúc microservices ngày càng phổ biến.

1. Hiệu suất vượt trội

WebSockets không hỗ trợ đa kênh (multiplexing). Điều này hạn chế khả năng truyền tải nhiều luồng dữ liệu đồng thời trên cùng một kết nối mạng.

Trong khi đó, RSocket giải quyết vấn đề đa kênh bằng cách tạo ra nhiều kênh logic bên trong một kết nối mạng duy nhất. Mỗi kênh logic chính là một đường truyền dữ liệu độc lập. Thậm chí, RSocket còn cho phép trộn ghép các phần của nhiều message khác nhau trên cùng một kênh để tối ưu băng thông.

51739f50-d453-460d-bdb0-5cadce927e7b.png

Đa kênh giúp RSocket có khả năng truyền song song nhiều luồng dữ liệu mà không bị nghẽn hay cạn kiệt tài nguyên. Nhờ vậy, nó đảm bảo được hiệu suất giao tiếp bất đồng bộ cao cho các ứng dụng thời gian thực tại quy mô lớn.

Để triển khai RSocket, có thể sử dụng các thư viện Reactive Streams như RxJava. Những thư viện này tối ưu việc xử lý luồng dữ liệu, đảm bảo giao tiếp an toàn và hiệu quả.

2. Định dạng dữ liệu

RSocket là một giao thức nhị phân (binary protocol) được sử dụng trên các lớp vận chuyển như TCP, WebSockets hoặc Aeron. Điều này có nghĩa là RSocket không phụ thuộc vào transport layer cụ thể nào, mà có thể hoạt động trên nhiều transport layer khác nhau.

Ví dụ, RSocket có thể mã hóa dữ liệu JSON thành định dạng nhị phân và gửi đi dưới dạng dữ liệu nhị phân.

image.png

Một RSocket message bao gồm hai thành phần chính: datametadata. Điều đáng lưu ý là data và metadata có thể được biểu diễn ở các định dạng khác nhau.

Ngoài ra, RSocket hỗ trợ giao thức RPC (Remote Procedure Call) và truyền thông tin dựa trên sự kiện (event-based messaging). Điều này cho phép RSocket gửi đi các thông điệp thực sự (real messages) thay vì chỉ đơn thuần là các luồng byte.

3. Tính linh hoạt

RSocket được hỗ trợ bởi hầu hết các ngôn ngữ lập trình phổ biến, đảm bảo khả năng tương thích và linh hoạt trong việc triển khai.

Một tính năng quan trọng khác của RSocket là khả năng kiểm soát luồng dữ liệu ở cấp ứng dụng (application-level flow control). Điều này cho phép lập trình viên có thể chỉ định số lượng messages mà ứng dụng có thể tiêu thụ một cách hiệu quả, mà không cần phải triển khai thủ công các cơ chế như buffering hoặc windowing.

Ngoài ra, RSocket cũng cho phép thêm dữ liệu để xác định luồng logic (logical stream identification) và cung cấp thông tin cho cơ sở hạ tầng (infrastructure).

4. Khả năng phục hồi

Trong một kết nối RSocket, mỗi kênh (channel) sẽ thực hiện kiểm soát áp lực (backpressure) một cách độc lập. Nói cách khác, có kiểm soát luồng dữ liệu trên từng luồng logic riêng biệt.

Khái niệm Backpressure đề cập đến việc làm chậm lại luồng dữ liệu để tránh gây quá tải cho bên nhận. Nếu không có cơ chế này, các yêu cầu đang chờ xử lý có thể làm sập toàn bộ hệ thống. Do đó, backpressure giúp giảm thiểu blast radius (phạm vi ảnh hưởng của sự cố).

Tuy nhiên, RSocket chỉ cho phép triển khai backpressure trên một số kênh cụ thể trong cùng một kết nối. Điều này rất hợp lý vì đối với một số dịch vụ như phân tích dữ liệu, việc đệm dữ liệu là cần thiết. Nhưng với các dịch vụ quan trọng, cần đảm bảo tính nhất quán cao, nên dữ liệu không đáng tin cậy sẽ bị loại bỏ.

image.png

Phía client có thể thông báo cho server về số lượng messages. Và server sẽ dành sẵn tài nguyên để trả về đúng số lượng messages đó. Đây được gọi là cơ chế Leasing

Ngoài ra, server cũng có thể thông báo khả năng xử lý của mình cho client thông qua các frame dữ liệu. Nhờ vậy, nó hoạt động như một bộ giới hạn tỷ lệ (rate limiter) và đóng ngắt mạch (circuit breaker) tự nhiên.

Bên cạnh đó, RSocket cũng hỗ trợ tín hiệu heartbeat giúp duy trì kết nối.

5. Mô hình giao tiếp

Một khi kết nối được thiết lập, sự phân biệt giữa client và server trong RSocket sẽ bị loại bỏ. Cả hai bên trở nên đối xứng thông qua giao tiếp ngang hàng (peer-to-peer). Nói cách khác, mỗi bên đều có thể khởi tạo các tương tác.

image.png

RSocket hỗ trợ các mô hình giao tiếp sau:

  • Request-Response: Một bên gửi yêu cầu và nhận phản hồi tương ứng, phù hợp cho các tương tác đơn giản.
  • Request-Stream: Cho phép gửi một yêu cầu và nhận một luồng phản hồi liên tục, thích hợp cho các trường hợp cần truyền dữ liệu theo thời gian thực.
  • Request-Channel: Cho phép cả hai bên gửi và nhận luồng dữ liệu song song, hữu ích cho các ứng dụng cần trao đổi dữ liệu hai chiều.
  • Fire-and-Forget: Gửi một thông điệp một chiều, phù hợp cho các trường hợp chỉ cần gửi thông điệp một chiều mà không cần phản hồi.

Với mô hình giao tiếp ngang hàng và khả năng hỗ trợ đa dạng các kiểu giao tiếp, RSocket cho phép xây dựng các ứng dụng phân tán linh hoạt và hiệu quả hơn. Sự đối xứng giữa các bên tham gia giúp tối ưu hóa việc trao đổi dữ liệu, đồng thời đáp ứng các yêu cầu giao tiếp khác nhau trong hệ thống.

Kiến trúc của Canva

Trong kiến trúc của Canva, client kết nối với máy chủ WebSocket Gateway thông qua giao thức HTTP.

Trong khi đó, kết nối giữa máy chủ WebSocket Gateway và các máy chủ backend được thực hiện thông qua giao thức RSocket.

Phía backend của Canva sử dụng ngôn ngữ lập trình Java.

image.png

Canva quản lý nhiều kênh (channels) trong một kết nối RSocket duy nhất. Nhờ đó, tổng số kết nối cần thiết được giữ ở mức thấp, giúp tối ưu hóa hiệu suất và tài nguyên hệ thống.

Ngoài ra, Canva sử dụng thuật toán "least-loaded" (tải thấp nhất) để cân bằng tải cho các kênh RSocket. Lý do là vì các kết nối đến các máy chủ backend thường có thời gian tồn tại dài.

Với kiến trúc này, Canva có thể tận dụng tối đa lợi thế của giao thức RSocket trong việc quản lý luồng dữ liệu, kết nối hiệu quả và khả năng mở rộng. Điều này giúp Canva đảm bảo hiệu suất và khả năng phục vụ cho một lượng lớn người dùng trên toàn cầu.

Việc sử dụng WebSocket Gateway làm cầu nối giữa client và các máy chủ backend cho phép tách biệt và quản lý hiệu quả các giao thức khác nhau được sử dụng trong hệ thống. Trong khi đó, Java được lựa chọn cho phía backend nhằm tận dụng các lợi thế về hiệu năng, khả năng mở rộng và cộng đồng phát triển lớn mạnh của ngôn ngữ này.

Tổng thể, kiến trúc của Canva thể hiện một cách tiếp cận hiệu quả và linh hoạt trong việc xây dựng một hệ thống phân tán quy mô lớn, đáp ứng các yêu cầu về hiệu suất, khả năng mở rộng và trải nghiệm người dùng tốt nhất.


Tổng kết

Trải nghiệm người dùng tốt là mục tiêu hàng đầu của mọi ứng dụng. Khả năng truyền dữ liệu thời gian thực giúp nâng cao trải nghiệm này, nhưng triển khai lại rất phức tạp. Lựa chọn giao thức phù hợp là chìa khóa để đảm bảo hiệu suất, khả năng mở rộng và kiểm soát chi phí hệ thống.

RSocket, một giao thức cloud-native được thiết kế cho hiệu năng cao, đang dần trở thành lựa chọn hấp dẫn. Mặc dù vẫn trong giai đoạn phát triển, RSocket đã chứng minh tiềm năng to lớn trong xây dựng ứng dụng phân tán, đáp ứng yêu cầu khắt khe về hiệu suất, phục hồi và mở rộng.


Sydexa.com xin hẹn gặp lại các bạn ở các bài viết thú vị hơn nha

Lời nhắn

Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về thiết kế hệ thống nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng System Design Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng System Design Việt Nam: https://www.facebook.com/groups/sydexa


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí