Bí mật đằng sau bài toán lưu trữ media của Canva và hành trình tìm đến DynamoDB
Canva, một công cụ thiết kế trực tuyến chắc hẳn bạn đã từng nghe qua hoặc đã từng dùng để tạo ra các design một cách vô cùng nhanh chóng. Canva được hàng triệu người yêu thích trên toàn cầu, không chỉ nổi tiếng với giao diện thân thiện và kho tài nguyên đồ họa khổng lồ mà còn nhờ khả năng cho phép người dùng tự do tải lên các design của riêng họ.
Với hơn 100 triệu người dùng hoạt động hàng tháng và 50 triệu tệp media được tải lên mỗi ngày, Canva đã nhanh chóng trở thành một trong những nền tảng thiết kế trực tuyến phổ biến nhất thế giới.
Tuy nhiên, sự tăng trưởng vượt bậc này cũng đặt ra một thách thức không nhỏ cho đội ngũ kỹ sư của Canva:
(đôi khi công ty phát triển nhanh quá cũng khổ mấy ông dev phết 😄) làm thế nào để quản lý và lưu trữ khối lượng dữ liệu khổng lồ này một cách hiệu quả, đảm bảo trải nghiệm người dùng luôn mượt mà và không bị gián đoạn nhỉ?
Cùng Sydexa tìm hiểu cách mà Canva giải quyết vấn đề khá khoai này nha
Bạn cho chúng mình xin 1 upvote và comment để chúng mình nhận giải của viblo nha. Và chúng mình có động lực ra những bài viết thú vị hơn nữa 😄😄😄
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
Kiến trúc hiện tại của Canva và vấn đề gặp phải
Canva được xây dựng trên một kiến trúc microservices linh hoạt, nơi mỗi service đảm nhận một vai trò riêng biệt. Trong đó, dịch vụ media đóng vai trò trung tâm, quản lý toàn bộ thông tin liên quan đến tài nguyên media của người dùng, từ ID, chủ sở hữu, trạng thái (đang hoạt động, đã xóa, chờ xóa...) cho đến metadata (tiêu đề, tác giả, từ khóa, thông tin màu sắc...) và đặc biệt là vị trí lưu trữ của tệp tin.
Service media hoạt động như một "thủ thư" cực kỳ tận tâm, liên tục xử lý hàng loạt request đọc và ghi dữ liệu. Tuy nhiên, có một điểm thú vị là lượng yêu cầu đọc vượt xa lượng yêu cầu ghi, bởi người dùng thường xuyên tìm kiếm và sử dụng các media có sẵn hơn là chỉnh sửa chúng. Hầu hết các tệp media ít khi bị thay đổi sau khi được tạo ra, ngoại trừ những media nằm trong thư viện ảnh và đồ họa của Canva.
Ban đầu, Canva lựa chọn MySQL trên AWS RDS làm "ngôi nhà" để lưu trữ "kho báu" media của mình. Tuy nhiên, khi "gia tài" media ngày càng đồ sộ với tốc độ tăng trưởng chóng mặt, MySQL bắt đầu bộc lộ những hạn chế.
Việc thay đổi cấu trúc (schema) của các bảng media lớn trở nên chậm chạp, có thể mất đến hàng ngày trời. Giới hạn về tốc độ sao chép của MySQL 5.6 đã cản trở tốc độ ghi vào các bản sao đọc. Canva cũng sắp đạt đến giới hạn về kích thước volume EBS của RDS MySQL (16TB) tại thời điểm đó. Hơn nữa, mỗi lần nâng cấp dung lượng lưu trữ lại kéo theo sự gia tăng độ trễ I/O, ảnh hưởng trực tiếp đến tốc độ phản hồi yêu cầu của người dùng. Việc khởi động lại máy chủ hay nâng cấp phiên bản MySQL cũng gây ra downtime, điều tối kỵ đối với một nền tảng trực tuyến như Canva.
Các giải pháp tạm thời để khắc phục vấn đề
Để kéo dài tuổi thọ cho MySQL trong khi tìm kiếm một giải pháp thay thế lâu dài, Canva đã thực hiện một loạt các biện pháp tạm thời. Một trong những thay đổi quan trọng là chuyển metadata nội dung sang một cột JSON riêng biệt. Metadata, là phần thông tin mô tả về tệp media, thường xuyên được cập nhật và thay đổi. Việc chuyển metadata sang JSON cho phép Canva tự quản lý schema của phần dữ liệu này một cách linh hoạt hơn, giảm sự phụ thuộc vào việc thay đổi schema của toàn bộ bảng dữ liệu, vốn rất tốn kém về thời gian và tài nguyên.
Tiếp theo, Canva đã thực hiện phi chuẩn hóa một số bảng (Denormalized) để giảm xung đột khóa (lock contention) và số lượng phép nối (join) cần thiết khi thực hiện truy vấn.
Bên cạnh đó, Canva cũng thực hiện các biện pháp tối ưu hóa khác như loại bỏ các nội dung lặp lại hoặc mã hóa chúng một cách ngắn gọn hơn. Điều này giúp giảm dung lượng lưu trữ và tăng tốc độ truy vấn. Canva cũng loại bỏ các ràng buộc khóa ngoại để tăng tốc độ ghi và cập nhật dữ liệu, mặc dù điều này có thể làm giảm tính toàn vẹn dữ liệu. Cuối cùng, Canva thay đổi cách thức nhập media để giảm số lần cập nhật metadata, giúp giảm tải cho hệ thống.
Một giải pháp tạm thời quan trọng khác được Canva áp dụng là sharding. Đây là kỹ thuật chia nhỏ dữ liệu thành nhiều phần và lưu trữ trên nhiều máy chủ khác nhau. Sharding giúp Canva vượt qua giới hạn kích thước tệp bảng 2TB của hệ thống tệp ext3, đồng thời tăng tốc độ sao chép và cải thiện hiệu suất cho các truy vấn theo ID, vốn là loại truy vấn phổ biến nhất khi tải thiết kế trên Canva. Tuy nhiên, sharding cũng có nhược điểm là kém hiệu quả đối với các truy vấn ít phổ biến hơn, chẳng hạn như liệt kê tất cả media thuộc sở hữu của một người dùng.
Mặc dù các biện pháp trên đã giúp Canva tạm thời giải quyết được những vấn đề cấp bách, nhưng về lâu dài, họ vẫn cần một giải pháp lưu trữ mới có khả năng mở rộng và đáp ứng tốt hơn nhu cầu ngày càng tăng của người dùng.
Quá trình di chuyển từ MySQL sang DynamoDB
Sau khi xem xét và thử nghiệm nhiều giải pháp khác nhau, Canva đã chọn DynamoDB làm điểm đến cuối cùng cho kho dữ liệu media khổng lồ của mình. DynamoDB là một cơ sở dữ liệu NoSQL được quản lý hoàn toàn bởi AWS, nổi tiếng với khả năng mở rộng linh hoạt, tính sẵn sàng cao và hiệu suất vượt trội, đáp ứng được yêu cầu khắt khe về khả năng mở rộng và tốc độ của Canva.
Tuy nhiên, quá trình di chuyển dữ liệu từ MySQL sang DynamoDB không hề đơn giản. Canva phải đối mặt với hai yêu cầu quan trọng: không được gây ảnh hưởng đến trải nghiệm người dùng và thực hiện chuyển đổi mà không có bất kỳ downtime nào. Để đảm bảo tính liên tục của dịch vụ, Canva đã triển khai một chiến lược di chuyển vô cùng tỉ mỉ và thận trọng.
Canva cần di chuyển tất cả các dữ liệu cũ, các dữ liệu mới được tạo, và các dữ liệu mới được cập nhật sang Dynamo DB.
Đầu tiên, Canva sử dụng hàng đợi SQS của AWS để gửi các thông báo về việc một tập tin media cụ thể đã được tạo, cập nhật hoặc đọc, nhưng không chứa nội dung của bản cập nhật. Một worker instance sẽ xử lý các thông báo này để đọc trạng thái hiện tại từ cơ sở dữ liệu MySQL chính và cập nhật DynamoDB. Các bản ghi mới được tạo, cập nhật hoặc được đọc gần đây sẽ được ưu tiên sao chép sang DynamoDB trước. Cách tiếp cận này đảm bảo rằng những dữ liệu được sử dụng thường xuyên nhất sẽ có sẵn trên DynamoDB, giúp giảm thiểu độ trễ và cải thiện trải nghiệm người dùng, giảm tải cho cụm MySQL
Ghi dữ liệu trong quá trình di chuyển từ MySQL sang DynamoDB:
Các thông báo về việc tạo mới hoặc cập nhật media được đặt vào hàng đợi ưu tiên cao, trong khi các thông báo về việc đọc media được đặt vào hàng đợi ưu tiên thấp. Điều này đảm bảo rằng các worker instance sẽ tập trung vào việc xử lý các thông báo ghi trước để dữ liệu mới được cập nhật nhanh chóng trên tất cả các bản sao của DynamoDB. Sau khi đã xử lý hết các thông báo ghi, chúng mới chuyển sang xử lý các thông báo đọc.
Điều này giúp cho đảm bảo có thể phục vụ các yêu cầu đọc có tính nhất quán cuối cùng (eventually consistent) từ DynamoDB
Đọc dữ liệu trong quá trình di chuyển từ MySQL sang DynamoDB:
Tiếp theo, Canva thực hiện một quá trình quét và sao chép dần dần để chuyển toàn bộ dữ liệu còn lại sang DynamoDB. Quá trình này được thực hiện một cách cẩn thận và kiểm soát để không ảnh hưởng đến hoạt động của hệ thống.
Quá trình quyét dữ liệu:
Để di chuyển những media còn lại sang DynamoDB, Canva sẽ quét qua tất cả các media, bắt đầu từ những media được tạo gần đây và gửi một thông báo qua message queue có độ ưu tiên thấp, để worker thực hiện sao chép qua DynamoDB.
Quá trình kiểm tra
Để đảm bảo tính toàn vẹn của dữ liệu trong quá trình di chuyển, Canva đã thực hiện nhiều biện pháp kiểm tra nghiêm ngặt. Trước khi chuyển hoàn toàn sang đọc từ DynamoDB, Canva đã thực hiện kiểm tra so sánh kết quả từ cả hai hệ thống MySQL và DynamoDB. Bất kỳ sự không nhất quán nào được phát hiện sẽ được điều tra và sửa chữa ngay lập tức. Ngoài ra, Canva cũng sử dụng MySQL như một phương án dự phòng (fallback) trong giai đoạn đầu của quá trình chuyển đổi. Điều này đảm bảo rằng nếu có bất kỳ vấn đề nào xảy ra với DynamoDB, hệ thống vẫn có thể hoạt động bình thường bằng cách đọc dữ liệu từ MySQL. Nhờ sự kết hợp của các biện pháp này, Canva đã thực hiện thành công việc di chuyển dữ liệu sang DynamoDB một cách an toàn và không gây gián đoạn cho người dùng.
Việc chuyển đổi sang DynamoDB đã mang lại những kết quả vượt ngoài mong đợi cho Canva. Độ trễ của dịch vụ media giảm đáng kể, giúp cải thiện tốc độ tải và trải nghiệm người dùng. Khả năng mở rộng của DynamoDB cũng được thể hiện rõ rệt khi số lượng người dùng hoạt động hàng tháng của Canva tăng gấp ba lần kể từ khi chuyển đổi, và DynamoDB vẫn hoạt động ổn định, tự động mở rộng quy mô để đáp ứng nhu cầu ngày càng tăng. Không chỉ vậy, chi phí vận hành DynamoDB còn thấp hơn so với cụm AWS RDS trước đây, mang lại hiệu quả kinh tế đáng kể cho Canva.
Tuy nhiên, quá trình chuyển đổi này cũng mang đến những bài học quý giá cho đội ngũ kỹ sư của Canva. Họ nhận ra tầm quan trọng của việc hiểu rõ đặc điểm truy cập dữ liệu để ưu tiên di chuyển những dữ liệu được sử dụng thường xuyên nhất. Bên cạnh đó, việc kiểm tra và thử nghiệm trong môi trường production cũng được coi là rất cần thiết để đảm bảo tính ổn định của hệ thống sau khi chuyển đổi. Mặc dù DynamoDB không có những tính năng tiện lợi như thay đổi schema dễ dàng hay hỗ trợ truy vấn SQL ad-hoc, những lợi ích về khả năng mở rộng và hiệu suất đã bù đắp cho những hạn chế này.
Hành trình chuyển đổi từ MySQL sang DynamoDB đã đánh dấu một cột mốc quan trọng trong quá trình phát triển của Canva. Không chỉ giải quyết triệt để bài toán lưu trữ media, Canva còn chứng minh được khả năng thích ứng và vượt qua những thách thức về công nghệ để đáp ứng nhu cầu ngày càng tăng của người dùng. Với DynamoDB, Canva đã xây dựng một hệ thống lưu trữ media mạnh mẽ và linh hoạt, đủ sức chứa hơn 25 tỷ file media do người dùng tải lên và sẵn sàng đón nhận thêm 50 triệu file mới mỗi ngày. Thành công này không chỉ khẳng định vị thế của Canva là một trong những nền tảng thiết kế trực tuyến hàng đầu thế giới mà còn mở ra những cơ hội phát triển mới trong tương lai.
Nếu thấy bài viết này hay thì cho chúng mình xin 1 upvote và comment để chúng mình nhận giải của viblo 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
Kênh TikTok: https://www.tiktok.com/@sydexa.com
Bạn có thể tìm hiểu thêm:
Chia sẻ từ chính canva: https://www.canva.dev/blog/engineering/from-zero-to-50-million-uploads-per-day-scaling-media-at-canva
DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html
Eventual Consistency: https://www.scylladb.com/glossary/eventual-consistency/
All rights reserved