Bài viết này nói về câu chuyện phi thường của Adam D'Angelo, đồng sáng lập Quora, và các kỹ thuật sharding được sử dụng để shard MySQL tại Quora.
Mùa hè năm 2005 tại California, Hoa Kỳ, Adam D'Angelo trở thành nhân viên của Facebook. Sau đó, anh ta được bổ nhiệm làm Giám đốc Công nghệ (CTO). Tuy nhiên, anh cảm thấy trách nhiệm công việc không còn phù hợp với kỹ năng và sở thích của mình nữa - điều hoàn toàn hợp lý vì mỗi người có định nghĩa riêng về thành công.
Như nhà thơ Robert Frost đã viết: "Tôi đã đi con đường ít người đi, và điều đó đã tạo nên tất cả sự khác biệt." Adam muốn xây dựng Quora - một nền tảng hỏi đáp. Vì vậy, anh quyết định rời khỏi Facebook để theo đuổi ước mơ này.
Với đội ngũ kỹ thuật xuất sắc, Quora đã áp dụng các kỹ thuật sharding tiên tiến để mở rộng quy mô cơ sở dữ liệu MySQL.
Nhu cầu lưu trữ dữ liệu tại đây lên tới hàng chục terabyte, với hàng trăm nghìn lượt truy vấn mỗi giây(QPS).
Họ lựa chọn MySQL để lưu trữ và tăng hiệu suất đọc các dữ liệu quan trọng như câu hỏi, câu trả lời, lượt upvote và bình luận, vượt trội hơn các cơ sở dữ liệu NoSQL như HBase thường không được tối ưu cho các hệ thống nặng về tác vụ đọc dữ liệu.
Các kỹ sư của Quora muốn đạt hiệu suất đọc dữ liệu tối ưu hơn nữa, nên đã thêm một lớp bộ nhớ cache trước cơ sở dữ liệu. Tuy nhiên, vấn đề vẫn chưa được giải quyết triệt để, bởi sự gia tăng nhanh chóng của dữ liệu và QPS.
Giải pháp được áp dụng là sharding MySQL, tức là chia nhỏ cơ sở dữ liệu này lên nhiều máy chủ để nâng cao hiệu suất.
Cùng Sydexa tìm hiểu về công nghệ cực kỳ thú vị này nha!!! 😄😄
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
Shard MySQL là gì?
Mỗi máy chủ đơn lẻ đều có giới hạn về khả năng lưu trữ và xử lý dữ liệu.
Sharding là kỹ thuật giúp vượt qua giới hạn này bằng cách phân tán một cơ sở dữ liệu lớn ra nhiều máy chủ khác nhau.
Đơn giản là sharding cho phép chia nhỏ khối lượng công việc từ một máy chủ đơn ra nhiều máy chủ, tăng không gian lưu trữ và năng lực xử lý dữ liệu.
Cách Shard cơ sở dữ liệu MySQL
Mặc dù MySQL cho phép thực hiện sharding, nhưng nó không hỗ trợ tự động hóa quá trình này. Vì vậy, các kỹ sư phải thực hiện sharding MySQL theo các thủ công.
Tại Quora, các kỹ sư kết hợp cả sharding dọc(vertical sharding) và sharding ngang(horizontal sharding) để shard MySQL.
Vertical sharding
Trong MySQL, mô hình leader - follower là kiến trúc nhân rộng (replication) phổ biến nhất. Leader xử lý các yêu cầu đọc-ghi, còn followers chỉ xử lý yêu cầu đọc và nhân bản dữ liệu từ leader.
Vertical sharding là một kỹ thuật trong cơ sở dữ liệu phân tán, nơi các bảng dữ liệu khác nhau được lưu trữ trên các máy chủ riêng biệt. Kỹ thuật này cho phép phân tán các bảng ra nhiều máy chủ khác nhau, cải thiện khả năng mở rộng và ghi dữ liệu.
Phân vùng là sự phân chia của cơ sở dữ liệu logic thành các phần độc lập khác nhau. Tuy nhiên, theo Quora, phân vùng cũng có nghĩa là một cụm có một leader và các follower.
Trong vertical sharding, metadata được lưu trữ trong Apache Zookeeper bao gồm:
-
Ánh xạ từ phân vùng đến danh sách bảng trong phân vùng đó
-
Ánh xạ từ phân vùng đến danh sách máy chủ
Khi bảng dữ liệu lớn hoặc có lưu lượng truy cập cao sẽ được di chuyển tới một phân vùng mới để tăng khả năng mở rộng.
Trong MySQL, để thực hiện các phép kết hợp (join) giữa các bảng, các bảng đó phải thuộc về cùng một cơ sở dữ liệu và phân vùng. Tuy nhiên, khi áp dụng kỹ thuật vertical sharding, các bảng dữ liệu thường được chia thành các phân vùng khác nhau, vì vậy việc join các bảng ở mức cơ sở dữ liệu sẽ không thể thực hiện được. Để giải quyết vấn đề này, một phương pháp thường được sử dụng là kết hợp các bảng ở mức ứng dụng.
Nhược điểm của vertical sharding bao gồm:
-
Vấn đề độ trễ trong sao chép khi di chuyển các bảng lớn sang phân vùng khác.
-
Giảm khả năng xử lý các transactional.
-
Hiệu suất giảm đi nếu bảng trở nên rất lớn.
Horizontal Sharding
Đối với các bảng lớn trong cơ sở dữ liệu nếu áp dụng vertical sharding sẽ trở thành vấn đề với họ vì những lý do sau:
-
Thay đổi lược đồ dữ liệu (schema) trở nên khó khăn
-
Di chuyển bảng sang máy chủ khác gặp nhiều thách thức
-
Các lỗi bất ngờ có thể làm hỏng toàn bộ dữ liệu trong bảng
Horizontal Sharding là kỹ thuật chia nhỏ một bảng logic thành nhiều bảng vật lý.
Với sharding theo chiều ngang, một bảng lớn được phân tán lên nhiều máy chủ/phân vùng khác nhau, mỗi phân vùng chứa một phần dữ liệu của bảng gốc. Điều này giúp giảm gánh nặng trên từng máy chủ đơn lẻ, cải thiện khả năng mở rộng và hiệu suất của hệ thống. Các vấn đề về thay đổi lược đồ, di chuyển hay lỗi dữ liệu cũng được giải quyết hiệu quả hơn khi dữ liệu được phân tán.
Các quyết định thiết kế chính để thực hiện horizontal sharding ở Quora được thực hiện như sau:
1. Sử dụng các giải pháp có sẵn hay tự xây dựng?
Họ quyết định không sử dụng một giải pháp của bên thứ ba (Vitess), mà tự xây dựng giải pháp sharding riêng. Lý do đằng sau quyết định này là:
-
Việc làm chủ công nghệ để chỉnh sửa một dịch vụ sharding của bên thứ 3 rất tốn kém. Trong khi đó, họ chỉ có dưới 10 bảng lớn cần sharding.
-
Dễ dàng tái sử dụng logic vartical sharding hiện có.
-
Dễ dàng hỗ trợ API tùy chỉnh ở cấp cơ sở dữ liệu.
-
Không cần kết hợp (join) ở cấp cơ sở dữ liệu. Họ thực hiện kết hợp ở cấp ứng dụng.
-
Không sử dụng thêm bất kỳ lớp trung gian hoặc middleware nào khác trong hệ thống. Bằng cách này, họ giữ cho độ trễ ở mức thấp.
2. Các cấp độ Shard
Có 2 cấp độ để shard cơ sở dữ liệu: cấp độ cơ sở dữ liệu logic và cấp độ bảng.
-
Sharding ở cấp cơ sở dữ liệu logic khá đơn giản, hệ thống sẽ tiến hành shard toàn bộ bảng trong cùng một máy chủ cơ sở dữ liệu.
-
Sharding ở cấp độ bảng áp dụng cho các bảng lớn, có nhiều dữ liệu.
Shard ở cấp bảng được ưu tiên sử dụng do sử dụng rộng rãi các chỉ mục thứ cấp (secondary index) tại Quora. Chỉ mục thứ cấp là chỉ mục không dựa trên chỉ mục chính (primary index) thường và có thể chứa giá trị trùng lặp.
Chỉ mục thứ cấp chỉ được lưu trữ trong một shard. Vì vậy, các truy vấn dựa trên chỉ mục thứ cấp có thể phải truy vấn tất cả các shard của bảng (scatter-and-gather pattern), làm cho sharding ở cấp cơ sở dữ liệu logic trở nên tốn kém.
Có một cách để khắc phục vấn đề này, đó là chuyển chỉ mục thứ cấp sang một bảng chuyên biệt rồi mới shard. Nhưng cách này không dễ để thực hiện.
Việc shard ở cấp độ bảng là khả thi. Bởi vì chỉ những truy vấn đối với các bảng đã được shard cần thực hiện quá trình tán rải và thu thập (scatter and gather).
3. Phương pháp Sharding
Một bảng logic được chia thành nhiều bảng vật lý thông qua sharding. Các phương pháp sharding phổ biến là:
- Phân vùng dựa trên phạm vi (Range-based partitioning) Với phương pháp này, dữ liệu trong bảng sẽ được phân chia dựa trên một cột nhất định có giá trị thuộc một phạm vi nào đó. Ví dụ, các hàng có giá trị cột từ 1-1000 sẽ nằm trên Shard 1, từ 1001-2000 trên Shard 2, và cứ thế. Mỗi shard sẽ chứa một phạm vi giá trị cụ thể của cột đó.
- Phân vùng dựa trên hàm băm (Hash-based partitioning) Thay vì dựa trên phạm vi, phương pháp này sử dụng một hàm băm (hashing) để tính toán và gán một khóa shard cho mỗi hàng dữ liệu dựa trên giá trị của một hoặc nhiều cột. Các hàng có cùng khóa shard sẽ được đặt trên cùng một shard. Điều này giúp phân tán dữ liệu đều hơn giữa các shard.
4. API để Truy vấn Bảng đã Shard
Các kĩ sư đã thiết kế API ở cơ sở dữ liệu, các API này nhận tham số và tạo các lệnh SQL thay vì nhận trực tiếp câu lệnh. Mục đích của cách làm này nhằm tránh các cuộc tấn công SQL injection.
SQL Injection là kỹ thuật tấn công bằng cách chèn mã độc hại vào các câu lệnh SQL, thường thông qua việc nhập dữ liệu từ người dùng. Nếu không được xử lý đúng cách, điều này có thể gây ra những hậu quả nghiêm trọng.
Để hỗ trợ truy vấn các bảng đã shard, họ đã mở rộng API bằng cách thêm vào khả năng truyền vào tên cột sharding và giá trị khóa sharding tương ứng.
5. Sharding Cột
Lựa chọn cột sharding là một quyết định quan trọng, vì nó ảnh hưởng đến hiệu suất truy vấn. Tại Quora, họ lựa chọn cột sharding dựa trên hai yếu tố chính: độ trễ và lưu lượng truy vấn.
Việc sử dụng một cột không phải cột sharding để truy vấn sẽ dẫn đến mô hình scatter-and-gather - truy vấn phải được thực hiện trên tất cả các shard. Điều này làm tăng độ trễ, vì thời gian truy vấn phụ thuộc vào shard chậm nhất.
Để tối ưu hiệu suất, họ đã sử dụng chỉ mục cross-shard. Đây là một bảng riêng biệt, ánh xạ giá trị của cột không phải cột sharding sang cột sharding. Trong một số trường hợp, chỉ mục này có thể giúp tránh được mô hình scatter-and-gather bằng cách chỉ cần truy vấn một shard duy nhất.
Tuy nhiên, việc sử dụng chỉ mục cross-shard cũng có nhược điểm. Chúng ta vẫn phải truy vấn chỉ mục này, tốn kém một chi phí nhất định. Hơn nữa, nếu có nhiều giá trị trong cột sharding tương ứng với một giá trị cột không phải sharding, chỉ mục sẽ buộc phải truy vấn nhiều shard, làm giảm hiệu suất. Việc duy trì tính nhất quán của chỉ mục cross-shard cũng là một thách thức.
6. Số Lượng Shard Thích Hợp
Số lượng shard cần được xác định một cách cân bằng dựa trên kích thước dữ liệu. Nguyên tắc chung là nên giữ số lượng shard ở mức thấp, tránh chia nhỏ dữ liệu quá nhiều.
Lý do đằng sau nguyên tắc này là để đảm bảo hiệu suất truy vấn tối ưu. Khi một truy vấn sử dụng cột không phải cột sharding, nó sẽ phải được thực hiện trên tất cả các shard có liên quan. Điều này dẫn đến mô hình "scatter-and-gather", với độ trễ tổng thể phụ thuộc vào shard chậm nhất. Vì vậy, nếu số lượng shard quá lớn, độ trễ truy vấn sẽ gia tăng đáng kể.
Quora đã trở thành một kỳ lân công nghệ.
Theo tạp chí Forbes, vào năm 2023, Adam D'Angelo có giá trị tài sản khoảng 600 triệu USD. Ông là một ví dụ xuất sắc về người dám theo đuổi ước mơ để đạt được thành công.
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