Docker là một nền tảng giúp cho việc triển khai và quản lý ứng dụng trên các container. Các container là một cách để đóng gói một ứng dụng cùng với tất cả các phụ thuộc của nó (thư viện, hệ điều hành, file cấu hình, v.v.) trong một môi trường độc lập và có thể di động. Việc sử dụng Docker giúp cho việc triển khai ứng dụng trở nên đơn giản hơn, giảm thiểu sự phụ thuộc vào các thư viện và hệ điều hành, giảm thời gian triển khai, cũng như giúp tăng tính di động và linh hoạt cho ứng dụng.
MongoDB trên Docker là việc triển khai MongoDB trong một container Docker. MongoDB là một cơ sở dữ liệu phi quan hệ (NoSQL) phổ biến, được sử dụng rộng rãi cho các ứng dụng web và di động. Việc triển khai MongoDB trên Docker giúp cho việc cài đặt và triển khai MongoDB trở nên dễ dàng hơn, vì bạn không cần phải cài đặt MongoDB trực tiếp trên hệ thống mà bạn đang sử dụng. Thay vào đó, bạn có thể sử dụng Docker để tạo ra một container MongoDB độc lập, với tất cả các phụ thuộc và cấu hình cần thiết, và triển khai container đó trên bất kỳ hệ thống nào hỗ trợ Docker.
Trong một replica set MongoDB, để đảm bảo rằng dữ liệu được bảo toàn và không bị mất đi, bạn cần đặt số lượng thành viên (members) phù hợp và có đủ số lượng các thành viên đồng nhất (members in sync) để có thể chịu được một số sự cố nhất định.
Cụ thể, nếu replica set có n thành viên và bạn muốn đảm bảo rằng dữ liệu được bảo toàn nếu một số sự cố xảy ra, bạn có thể sử dụng công thức:
- Nếu n là số lẻ, bạn có thể chịu được (n-1)/2 sự cố.
- Nếu n là số chẵn, bạn có thể chịu được n/2 sự cố.
Ví dụ, trong cấu hình trên, chúng ta có 3 thành viên trong replica set, vậy nếu một node bị chết, replica set vẫn có thể hoạt động và đảm bảo dữ liệu được bảo toàn. Tuy nhiên, nếu hai node bị chết, replica set sẽ không còn đủ số lượng thành viên để đảm bảo dữ liệu được bảo toàn. Vì vậy, để đảm bảo an toàn và bảo mật dữ liệu, bạn cần đặt số lượng thành viên phù hợp cho replica set của mình.
Đây là một ví dụ về docker-compose.yml
file để cài đặt MongoDB cluster với 3 node sử dụng MongoDB version 4.4:
version: '3'
services:
mongo1:
image: mongo:4.4
container_name: mongo1
restart: always
ports:
- 27017:27017
volumes:
- ./data/mongo1:/data/db
command: mongod --replSet rs0 --bind_ip localhost,mongo1 --port 27017
mongo2:
image: mongo:4.4
container_name: mongo2
restart: always
ports:
- 27018:27017
volumes:
- ./data/mongo2:/data/db
command: mongod --replSet rs0 --bind_ip localhost,mongo2 --port 27017
mongo3:
image: mongo:4.4
container_name: mongo3
restart: always
ports:
- 27019:27017
volumes:
- ./data/mongo3:/data/db
command: mongod --replSet rs0 --bind_ip localhost,mongo3 --port 27017
Mô tả các trường quan trọng trong file docker-compose.yml
:
version: '3'
: phiên bản của Docker Compose.services
: danh sách các dịch vụ cần thiết để triển khai MongoDB cluster.mongo1
,mongo2
,mongo3
: tên của các container sử dụng MongoDB image.image: mongo:4.4
: phiên bản của MongoDB image.container_name
: tên của container.restart: always
: container tự động khởi động lại nếu bị tắt.ports
: sử dụng các port khác nhau để truy cập vào các container.volumes
: mount thư mục lưu trữ dữ liệu trên host và container.command
: thực thi lệnh để khởi tạo MongoDB replica set với 3 nodes.
Với các tham số được định nghĩa như trên, bạn có thể khởi động MongoDB cluster với lệnh:
docker-compose up -d
Sau khi các container được khởi động thành công bạn có thể kiểm tra các port của MongoDB đã hoạt động chưa:
$ netstat -tlnp | grep 2701
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 14289/docker-proxy
tcp 0 0 0.0.0.0:27018 0.0.0.0:* LISTEN 13483/docker-proxy
tcp 0 0 0.0.0.0:27019 0.0.0.0:* LISTEN 9640/docker-proxy
tcp6 0 0 :::27017 :::* LISTEN 14295/docker-proxy
tcp6 0 0 :::27018 :::* LISTEN 13490/docker-proxy
tcp6 0 0 :::27019 :::* LISTEN 9647/docker-proxy
Bạn có thể truy cập vào MongoDB shell trong container mongo1 bằng cách chạy lệnh:
docker exec -it mongo1 mongo
Sau đó, bạn có thể tạo replica set bằng cách chạy các lệnh sau:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
Cấu hình trên đang sử dụng một replica set (RS) với tên là “rs0” và gồm 3 thành viên, mỗi thành viên được định danh bằng trường “_id” và được đặt tên theo tên của các container Docker, bao gồm:
- mongo1:27017
- mongo2:27017
- mongo3:27017
Có thể thấy rằng, trong một replica set MongoDB, các thành viên có thể đóng vai trò khác nhau, bao gồm:
- Primary: replica set luôn có một primary, đây là thành viên chịu trách nhiệm xử lý các yêu cầu ghi dữ liệu từ ứng dụng và đồng bộ dữ liệu với các secondary member.
- Secondary: các thành viên secondary đồng bộ dữ liệu với primary và cung cấp khả năng đọc dữ liệu cho ứng dụng. Nếu primary gặp sự cố, một secondary sẽ được bầu làm primary để tiếp tục xử lý các yêu cầu ghi dữ liệu.
- Arbiter: arbiter là một thành viên đặc biệt, không lưu trữ dữ liệu, chỉ đóng vai trò trong quá trình bầu chọn primary khi có sự cố xảy ra.
Trong cấu hình trên, chúng ta không xác định rõ ràng vai trò của từng thành viên, vì vậy khi chạy lệnh trên, replica set sẽ tự động quyết định vai trò của các thành viên dựa trên cấu hình và trạng thái hiện tại của replica set.
Lưu ý: việc triển khai MongoDB replica set trong Docker là một chủ đề phức tạp và có nhiều yếu tố để xem xét như tài nguyên máy tính, bảo mật và hiệu suất. Để triển khai một MongoDB cluster cho môi trường sản xuất, bạn cần phải xem xét các yếu tố như:
- Bảo mật: đảm bảo an toàn và bảo mật dữ liệu trong cluster.
- Hiệu suất: đảm bảo rằng MongoDB cluster hoạt động hiệu quả và đáp ứng nhu cầu sử dụng của ứng dụng.
- Khả năng mở rộng: đảm bảo rằng MongoDB cluster có thể mở rộng theo nhu cầu tăng trưởng của ứng dụng.
- Sao lưu và phục hồi: đảm bảo rằng MongoDB cluster có khả năng sao lưu và phục hồi dữ liệu nhanh chóng và dễ dàng.
Để triển khai một MongoDB cluster cho môi trường sản xuất, bạn cần xem xét sử dụng các công cụ và giải pháp chuyên nghiệp hơn như MongoDB Ops Manager, MongoDB Atlas hoặc các giải pháp tương tự. Các giải pháp này cung cấp nhiều tính năng hơn cho việc quản lý, giám sát, tối ưu hóa hiệu suất, bảo mật và sao lưu và phục hồi dữ liệu cho MongoDB cluster.
Dưới đây là một số câu lệnh để kiểm tra trạng thái và hoạt động của MongoDB Cluster:
- Kiểm tra trạng thái của các node trong replica set:
$ mongo
> rs.status()
Kết quả sẽ hiển thị trạng thái hiện tại của replica set, bao gồm thông tin về các node, thông tin về chức danh (primary, secondary, arbiter) và trạng thái của từng node.
- Thực hiện một số yêu cầu ghi và đọc dữ liệu:
$ mongo
> use your_database
> db.your_collection.insertOne({"name": "hoanghd"})
> db.your_collection.find({"name": "hoanghd"})
Lệnh insertOne
sẽ chèn một bản ghi mới vào trong collection, và lệnh find
sẽ tìm kiếm và trả về tất cả các bản ghi có trường “name” là “John Doe”. Bạn cũng có thể sử dụng các lệnh khác để thực hiện các yêu cầu khác.
- Tắt một số node và kiểm tra trạng thái của replica set:
- Tắt node bằng cách dừng quá trình MongoDB trên node đó.
- Kiểm tra trạng thái của replica set bằng cách sử dụng lệnh
rs.status()
như trên. Trong kết quả, node bị tắt sẽ được đánh dấu là “down”.
- Thêm mới các node vào replica set:
- Thêm mới các node bằng cách chạy các container mới với cấu hình tương ứng.
- Kiểm tra trạng thái của replica set bằng cách sử dụng lệnh
rs.status()
như trên. Trong kết quả, node mới sẽ được đánh dấu là “startup”.
Lỗi thường gặp với các bạn mới là “not master”, lỗi “not master” xuất hiện khi bạn cố gắng thực hiện một yêu cầu ghi (write operation) trên một node không phải là primary trong replica set của MongoDB.
Khi một replica set có nhiều hơn một node, chỉ có node primary mới cho phép thực hiện các yêu cầu ghi vào cơ sở dữ liệu. Các node secondary chỉ được sử dụng để đọc dữ liệu và sao chép dữ liệu từ primary. Khi primary node gặp lỗi, nó sẽ được thay thế bằng một node secondary, và node mới này sẽ trở thành primary để cho phép thực hiện các yêu cầu ghi.
Trong quá trình kiểm tra và vận hành MongoDB Cluster, bạn cần theo dõi các thông tin và logs từ các node trong replica set để phát hiện và giải quyết các vấn đề kịp thời.