Thật sự mà nói thì bài này lẽ ra phải lên sóng lâu lắm rồi vì năm xưa đã từng hứa với một đại Idol giấu tên sẽ biên mấy dòng về chủ đề này, “sẽ duyệt bài nhanh cho” anh Hưng giấu tên ân cần nhắn. Sau đó vì nhiều lý do khách quan cũng như chủ quan, cộng với việc tác giả đã xin được hơn mười nghìn Mỹ kim tiền credits cho cả MongoDB Atlas, nên bạn biết đấy, sống đời kham khổ đêm thức khuya ngáp muốn trẹo bản họng ngồi canh traffic lên xuống như canh nước ròng nước lớn để tắt instance rồi sáng dậy sớm bật lên cho tiết kiệm đồng nào hay đồng nấy(*) bỗng dưng được một cục credits tổ chảng rớt cái đùng xuống thì đâu còn động lực để ngồi lọ mọ cài cài cắm cắm config config chi cho cực khổ nữa đâu, cứ xài service cho sướng đời thôi!
Ah, nhưng mà thực tế thì sắp hết credits xài MongoDB Atlas rồi… 😪
Lần đầu viết bài này thì chỉ mới Mongo 6.0, lần này ráng viết tiếp phần kết thì đã có phiên bản 7.0, ôi thời gian nhanh còn hơn chó chạy ngoài đồng.
Poe Assistant viết lại: Trong chặng đường đầu tiên của viết bài này, tôi chỉ mới khởi đầu với phiên bản Mongo 6.0. Nhưng ngay khi tôi cố gắng hoàn thiện phần kết, phiên bản 7.0 đã xuất hiện. Trái tim tôi tràn đầy tiếc nuối khi nhận ra rằng thời gian đã trôi đi nhanh chóng, vượt xa cả sự vụt bước của chó trên đồng cỏ. Tôi hối tiếc vì chưa thể biến những kỳ vọng của mình thành hiện thực.
aws ec2 stop-instances
cùng với Task Scheduler.Mặc dù AWS đã hỗ trợ NoSQL với 2 dịch vụ là DynamoDB và DocumentDB, trong đó DynamoDB là cơ sở dữ liệu dạng key-value, còn DocumentDB thì cùng một nền tảng với MongoDB. Tuy nhiên, nếu như bạn chỉ muốn đơn giản sử dụng MongoDB trên hạ tầng của AWS để tận dụng sức mạnh mà không cần phải tốn nhiều công sức migration source-code hiện tại thì giải pháp tự cài đặt được trình bày ở bên dưới sẽ rất phù hợp với nhu cầu của bạn.
Từ màn hình AWS Console > EC2 > Instances, chọn Launch instances với các tùy chọn sau.
Sau khi đã khởi tạo xong instance ở trạng thái Running, dùng SSH client nào đó hoặc EC2 Instance Connect để kết nối vào instance vừa được tạo.
Gõ lệnh sau để tạo file mongodb-org-7.0.repo và thêm vào đoạn cấu hình bên dưới để ta có thể cài đặt MongoDB bằng yum. Có thể dùng vi hay nano để tạo/ edit file này đều được.
sudo nano /etc/yum.repos.d/mongodb-org-7.0.repo
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2023/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc
Chạy lệnh sau để cài đặt MongoDB sudo yum install -y mongodb-org
Sau khi thấy terminal hiện ra Complete! thì chạy tiếp lệnh mongod --version
để kiểm tra xem phiên bản MongoDB được cài đặt thành công.
Tiếp đến, chạy lệnh sudo systemctl start mongod
để khởi động các dịch vụ của MongoDB. Xong thì chạy tiếp sudo systemctl status mongod
để kiểm tra trạng thái dịch vụ.
Vẫn trên terminal, chạy lệnh mongosh
để tiến hành tạo DB, user, insert dữ liệu vào collection customer, đọc dữ liệu vừa instert.
use myDB
db.createUser({user: "admin", pwd: "admin", roles:[{role:"dbAdmin", db: "myDB"}]})
db.customer.insert({name: "Viet-AWS"})
db.customer.find()
Gõ exit()
để thoát khỏi mongosh.
Thật không may, ở phiên bản 7.0 này thì ngay khi chạy lên mongosh
là gặp lỗi liền
mongosh: OpenSSL configuration error: 00698192257F0000:error:030000A9:digital envelope routines:alg_module_init:unknown option:../deps/openssl/openssl/crypto/evp/evp_cnf.c:61:name=rh-allow-sha1-signatures, value=yes
Để xử lý, chúng ta sẽ chạy 3 lệnh thần thánh bên dưới:
sudo yum remove mongodb-mongosh
sudo yum install mongodb-mongosh-shared-openssl3
sudo yum install mongodb-mongosh
Mặc định, nếu cài từ package như trên thì chúng ta sẽ có 2 thư mục.
/var/lib/mongo
/var/log/mongodb
Trường hợp bạn cần sử dụng các client tool như kiểu MongoDB Compass hay NoSQLBooster hoặc application kết nối MongoDB của bạn đang nằm ở một nơi khác AWS thì đây là những thứ cần phải làm:
sudo nano /etc/mongod.conf
, tìm đến đoạn #network interface và cập nhật bindIp thành 0.0.0.0. Sau đó lưu file và chạy lệnh sudo systemctl restart mongod
để khởi động lại MongoDB với cấu hình mới.Vậy là xong, bạn có thể thay đổi connection string trong ứng dụng của mình để chuyển sang dùng MongoDB trên hạ tầng AWS.
Để triển khai hệ thống MongoDB trên môi trường production thì gần như bắt buộc phải có cơ chế replica set để đảm bảo:
Tính năng này có trên các phiên bản MongoDB Atlas/ Enterprise/ Community.
Một replica set tiêu chuẩn cơ bản sẽ gồm có 3 node (có thể hiểu là thành viên), trong đó có 1 node làm nhiệm vụ voting (trọng tài điều phối khi có sự cố xảy ra), 1 node là node chính, các node còn lại sẽ là node phụ. Tối đa 7 voting, số còn lại sẽ là non-voting node và lên đến 50 node.
Một replica set tiêu chuẩn cơ bản
Các noode phu sẽ chép dữ liệu oplog của node chính để đồng bộ hóa. Khi có sự cố xảy ra với node chính, một trong các node phụ sẽ “làm trọng tài” để bầu ra một node chính khác thay thế.
Vẫn có trường hợp voting node chỉ làm trọng tài, không chứa dữ liệu.
Nói chung, phần này khá hay nhưng hơi lằng nhằng, cần phải request thêm nhiều task research trước khi nhào vô. Bạn đọc quan tâm có thể coi kỹ hình minh họa và giải thích rất chi tiết về Repication tại https://www.mongodb.com/docs/manual/replication/
Khả năng chịu lỗi
Số lượng node | Số node cần để bầu node chính | Khả năng chịu lỗi |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
Các patterns hãng khuyên dùng:
Theo chiến lược ở trên, chúng ta sẽ cần có 3 instance, ở phần đầu Cài đặt Standalone trên EC2 Instance chúng ta đã có 1 instance, bạn có thể tiếp tục lặp lại các bước trên để cài 2 instance. Hoặc để nhanh hơn thì bạn cứ tạo AMI Image từ instance hiện tại rồi sau đó Launch Instance from AMI vừa tạo là được.
Sau khi đã chuẩn bị xong 3 instance, tạm gọi là mongo1, mongo2, mongo3.
Ở instance mongo1, bạn chạy sudo nano /etc/mongod.conf
rồi tìm đến dòng # network interfaces, tiến hành thay đổi như sau:
# network interfaces
net:
port: 27021
bindIp: 127.0.0.1,ip-x-x-x-x.ap-regionname.compute.internal
replication:
replSetName: "dbrs"
Trong đó
port: 27021
chỉ định port mặc định MongoDBbindIp: 127.0.0.1,ip-x-x-x-x.ap-regionname.compute.internal
đoạn ở sau dấu phẩy là Private IP DNS name (IPv4 only).replSetName: "dbrs"
chỉ định tên của replicate setSau khi đã cấu hình xong thì chạy sudo systemctl restart mongod
để khởi động lại MongoDB với cấu hình mới.
Thực hiện tương tự cho các instance mongo2, mongo3, bạn có thể thay đổi giá trị port thành 27022, 27023 để dễ nhận dạng. Chú ý replSetName thì phải cùng một tên.
Sau khi thực hiện xong toàn bộ 3 instance, để test xem đã thông port chưa thì ta có thể dùng Netcat. Mặc định trên Amazon Linux không có package này, cần phải cài thêm bằng lệnh sudo yum install -y nc
, nếu có package nào mặc định cũng ngon thì nhờ bà con chỉ giùm tui nghen.
nc -zv ip-x-x-x-x.ap-regionname.compute.internal 27021
nc -zv ip-x-x-x-x.ap-regionname.compute.internal 27022
nc -zv ip-x-x-x-x.ap-regionname.compute.internal 27023
Quay lại mongo1, chạy mongo shell, lúc này port mặc định đã thay đổi thành 27021 nên cần phải thêm agrument —port chứ không sẽ bị báo lỗi như hình.
mongosh --port 27021
Gõ đoạn này vào mongo shell.
rsconf = {
_id: "dbrs",
members: [
{ _id: 0, host: "ip-x-x-x-x.ap-regionname.compute.internal:27021" },
{ _id: 1, host: "ip-x-x-x-x.ap-regionname.compute.internal:27022" },
{ _id: 2, host: "ip-x-x-x-x.ap-regionname.compute.internal:27023" }
]
}
Gõ xong thì gõ tiếp rồi Enter: rs.initiate(rsconf);
Nếu mọi chuyện xuôi chèo mát mái thì lúc này command line sẽ chuyển thành dbrs [direct: secondary] test>
Bạn có thể kiểm tra tình trạng replicate set bằng lệnh rs.status()
Để ý, lúc này command line đã chuyển thành dbrs [direct: primary] test>
. Điều này có nghĩa là voting node đã chọn node này làm node chính.
Thật tuyệt, bây giờ bạn có thể sang mongo2 hoặc mongo3 hay đứng ngay tại mongo1 và kết nối vào replicate set bằng lệnh
mongosh --host dbrs/mongo1-privateIPDNSname:27021,mongo2-privateIPDNSname:27022,mongo3-privateIPDNSname:27023
Thử nghiệm một chút
use myDB
db.customer.insert({name: "ThoCode"})
db.customer.find()
Còn khá nhiều thứ cần phải tiếp tục thực hiện để hệ thống an toàn hơn thí dụ cấu hình keyfile authentication hoặc sử dụng x.509 certificates cho việc authentication vì nếu không thì bất kỳ ai có quyền truy cập vào các instance này đều có thể đơn giản truy cập vào mongo shell.
Cảm ơn sự trợ giúp của Poe Assistant đã góp ý một vài chỗ ở bản nháp, cũng như là Adobe Firefly đã vẽ giùm ảnh minh họa cover theo prompt mà tôi chả hiểu gì cả.
color photo of a MongoDB replica set mechanism consisting of 3 nodes
Anh Dũng, Sài Gòn tháng 10-2023.