Việc ngừng sản xuất gần như được đảm bảo sẽ xảy ra vào một số thời điểm. Chấp nhận thực tế này và phân tích tiến trình và kịch bản thất bại của việc cơ sở dữ liệu của bạn ngừng hoạt động có thể giúp chuẩn bị, chẩn đoán và phục hồi tốt hơn từ lần tiếp theo. Để giảm thiểu tác động của thời gian ngừng hoạt động, các tổ chức cần có kế hoạch khôi phục sau thảm họa (DR) thích hợp. Lập kế hoạch DR là một nhiệm vụ quan trọng đối với nhiều SysOps / DevOps, nhưng mặc dù điều đó đã được dự đoán trước; thường thì nó không tồn tại.
Trong bài đăng trên blog này, chúng tôi sẽ phân tích các kịch bản sao lưu và lỗi khác nhau trong hệ thống cơ sở dữ liệu MongoDB. Chúng tôi cũng sẽ hướng dẫn bạn các quy trình khôi phục và chuyển đổi dự phòng cho từng trường hợp tương ứng. Các trường hợp sử dụng này sẽ khác nhau từ việc khôi phục một nút duy nhất, khôi phục một nút trong một replicaSet hiện có và gieo một nút mới trong một replicaSet. Hy vọng rằng điều này sẽ giúp bạn hiểu rõ về những rủi ro bạn có thể gặp phải và những điều cần cân nhắc khi thiết kế cơ sở hạ tầng của bạn.
Trước khi chúng ta bắt đầu thảo luận về các tình huống thất bại có thể xảy ra, hãy xem cách MongoDB lưu trữ dữ liệu và những loại sao lưu nào có sẵn.
Cách MongoDB lưu trữ dữ liệu
MongoDB là cơ sở dữ liệu hướng tài liệu. Thay vì lưu trữ dữ liệu của bạn trong các bảng được tạo từ các hàng riêng lẻ (như cơ sở dữ liệu quan hệ làm), nó lưu trữ dữ liệu trong các bộ sưu tập được tạo từ các tài liệu riêng lẻ. Trong MongoDB, một tài liệu là một khối JSON lớn không có định dạng hoặc lược đồ cụ thể. Ngoài ra, dữ liệu có thể được lan truyền trên các nút cụm khác nhau bằng cách chia sẻ hoặc sao chép sang các máy chủ phụ có replicaSet.
MongoDB cho phép ghi và cập nhật rất nhanh theo mặc định. Sự đánh đổi là bạn thường không được thông báo rõ ràng về những thất bại. Theo mặc định, hầu hết các trình điều khiển thực hiện ghi không đồng bộ, không an toàn. Điều này có nghĩa là trình điều khiển không trả lại lỗi trực tiếp, tương tự như CHÈN TRÌ HOÃN với MySQL. Nếu bạn muốn biết liệu điều gì đó có thành công hay không, bạn phải kiểm tra lỗi theo cách thủ công bằng cách sử dụng getLastError.
Để có hiệu suất tối ưu, bạn nên sử dụng SSD hơn là HDD để lưu trữ. Cần quan tâm đến việc lưu trữ của bạn là cục bộ hay từ xa và thực hiện các biện pháp cho phù hợp. Tốt hơn nên sử dụng RAID để bảo vệ các lỗi phần cứng và các kế hoạch khôi phục, nhưng đừng hoàn toàn dựa vào nó vì nó không cung cấp khả năng bảo vệ khỏi các lỗi bất lợi. Phần cứng phù hợp là nền tảng để ứng dụng của bạn tối ưu hóa hiệu suất và tránh sự cố lớn.
Lỗi dữ liệu cấp đĩa hoặc tệp dữ liệu bị thiếu có thể ngăn các phiên bản mongod khởi động và các tệp tạp chí có thể không đủ để tự động khôi phục.
Nếu bạn đang chạy với tính năng ghi nhật ký được bật, thì hầu như không cần phải chạy sửa chữa vì máy chủ có thể sử dụng các tệp nhật ký để tự động khôi phục các tệp dữ liệu về trạng thái sạch. Tuy nhiên, bạn vẫn có thể phải chạy sửa chữa trong các trường hợp cần khôi phục do hỏng dữ liệu cấp đĩa.
Nếu tính năng ghi nhật ký không được bật, lựa chọn duy nhất của bạn có thể là chạy lệnh sửa chữa. mongod --repair chỉ nên được sử dụng nếu bạn không có tùy chọn nào khác vì thao tác này loại bỏ (và không lưu) bất kỳ dữ liệu bị hỏng nào trong quá trình sửa chữa. Loại hoạt động này phải luôn được đặt trước với bản sao lưu.
Kịch bản khôi phục sau thảm họa MongoDB
Trong kế hoạch khôi phục thất bại, Mục tiêu Điểm khôi phục (RPO) của bạn là một tham số khôi phục chính cho biết bạn có thể mất bao nhiêu dữ liệu. RPO được liệt kê theo thời gian, từ mili giây đến vài ngày và phụ thuộc trực tiếp vào hệ thống sao lưu của bạn. Nó xem xét tuổi của dữ liệu sao lưu của bạn mà bạn phải khôi phục để tiếp tục hoạt động bình thường.
Để ước tính RPO, bạn cần tự hỏi mình một số câu hỏi. Khi nào dữ liệu của tôi được sao lưu? SLA liên quan đến việc truy xuất dữ liệu là gì? Việc khôi phục bản sao lưu dữ liệu có được chấp nhận không hay dữ liệu cần phải trực tuyến và sẵn sàng được truy vấn vào bất kỳ thời điểm nào?
Câu trả lời cho những câu hỏi này sẽ giúp định hướng loại giải pháp sao lưu bạn cần.
Giải pháp sao lưu MongoDB
Kỹ thuật sao lưu có các tác động khác nhau đến hiệu suất của cơ sở dữ liệu đang chạy. Một số giải pháp sao lưu làm giảm hiệu suất cơ sở dữ liệu đến mức bạn có thể cần phải lên lịch sao lưu để tránh các cửa sổ bảo trì hoặc sử dụng cao điểm. Bạn có thể quyết định triển khai các máy chủ phụ mới chỉ để hỗ trợ sao lưu.
Ba giải pháp phổ biến nhất để sao lưu máy chủ / cụm MongoDB của bạn là ...
- Mongodump / Mongorestore - sao lưu hợp lý.
- Hệ thống quản lý Mongo (Đám mây) - Cơ sở dữ liệu sản xuất có thể được sao lưu bằng MongoDB Ops Manager hoặc nếu sử dụng dịch vụ MongoDB Atlas, bạn có thể sử dụng giải pháp sao lưu được quản lý hoàn toàn.
- Ảnh chụp nhanh cơ sở dữ liệu (sao lưu cấp đĩa)
Mongodump / Mongorestore
Khi thực hiện mongodump, tất cả các tập hợp trong cơ sở dữ liệu được chỉ định sẽ được kết xuất dưới dạng đầu ra BSON. Nếu không có cơ sở dữ liệu nào được chỉ định, MongoDB sẽ kết xuất tất cả cơ sở dữ liệu ngoại trừ cơ sở dữ liệu quản trị, kiểm tra và cục bộ vì chúng được dành riêng cho mục đích sử dụng nội bộ.
Theo mặc định, mongodump sẽ tạo một thư mục được gọi là kết xuất, với một thư mục cho mỗi cơ sở dữ liệu chứa một tệp BSON cho mỗi bộ sưu tập trong cơ sở dữ liệu đó. Ngoài ra, bạn có thể yêu cầu mongodump lưu trữ bản sao lưu trong một tệp lưu trữ duy nhất. Tham số lưu trữ sẽ nối kết quả đầu ra từ tất cả cơ sở dữ liệu và bộ sưu tập thành một luồng dữ liệu nhị phân duy nhất. Ngoài ra, tham số gzip có thể nén tự nhiên kho lưu trữ này bằng cách sử dụng gzip. Trong ClusterControl, chúng tôi phát trực tuyến tất cả các bản sao lưu của mình, vì vậy chúng tôi bật cả thông số lưu trữ và gzip.
Tương tự như mysqldump với MySQL, nếu bạn tạo bản sao lưu trong MongoDB, nó sẽ đóng băng các bộ sưu tập trong khi kết xuất nội dung vào tệp sao lưu. Vì MongoDB không hỗ trợ các giao dịch (đã thay đổi trong 4.2) nên bạn không thể tạo bản sao lưu hoàn toàn nhất quán 100% trừ khi bạn tạo bản sao lưu bằng tham số oplog. Bật điều này trên bản sao lưu bao gồm các giao dịch từ oplog đang thực hiện trong khi tạo bản sao lưu.
Để tự động hóa tốt hơn và Bạn có thể chạy MongoDB từ dòng lệnh hoặc sử dụng các công cụ bên ngoài như ClusterControl. ClusterControl là tùy chọn được khuyến nghị để quản lý sao lưu và tự động hóa sao lưu, vì nó cho phép tạo các chiến lược sao lưu nâng cao cho các hệ thống cơ sở dữ liệu nguồn mở khác nhau.
ClusterControl cho phép bạn tải bản sao lưu của mình lên đám mây. Nó hỗ trợ sao lưu đầy đủ và khôi phục mã hóa mongodump. Nếu bạn muốn xem nó hoạt động như thế nào, hãy có bản demo trên trang web của chúng tôi.
Khôi phục MongoDB từ bản sao lưu
Về cơ bản có hai cách bạn có thể sử dụng kết xuất định dạng BSON:
- Chạy mongod trực tiếp từ thư mục sao lưu
- Chạy mongorestore và khôi phục bản sao lưu
Chạy mongod Trực tiếp từ bản sao lưu
Điều kiện tiên quyết để chạy mongod trực tiếp từ bản sao lưu là mục tiêu sao lưu là một kết xuất chuẩn và không được nén.
Daemon MongoDB sau đó sẽ kiểm tra tính toàn vẹn của thư mục dữ liệu, thêm cơ sở dữ liệu quản trị, tạp chí, danh mục bộ sưu tập và chỉ mục và một số tệp khác cần thiết để chạy MongoDB. Nếu trước đây bạn đã chạy WiredTiger làm công cụ lưu trữ, thì bây giờ nó sẽ chạy các bộ sưu tập hiện có dưới dạng MMAP. Đối với kết xuất dữ liệu đơn giản hoặc kiểm tra tính toàn vẹn, điều này hoạt động tốt.
Đang chạy mongorestore
Cách tốt hơn để khôi phục rõ ràng là khôi phục nút bằng cách sử dụng mongorestore.
mongorestore dump/
Thao tác này sẽ khôi phục bản sao lưu vào cài đặt máy chủ mặc định (localhost, cổng 27017) và ghi đè bất kỳ cơ sở dữ liệu nào trong bản sao lưu nằm trên máy chủ này. Bây giờ có rất nhiều tham số để thao tác quá trình khôi phục và chúng tôi sẽ đề cập đến một số tham số quan trọng.
Trong ClusterControl, điều này được thực hiện trong tùy chọn khôi phục sao lưu. Bạn có thể chọn máy khi bản sao lưu sẽ được khôi phục và xử lý phần còn lại. Điều này bao gồm sao lưu được mã hóa mà thông thường bạn cũng cần giải mã bản sao lưu của mình.
Xác thực Đối tượng
Vì bản sao lưu chứa dữ liệu BSON, bạn sẽ mong đợi nội dung của bản sao lưu là chính xác. Tuy nhiên, bắt đầu có thể xảy ra trường hợp tài liệu bị đổ là không đúng định dạng. Mongodump không kiểm tra tính toàn vẹn của dữ liệu mà nó kết xuất.
Để giải quyết việc sử dụng đó - objcheck buộc mongorestore phải xác thực tất cả các yêu cầu từ khách hàng khi nhận được để đảm bảo rằng khách hàng không bao giờ chèn tài liệu không hợp lệ vào cơ sở dữ liệu. Nó có thể có một tác động nhỏ đến hiệu suất.
Phát lại Oplog
Oplog vào bản sao lưu của bạn sẽ cho phép bạn thực hiện sao lưu nhất quán và thực hiện khôi phục tại chỗ. Bật tham số oplogReplay để áp dụng oplog trong quá trình khôi phục. Để kiểm soát khoảng thời gian phát lại oplog, bạn có thể xác định dấu thời gian trong tham số oplogLimit. Sau đó, chỉ các giao dịch cho đến khi có dấu thời gian mới được áp dụng.
Khôi phục bộ bản sao đầy đủ từ bản sao lưu
Khôi phục một replicaSet không khác nhiều so với khôi phục một nút duy nhất. Bạn phải thiết lập replicaSet trước và khôi phục trực tiếp vào replicaSet. Hoặc bạn khôi phục một nút trước và sau đó sử dụng nút đã khôi phục này để tạo một bản sao.
Khôi phục nút trước, sau đó tạo bản sao
Bây giờ nút thứ hai và thứ ba sẽ đồng bộ hóa dữ liệu của chúng từ nút đầu tiên. Sau khi quá trình đồng bộ hóa hoàn tất, bản sao của chúng tôi đã được khôi phục.
Tạo ReplicaSet trước, sau đó khôi phục
Khác với quy trình trước, bạn có thể tạo bản sao trước. Đầu tiên hãy định cấu hình tất cả ba máy chủ có bật replicaSet, khởi động cả ba daemon và khởi chạy replicaSet trên nút đầu tiên:
Bây giờ chúng tôi đã tạo replicaSet, chúng tôi có thể trực tiếp khôi phục bản sao lưu của mình vào đó:
Theo ý kiến của chúng tôi, việc khôi phục lại một replicaSet theo cách này sẽ đẹp hơn nhiều. Nó gần giống với cách bạn thường thiết lập một replicaSet mới từ đầu và sau đó điền vào nó với dữ liệu (sản xuất).
Tạo một nút mới trong một tập hợp bản sao
Khi mở rộng một cụm bằng cách thêm một nút mới trong MongoDB, quá trình đồng bộ hóa ban đầu của tập dữ liệu phải diễn ra. Với bản sao MySQL và Galera, chúng ta đã quá quen với việc sử dụng bản sao lưu để khởi tạo quá trình đồng bộ ban đầu. Với MongoDB, điều này có thể thực hiện được, nhưng chỉ bằng cách tạo một bản sao nhị phân của thư mục dữ liệu. Nếu bạn không có phương tiện để tạo ảnh chụp nhanh hệ thống tệp, bạn sẽ phải đối mặt với thời gian chết trên một trong các nút hiện có. Quá trình này, với thời gian chết, được mô tả bên dưới.
Gieo hạt bằng bản sao lưu
Vì vậy, điều gì sẽ xảy ra nếu bạn khôi phục nút mới từ bản sao lưu mongodump thay thế và sau đó để nó tham gia vào một replicaSet? Về lý thuyết, việc khôi phục từ một bản sao lưu phải cung cấp cùng một tập dữ liệu. Vì nút mới này đã được khôi phục từ bản sao lưu, nó sẽ thiếu bản saoSetId và MongoDB sẽ nhận thấy. Vì MongoDB không xem nút này là một phần của bản sao nên lệnh rs.add () sau đó sẽ luôn kích hoạt đồng bộ hóa ban đầu MongoDB. Đồng bộ hóa ban đầu sẽ luôn kích hoạt xóa mọi dữ liệu hiện có trên nút MongoDB.
replicaSetId được tạo khi khởi tạo replicaSet và rất tiếc là bạn không thể thiết lập theo cách thủ công. Thật đáng tiếc khi việc khôi phục từ bản sao lưu (bao gồm cả phát lại oplog) về mặt lý thuyết sẽ cung cấp cho chúng ta tập dữ liệu giống hệt nhau 100%. Sẽ rất tuyệt nếu đồng bộ hóa ban đầu là tùy chọn trong MongoDB để đáp ứng trường hợp sử dụng này.