I. LỜI NÓI ĐẦU
Chào mọi người, cũng lâu rồi mình mới quay lại viết blog sau nhiều sóng gió của năm 2024. Dường như việc quay lại chia sẻ technical phần nào giúp mình tìm lại đam mê và cảm hứng lập trình sau nhiều biến cố xảy đến.
Dành cho các bạn đọc mới biết đến mình thì mình cũng xin giới thiệu lại, các bài viết của mình sẽ xoay quanh chủ đề liên quan đến các lĩnh vực Backend, Blockchain cũng như DevOps. Ngoài ra, mình cũng viết chia sẻ về suy nghĩ, tâm sự và quan điểm sống trên một vài lĩnh vực về tâm lý học, tài chính và phát triển bản thân.
Và hôm nay là bài viết cuối cùng của năm 2024 cũng như là bài viết thuộc lĩnh vực Technical cuối bằng tiếng việt mà mình chia sẻ. Sang năm mới, mình sẽ cố gắng duy trì thói quen viết blog bằng tiếng anh và xen kẽ các bài blog tâm sự bằng tiếng việt. Mọi người có thể đón đọc thêm trên blog cá nhân mình nhé.
Nếu mọi người vẫn còn nhớ thì trước đây mình có viết chuỗi bài hướng dẫn về cấu hình và thiết lập MongoDB. Các bạn có thể tìm xem lại các bài viết cũ thuộc chuỗi series tại đây nhé:
- Phần 1: cấu hình standalone MongoDB
- Phần 2: cấu hình replica set MongoDB
Sau đó mình có nợ lại một phần thứ ba về sharding mongoDB trên cụm nhiều server. Sau 2 năm, mình quay lại để gửi đến các bạn phần cuối cùng để hoàn thiện chuỗi bài viết nhé.
II. NGUYÊN LÝ
1. Sharding là gì?
Sharding là một cơ chế tự động của MongoDB, được thiết kế để phân chia dữ liệu có kích thước lớn thành nhiều phần nhỏ và phân tán trên các máy chủ khác nhau (thường gọi là cluster). Cơ chế này đáp ứng ba mục tiêu chính:
- Đảm bảo tính "trong suốt" với người dùng
MongoDB sử dụng một thành phần đặc biệt gọi là mongos để thực hiện điều này. Mongos đóng vai trò điều phối, định tuyến các yêu cầu đến đúng shard và tổng hợp dữ liệu từ các shard để trả về cho client. Nhờ vậy, người dùng không cần biết về cấu trúc cluster phía sau, mà chỉ cảm nhận được họ đang làm việc với một máy chủ duy nhất. Đây chính là tính "trong suốt" của hệ thống.
- Duy trì tính sẵn sàng cao cho các thao tác đọc/ghi
Cluster phải luôn đảm bảo sẵn sàng hoạt động. Để đạt được điều này, mỗi shard trong cluster sẽ được sao lưu với ít nhất một tiến trình phục vụ dự phòng trên các máy khác nhau.
- Khả năng mở rộng linh hoạt
Cluster được thiết kế để dễ dàng mở rộng. Khi cần thêm dung lượng lưu trữ hoặc tăng hiệu suất, người dùng có thể thêm các node mới mà không gặp khó khăn. Mỗi cluster được quản lý như một node riêng lẻ và cấu hình dễ dàng.
Mongos là yếu tố quan trọng giúp hiện thực hóa những tính năng này, đảm bảo hệ thống hoạt động mượt mà và hiệu quả ngay cả khi quy mô dữ liệu và yêu cầu truy cập tăng cao.
2. Cơ chế của sharding
Sharding trong MongoDB được triển khai thông qua hai cơ chế chính: chia tách dữ liệu và phân tán dữ liệu. Cả hai cơ chế này phối hợp với nhau để đảm bảo dữ liệu được lưu trữ, truy cập, và mở rộng một cách hiệu quả.
2.1 Cơ chế chia tách dữ liệu
MongoDB sử dụng một khái niệm gọi là shard key để quyết định cách chia tách dữ liệu. Shard key là một trường hoặc một tổ hợp các trường trong tài liệu, đóng vai trò như chỉ số để xác định tài liệu đó thuộc shard nào.
Quá trình chia tách dữ liệu diễn ra như sau:
- MongoDB sử dụng shard key để tạo ra các range hoặc hash tương ứng với giá trị của key đó.
- Dựa trên phạm vi hoặc giá trị hash của shard key, dữ liệu được chia tách thành các chunk (khoảng dữ liệu).
- Mỗi chunk sẽ được gán vào một shard trong cluster, đảm bảo dữ liệu được phân bổ đồng đều.
Ví dụ: Nếu shard key là trường
userId
, MongoDB có thể chia dải giá trị userId
thành các khoảng (range) như [1-1000]
, [1001-2000]
,... và gán chúng cho các shard khác nhau.Shard key được thiết kế cẩn thận để tránh các vấn đề như skewed distribution (phân phối không đồng đều), từ đó cải thiện hiệu suất và khả năng mở rộng.
2.2 Cơ chế phân tán dữ liệu
Sau khi dữ liệu được chia tách thành các chunk, MongoDB sẽ sử dụng cơ chế phân tán để lưu trữ chúng trên các shard trong cluster. Quá trình này đảm bảo rằng:
- Dữ liệu được phân bổ đồng đều: Các chunk sẽ được phân tán sao cho không có shard nào bị quá tải. Mongos, thông qua config servers, giám sát trạng thái của các shard và di chuyển chunk nếu cần thiết để cân bằng tải.
- Hỗ trợ thao tác đọc/ghi hiệu quả: Khi nhận được yêu cầu, mongos xác định chính xác shard nào chứa chunk liên quan dựa trên shard key, giúp giảm thời gian truy cập.
Ngoài ra, MongoDB còn hỗ trợ cơ chế split và move chunk để quản lý dữ liệu:
- Split chunk: Khi kích thước một chunk vượt quá ngưỡng cho phép, nó sẽ được chia nhỏ thành các chunk mới để duy trì hiệu suất.
- Move chunk: Khi một shard bị quá tải, MongoDB tự động di chuyển các chunk sang các shard ít tải hơn để cân bằng.
3. Kiến trúc sharding MongoDB
Kiến trúc của Sharding trong MongoDB được thiết kế theo mô hình phân tán với các thành phần chính sau đây:
3.1 Shard
- Mô tả:Mỗi shard là một tập hợp các dữ liệu được lưu trữ trên một hoặc nhiều máy chủ. Shard đảm nhiệm vai trò lưu trữ các chunk (các phần dữ liệu được phân chia dựa trên shard key).
- Đặc điểm:
- Mỗi shard là một cụm cơ sở dữ liệu độc lập, có thể là một replica set để đảm bảo tính sẵn sàng và khả năng chịu lỗi.
- Shards là nơi thực hiện các thao tác lưu trữ và xử lý dữ liệu cục bộ.
3.2 Mongos (Query Router)
- Mô tả:Mongos là thành phần trung gian, đóng vai trò điều phối và định tuyến các truy vấn từ client đến các shard phù hợp.
- Chức năng:
- Nhận yêu cầu từ client và xác định shard nào chứa dữ liệu cần thiết.
- Tổng hợp kết quả từ các shard và trả về kết quả cuối cùng cho client.
- Đảm bảo tính trong suốt, giúp client không cần biết dữ liệu thực sự được lưu trữ ở đâu.
- Đặc điểm:Mongos có thể được triển khai nhiều phiên bản để tăng khả năng chịu tải và đảm bảo hiệu suất khi số lượng truy vấn lớn.
3.3 Config Servers
- Mô tả:Config servers là các máy chủ lưu trữ metadata của cluster. Metadata này bao gồm thông tin về shard key, các range của chunk, và vị trí của các chunk trên các shard.
- Chức năng:
- Cung cấp thông tin cần thiết để mongos định tuyến truy vấn đến đúng shard.
- Quản lý và theo dõi trạng thái của cluster, như việc phân phối chunk giữa các shard.
- Đặc điểm:
- Config servers thường được triển khai dưới dạng một replica set để đảm bảo tính sẵn sàng và toàn vẹn dữ liệu.
3.4 Client
- Mô tả:Client là các ứng dụng hoặc người dùng thực hiện truy vấn tới MongoDB cluster.
- Đặc điểm:
- Client kết nối trực tiếp đến mongos, không cần biết về cấu trúc hay vị trí của dữ liệu trong cluster.
- Truy vấn được gửi đến mongos giống như cách làm việc với một cơ sở dữ liệu đơn lẻ thông thường.
3.5 Cách các thành phần hoạt động cùng nhau
- Client gửi truy vấn đến mongos.
- Mongos sử dụng metadata từ config servers để xác định shard nào cần xử lý yêu cầu.
- Mongos chuyển tiếp truy vấn đến shard tương ứng, lấy dữ liệu (hoặc ghi dữ liệu) từ các shard.
- Nếu cần, mongos sẽ tổng hợp kết quả từ nhiều shard và trả về cho client.
- Balancing
Nếu có nhiều shard đang sẵn sàng và có thêm chứa thêm dữ liệu, MongoDB sẽ tiến hành chuyển dữ liệu từ các shard khác sang để cân bằng tải. Cách thức tiến hành là di chuyển các chunk từ shard này sang shard khác một cách tự động. Balancing cũng có thể bị tắt hoặc bật nếu admin muốn Balancing cũng không được đảm bảo ngay tức thì, chúng ta hãy xem ví dụ dưới đây
III. TẠM KẾT
Vì nội dung cho phần sharding MongoDB khá dài, nên để tiện cho việc theo dõi và truyền tải thông tin cách dễ hiểu, mình xin tạm ngưng phần nguyên lý lý thuyết tại đây, phần thực chiến cũng như kinh nghiệm sẽ được truyền tải trong bài viết tiếp theo.
Hi vọng thông qua lượng kiến thức cơ bản sharding mongoDB bao gồm giới thiệu, cơ chế hoạt động, kiến trúc và cân bằng tải, mọi người có thể tương đối hiểu và chuẩn bị kiến thức để chúng ta bắt tay vào phần thực chiến và kinh nghiệm cá nhân trong việc thiết lập chiến lược sharding trong bài viết sắp tới.
Nếu thấy thú vị và bổ ích, mọi người có thể để lại cho mình 1 like/upvote hoặc comment để đóng góp ý kiến tiếp thêm động lực cho mình viết thêm nhiều nội dung truyền tải kiến thức chất lượng và thú vị hơn trong tương lai.