+5

Nắm tay chỉ cài đặt MongoDB trên hạ tầng của AWS, đảm bảo đầy đủ tính high availability

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.

MongoDB on AWS: Cài đặt Standalone trên EC2 Instance

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.

1. Tạo EC2 Instance

Từ màn hình AWS Console > EC2 > Instances, chọn Launch instances với các tùy chọn sau.

  • Name: Tên instance.
  • Application and OS Images (Amazon Machine Image): Amazon Linux 2 AMI (Free tier**)**. Hiện tại đã có phiên bản Amazon Linux 2023, tuy nhiên qua test thử thì việc cài đặt các package liên quan đến MongoDB vẫn còn khá phức tạp cũng như là phía MongoDB.com họ thông báo chưa hỗ trợ. Cập nhật tại thời điểm tháng 10/2023: MongoDB đã hỗ trợ Amazon Linux 2023 https://www.mongodb.com/docs/manual/installation/#supported-platforms.
  • Instance type: t2.micro (Free tier). Hãy chú ý nếu như không muốn tốn tiền oan! 😂
  • Key pair (login): Chọn key pair sẵn có của bạn hoặc tạo mới tùy.
  • Network settings: Nhớ chú ý việc Allow SSH traffic from Anywhere để có thể SSH vào instance.

2. Cài đặt MongoDB

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

Untitled.png

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ụ.

Untitled.png

3. Cấu hình & thử nghiệm

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()

Untitled.png

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.

  • Dữ liệu /var/lib/mongo
  • Logs /var/log/mongodb

4. Mở đường ra Internet

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:

  • Vì MongoDB listen port 27017, nên ta cần phải allow port này để có thể kết nối từ bên ngoài.
  • Mở Security Groups của instance vừa tạo và Edit inbound rules, rồi add như minh họa hoặc chỉ với địa chỉ IP mà ta muốn cho phép để đảm bảo an toàn.

Untitled.png

  • Cập nhật lại cấu hình MongoDB: 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.

Untitled.png

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.

Untitled.png

MongoDB on AWS: Thiết lập Replica

Để 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:

  1. Dự phòng và độ tin cậy cao: Replica set cho phép sao lưu dữ liệu và duy trì sự nhất quán giữa các bản sao dữ liệu trên các thành viên của replica set. Khi một thành viên gặp sự cố hoặc bị ngắt kết nối, hệ thống vẫn tiếp tục hoạt động bình thường và người dùng vẫn có thể truy cập vào dữ liệu từ các thành viên khác trong replica set.
  2. Tăng cường hiệu suất đọc: Replica set cho phép phân tán yêu cầu đọc dữ liệu qua các thành viên của replica set. Điều này giúp tăng cường khả năng chịu tải và cung cấp khả năng đáp ứng tốt hơn cho các hoạt động đọc dữ liệu.
  3. Khả năng mở rộng: Replica set cung cấp khả năng mở rộng dễ dàng bằng cách thêm các thành viên mới vào replica set. Khi lưu lượng truy cập tăng, bạn có thể thêm các thành viên mới để phân tán công việc và tăng cường khả năng xử lý.
  4. Khả năng phục hồi dữ liệu: Khi có sự cố xảy ra và một thành viên trong replica set bị mất, replica set có khả năng tự động chuyển đổi sang các thành viên khác để tiếp tục hoạt động. Quá trình này được gọi là quá trình bầu cử (election), và nó đảm bảo rằng hệ thống vẫn có thể truy cập và sử dụng dữ liệu mà không bị gián đoạn.
  5. Sao lưu và khôi phục dữ liệu: Replica set cung cấp khả năng sao lưu dữ liệu dựa trên các bản sao dữ liệu trên các thành viên của replica set. Điều này giúp đảm bảo an toàn dữ liệu và khả năng khôi phục dữ liệu khi cần thiết.

Tính năng này có trên các phiên bản MongoDB Atlas/ Enterprise/ Community.

Chiến lược

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

Untitled.png

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ế.

Untitled.png

Vẫn có trường hợp voting node chỉ làm trọng tài, không chứa dữ liệu. Untitled.png

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:

Cấu hình

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.

Untitled.png

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 MongoDB
  • bindIp: 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 set

Sau 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

Khởi động replicate set

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

Untitled.png

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);

Untitled.png

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()

Untitled.png

Để ý, 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()

Kết

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

The photo captures the intricate details of the replica set configuration, showcasing the interplay between the nodes. Each node is depicted with precision, highlighting their distinct roles within the replica set.

The environment exudes a sense of stability and reliability, with the nodes positioned securely in a well-organized server room. The scene is illuminated by soft, ambient lighting, casting a calm and focused atmosphere.

The camera captures the replica set with precision and clarity, showcasing the intricate details of the hardware. The specific camera model used is a high-resolution digital camera, capable of capturing fine details.

The color film type selected for this photo is a vibrant and dynamic option, enhancing the visual appeal of the replica set. The lens used is a wide-angle lens, enabling a comprehensive view of the nodes and emphasizing their significance.

In this unique collaboration, the photo captures the essence of the replica set mechanism, combining the creative vision of renowned directors such as Christopher Nolan, the expert cinematography of Roger Deakins, the keen eye of photographer Annie Leibovitz, and the innovative designs of fashion icon Alexander McQueen.

—c 10 —ar 2:3

Firefly The photo captures the intricate details of the replica set configuration, showcasing the in.jpg

Anh Dũng, Sài Gòn tháng 10-2023.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí