Replication, hay còn được biết đến với tên gọi đồng bộ hóa, là một tính năng không thể thiếu trong quản lý cơ sở dữ liệu, đặc biệt là trong MongoDB, một hệ quản trị cơ sở dữ liệu NoSQL phổ biến với khả năng mở rộng và linh hoạt cao. Đồng bộ hóa trong MongoDB được thực hiện thông qua cơ chế Replica Set, bao gồm một nhóm các server lưu trữ dữ liệu giống hệt nhau. Mục đích chính của replication là đảm bảo tính sẵn sàng và độ tin cậy của dữ liệu: nếu một server gặp sự cố, hệ thống có thể tự động chuyển đổi sang server khác mà không làm gián đoạn hoạt động của ứng dụng. Điều này không chỉ giúp tăng cường bảo mật dữ liệu trước các sự cố phần cứng hoặc mạng mà còn hỗ trợ cải thiện hiệu suất đọc dữ liệu bằng cách phân tải truy vấn đến nhiều server. Trong môi trường sản xuất, replication trở thành một yếu tố quan trọng giúp đảm bảo rằng dữ liệu luôn được cập nhật và sẵn sàng khi cần thiết, qua đó hỗ trợ doanh nghiệp duy trì hoạt động liên tục và ổn định.
Replication trong MongoDB
Trong MongoDB, cơ chế replication được triển khai thông qua Replica Set, một nhóm các server lưu trữ dữ liệu giống hệt nhau, đảm bảo tính sẵn sàng và độ tin cậy cao cho dữ liệu. Một Replica Set bao gồm các nodes, trong đó có một Primary node chịu trách nhiệm nhận tất cả các ghi dữ liệu, còn các Secondary nodes sẽ sao chép dữ liệu từ Primary node để đảm bảo dữ liệu luôn được đồng bộ. Vai trò của các nodes này không cố định: một Secondary node có thể trở thành Primary thông qua quá trình bầu chọn (election process) nếu Primary hiện tại gặp sự cố hoặc không khả dụng.
Quá trình bầu chọn Primary node là một phần quan trọng trong cơ chế hoạt động của Replica Set. Khi một Primary node không còn khả dụng do sự cố mạng, hỏng hóc phần cứng, hoặc bất kỳ lý do nào khác, các Secondary nodes sẽ tự động bắt đầu quá trình bầu chọn để chọn ra một node mới làm Primary. Quá trình này dựa trên một số tiêu chí như: độ trễ của dữ liệu, số phiên bản dữ liệu, và khả năng truy cập của node. Điều này đảm bảo rằng dữ liệu luôn có sẵn và ứng dụng có thể tiếp tục hoạt động mà không bị gián đoạn, ngay cả khi có sự cố xảy ra với Primary node.
Cách thiết lập Replica Set
Thiết lập một Replica Set trong MongoDB bắt đầu với việc cài đặt và cấu hình các instance MongoDB trên các máy chủ, sau đó khai báo chúng là một phần của cùng một Replica Set. Bước đầu tiên quan trọng nhất là khởi tạo Replica Set bằng cách sử dụng câu lệnh rs.initiate()
trên một trong các node, điều này sẽ biến node đó thành Primary node tạm thời và khởi động quá trình sao chép dữ liệu tới các Secondary nodes. Trong quá trình cấu hình, các tùy chọn quan trọng cần được xem xét bao gồm: tên của Replica Set, cấu hình file định tuyến dữ liệu, và thiết lập ưu tiên cho các nodes để ảnh hưởng đến quá trình bầu chọn Primary node.
Để thêm một node mới vào Replica Set, người quản trị cần sử dụng câu lệnh rs.add()
và cung cấp địa chỉ của node mới. MongoDB sẽ tự động bắt đầu quá trình sao chép dữ liệu từ Primary hiện tại tới node mới, đồng thời đồng bộ hóa cấu hình Replica Set để bao gồm node mới này. Ngược lại, để loại bỏ một node, có thể sử dụng câu lệnh rs.remove()
, điều này sẽ ngăn node đó tiếp tục nhận dữ liệu sao chép và loại bỏ nó khỏi cấu hình Replica Set. Quản lý chính xác các thành viên trong Replica Set không chỉ đảm bảo tính sẵn sàng và độ tin cậy của dữ liệu mà còn giúp cân bằng tải và tối ưu hóa hiệu suất truy cập dữ liệu trong môi trường phân tán.
Đồng bộ hóa Dữ liệu và Heartbeats
Trong MongoDB, đồng bộ hóa dữ liệu giữa các nodes trong Replica Set được thực hiện thông qua một quá trình gọi là sao chép dữ liệu (replication). Khi dữ liệu được ghi vào Primary node, các thay đổi đó được ghi lại trong một cấu trúc dữ liệu được gọi là oplog (operation log). Oplog này lưu trữ tất cả các thao tác ghi dữ liệu dưới dạng một chuỗi các bản ghi, giúp các Secondary nodes có thể theo dõi và sao chép các thay đổi từ Primary node một cách tuần tự. Các Secondary nodes liên tục đọc oplog từ Primary và áp dụng các thay đổi này vào bản sao dữ liệu của chính mình, đảm bảo rằng tất cả các nodes giữ dữ liệu nhất quán và cập nhật.
Heartbeats đóng một vai trò quan trọng trong việc duy trì sự ổn định và tính khả dụng của Replica Set. Heartbeats là những tín hiệu “sống” được gửi giữa các nodes trong Replica Set mỗi vài giây một lần để kiểm tra tình trạng sức khỏe và khả năng kết nối giữa chúng. Nếu một node không phản hồi tới các heartbeats trong một khoảng thời gian nhất định, nó sẽ được coi là không khả dụng, và quá trình bầu chọn Primary mới có thể được khởi xướng nếu node bị mất kết nối là Primary hiện tại. Quá trình này giúp đảm bảo rằng dữ liệu luôn sẵn sàng và khả dụng ngay cả khi một hoặc nhiều nodes gặp sự cố, từ đó tối ưu hóa độ tin cậy và khả năng phục hồi của hệ thống trong trường hợp xảy ra lỗi.
Failover và Recovery
Failover là một quá trình tự động xảy ra trong MongoDB khi Primary node của một Replica Set gặp sự cố và không còn khả dụng. Quy trình này bắt đầu với việc các Secondary nodes nhận thức được sự mất mát của Primary thông qua cơ chế heartbeats, những tín hiệu kiểm tra sức khỏe được gửi định kỳ giữa các nodes. Khi một Secondary node nhận ra rằng nó không nhận được phản hồi từ Primary node sau một khoảng thời gian nhất định, nó sẽ khởi xướng quá trình bầu chọn mới để chọn một Primary node mới từ số Secondary nodes còn lại. Quá trình bầu chọn dựa trên một số tiêu chí như độ trễ của dữ liệu, ưu tiên được cấu hình cho từng node, và thời gian hoạt động. Node nào đáp ứng đủ điều kiện và nhận được đa số phiếu bầu sẽ trở thành Primary node mới, cho phép hệ thống tiếp tục hoạt động mà không bị gián đoạn đáng kể.
Trong quá trình recovery sau sự cố, việc tái thiết lập Replica Set và đảm bảo dữ liệu đồng bộ giữa các nodes trở nên quan trọng. Khi một node mới được bổ nhiệm làm Primary, các Secondary nodes sẽ tự động bắt đầu quá trình sao chép dữ liệu từ Primary mới để cập nhật bất kỳ thay đổi nào mà chúng có thể đã bỏ lỡ trong thời gian failover. Điều này đảm bảo rằng tất cả các nodes trong Replica Set đều giữ dữ liệu nhất quán và cập nhật. Nếu node gặp sự cố trước đó có thể được phục hồi, nó có thể được thêm trở lại vào Replica Set như một Secondary node và sau đó đồng bộ hóa dữ liệu từ Primary node hiện tại. Quá trình này giúp duy trì tính toàn vẹn và sẵn sàng của dữ liệu trong toàn bộ hệ thống, đồng thời đảm bảo rằng MongoDB có thể phục hồi một cách nhanh chóng và hiệu quả sau các sự cố không lường trước được.
Các phương thức của Replication trong MongoDB
rs.add(host, arbiterOnly)
Phương thức add sẽ thêm một thành viên vào nhóm bản sao được chỉ định. Chúng tôi được yêu cầu kết nối với tập hợp chính của tập hợp bản sao cho phương pháp này. Kết nối với trình bao sẽ bị chấm dứt nếu phương thức sẽ kích hoạt một cuộc bầu cử sơ bộ. Ví dụ – nếu chúng tôi cố gắng thêm một thành viên mới có mức độ ưu tiên cao hơn thành viên chính. Lỗi sẽ được phản ánh bởi trình bao mongo ngay cả khi thao tác thành công.
Ví dụ:
Trong ví dụ sau, chúng tôi sẽ thêm một secondary member với phiếu bầu mặc định.
rs.add( { host: "mongodbd4.example.net:27017" } )
Tên máy chủ
rs.add( "mongodbd4.example.net:27017" )
rs.addArb(host)
Chúng tôi có thể thêm một host mới vào một bản sao hiện có được đặt tại máy chủ lưu trữ được chỉ định.
Ví dụ
mongod --bind_ip localhost,My-Example-<Associated-Hostname>
Nếu bạn muốn kết nối với phiên bản này, tên máy chủ hoặc địa chỉ IP liên kết 198.52.100.2 của nó phải được chỉ định bởi máy khách từ xa:
mongo --host My-Example-<Associated-Hostname> mongo --host 198.52.100.2
rs.conf ()
Phương thức conf được sử dụng để lấy một tài liệu có chứa cấu hình của tập bản sao hiện tại.
Rs.conf () kết thúc cấu hình lệnh replSetGetConfig.
Ví dụ
Tập lệnh sau hiển thị tài liệu cấu hình của một tập hợp bản sao bao gồm tập hợp con của các cài đặt này:
{ _id: <string>, version: <int>, protocolVersion: <number>, writeConcernMajorityJournalDefault: <boolean>, configsvr: <boolean>, members: [ { _id: <int>, host: <string>, arbiterOnly: <boolean>, buildIndexes: <boolean>, hidden: <boolean>, priority: <number>, tags: <document>, slaveDelay: <int>, votes: <number> }, ], settings: { chainingAllowed : <boolean>, heartbeatIntervalMillis : <int>, heartbeatTimeoutSecs: <int>, electionTimeoutMillis : <int>, catchUpTimeoutMillis : <int>, getLastErrorModes : <document>, getLastErrorDefaults : <document>, replicaSetId: <ObjectId> } }
rs.initiate(configuration)
Phương thức khởi tạo một tập hợp bản sao. Phương pháp này có thể coi một tài liệu chứa cấu hình rs.initiate () của một tập hợp bản sao, nhưng đó là tùy chọn.
Ví dụ
Ví dụ sau đây khởi tạo một tập hợp bản sao mới với ba thành viên khác nhau.
{ _id: "JTPReplSet", version: 1, members: [ { _id: 0, host : "mongodb0.example.net:27017" }, { _id: 1, host : "mongodb1.example.net:27017" }, { _id: 2, host : "mongodb2.example.net:27017" } ] }
rs.reconfig(configuration, force)
Như tên cho thấy, phương pháp được sử dụng để cấu hình lại một tập hợp bản sao hiện có. Nó sẽ ghi đè lên tất cả cấu hình bộ bản sao hiện có. Chúng ta phải kết nối với bộ bản sao chính để chạy phương thức này.
Các ví dụ
Một tập hợp bản sao có tên rs0 có cấu hình sau:
{ "_id" : "rs0", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "mongodb0.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "mongodb1.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "mongodb2.example.net:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("58858acc1f5609ed986b641b") } }
Bảo mật trong Replica Set
Trong quá trình replication, việc bảo mật dữ liệu giữa các nodes trong Replica Set của MongoDB là một ưu tiên hàng đầu, đòi hỏi các biện pháp bảo mật cụ thể để ngăn chặn truy cập không được phép và bảo vệ dữ liệu khỏi các mối đe dọa tiềm tàng. Một trong những cách hiệu quả nhất để đạt được điều này là thông qua việc sử dụng xác thực và mã hóa. Xác thực đảm bảo rằng chỉ những nodes đã được ủy quyền mới có thể tham gia vào Replica Set và trao đổi dữ liệu. MongoDB hỗ trợ nhiều cơ chế xác thực, bao gồm xác thực dựa trên chứng chỉ X.509, SCRAM (Salted Challenge Response Authentication Mechanism), và Kerberos, giúp quản trị viên có thể chọn phương pháp phù hợp nhất với môi trường và yêu cầu bảo mật của họ.
Mã hóa cũng là một phần quan trọng trong việc bảo vệ dữ liệu trong quá trình replication. Mã hóa dữ liệu “trên đường” (in-transit) sử dụng các kỹ thuật mã hóa như TLS/SSL để bảo vệ dữ liệu khi nó được truyền từ node này sang node khác, ngăn chặn việc nghe trộm và tấn công man-in-the-middle. Ngoài ra, mã hóa dữ liệu “tại chỗ” (at-rest) giúp bảo vệ dữ liệu trên đĩa, đảm bảo rằng dữ liệu vẫn an toàn ngay cả khi hệ thống bị xâm nhập. Việc kết hợp cả xác thực và mã hóa trong quá trình replication giúp tạo ra một lớp bảo vệ vững chắc, đảm bảo rằng dữ liệu quan trọng luôn được bảo vệ một cách hiệu quả, ngay cả trong môi trường phân tán và đa node như trong MongoDB.