Sao lưu dữ liệu quan trọng là một phần thiết yếu trong quản trị hạ tầng máy tính. Mặc dù nhu cầu sao lưu của mỗi người dùng có thể khác nhau, việc lưu trữ dữ liệu sao lưu ở một vị trí ngoại vi luôn là một thực hành tốt.
Quá trình gửi các bản sao dữ liệu đến một vị trí ngoại vi trước đây là một thách thức lớn về mặt hậu cần. Nhưng với sự ra đời của các dịch vụ lưu trữ đám mây như Crashplan và Dropbox, cũng như sự phát triển của các giải pháp lưu trữ đối tượng như DataOnline Spaces, việc này giờ đã trở nên đơn giản hơn rất nhiều. Tuy nhiên, việc nhớ sao lưu các file và dành thời gian để upload chúng vẫn có thể là một trở ngại.
Khám phá cách tự động sao lưu dữ liệu với DataOnline Spaces để bảo vệ thông tin quan trọng. Nếu bạn cần môi trường lưu VPS Windows mạnh mẽ để chạy ứng dụng hoặc lưu trữ, DataOnline cung cấp giải pháp VPS Windows ổn định, dễ quản lý, đảm bảo hiệu suất tối ưu cho doanh nghiệp.
Đó là lý do tại sao nhiều người lựa chọn sử dụng các công cụ khác nhau để thực hiện sao lưu tự động định kỳ cho các dữ liệu quan trọng. Trong bài hướng dẫn này, chúng ta sẽ xây dựng một script xoay quanh công cụ dòng lệnh s3cmd để upload dữ liệu nhanh chóng lên DataOnline Spaces. Sau đó, chúng ta sẽ sử dụng crontab để thường xuyên gọi script sao lưu và upload các file lên Space của chúng ta.
Yêu cầu
Để theo dõi bài hướng dẫn này, bạn cần:
-
Một Droplet Ubuntu 20.04 x64 với một tài khoản người dùng sudo không phải root. Bạn có thể cấu hình Droplet này theo bài hướng dẫn Cài đặt ban đầu cần thiết Ubuntu 20.04.
-
Một DataOnline Space cùng với API access key.
-
Công cụ dòng lệnh s3cmd được cài đặt trên Droplet của bạn.
Có chút quen thuộc với shell scripting và bộ lên lịch cron cũng sẽ hữu ích.
Để có thêm hướng dẫn và bối cảnh, bạn có thể đọc bài How To Schedule Routine Tasks With Cron and Anacron on a VPS.
Với các yêu cầu đã được chuẩn bị, chúng ta đã sẵn sàng bắt đầu quá trình tự động sao lưu.
Xây dựng script sao lưu của chúng ta
Có nhiều công cụ có thể được sử dụng để tự động upload các file sao lưu lên dịch vụ lưu trữ đối tượng theo định kỳ. Tuy nhiên, những công cụ đó có thể khó cấu hình và không linh hoạt. Việc sử dụng một script shell có thể là một cách tiếp cận tinh tế và đơn giản hơn để tự động sao lưu lên lưu trữ đối tượng.
Trong bài hướng dẫn này, chúng ta sẽ viết một script bash cơ bản nhằm tạo bản sao lưu của một file hoặc thư mục sử dụng tar. Script sau đó sẽ upload bản sao lưu đó lên DataOnline Spaces bằng tiện ích dòng lệnh s3cmd.
Để bắt đầu, đăng nhập vào Droplet của bạn và di chuyển đến thư mục home:
cd ~
Một khi đã ở trong thư mục home, chúng ta sẽ sử dụng nano để tạo một file rỗng, nơi chúng ta sẽ viết script:
nano bkupscript.sh
Bây giờ, chúng ta đã sẵn sàng bắt đầu viết script sao lưu của mình trong trình soạn thảo. Khi xây dựng script, chúng ta sẽ giải thích từng phần một, theo thứ tự.
Khởi tạo Script
Hiện tại, file bkupscript.sh chỉ là một file văn bản trống. Để máy tính của bạn có thể gọi file này như một lệnh, chúng ta cần bắt đầu script với một hashbang. Hashbang là một chỉ thị trình thông dịch cho phép các script hoặc file dữ liệu được chạy như lệnh.
Trong trường hợp của chúng ta, hashbang sẽ như sau:
#!/bin/bash
Bằng cách thêm dòng này ở đầu script, chúng ta đang báo cho shell rằng hãy chạy các lệnh trong file bằng bash.
Khai báo biến
Tiếp theo, chúng ta sẽ chỉ cho script biết các biến cần thiết để nó hoạt động đúng. Chúng ta có thể thêm các biến này ngay dưới hashbang:
... DATETIME=`date +%y%m%d-%H_%M_%S` SRC=$1 DST=$2 GIVENNAME=$3
Giải thích:
-
DATETIME: Biến này lưu trữ một dấu thời gian (timestamp) để gắn vào tên file sao lưu, giúp mỗi file được upload lên Space có một tên duy nhất. Dấu thời gian được tạo bằng cách gọi lệnh date với định dạng cho thấy 2 chữ số của năm (%y), 2 chữ số của tháng (%m), 2 chữ số của ngày (%d), giờ (%H), phút (%M) và giây (%S).
-
SRC: Đây là đường dẫn nguồn của file hoặc thư mục mà bạn muốn sao lưu.
$1
cho biết giá trị này được lấy từ tham số đầu tiên khi gọi script. -
DST: Biến này đại diện cho đích đến của file, trong trường hợp của chúng ta là tên của Space nơi chúng ta sẽ upload bản sao lưu. Giá trị này được lấy từ tham số thứ hai,
$2
. -
GIVENNAME: Biến này lưu tên do người dùng chỉ định cho file sao lưu. Tên file cuối cùng sẽ bắt đầu bằng GIVENNAME và sau đó nối thêm DATETIME. Giá trị này đến từ tham số thứ ba,
$3
.
Cung cấp hướng dẫn sử dụng
Khi viết một script, việc thêm vào một số mẹo hoặc lời khuyên tổng quát sẽ rất hữu ích để hỗ trợ người dùng khắc phục sự cố nếu quá trình sử dụng script của họ không thành công.
Với script sao lưu của chúng ta, chúng ta sẽ thêm một hàm có tên showhelp() ngay dưới phần khai báo biến. Hàm này sẽ in ra một loạt các thông điệp hướng dẫn sử dụng trên màn hình để giúp người dùng xử lý sự cố khi script gặp lỗi. Khi thêm hàm trong bash, cú pháp sẽ như sau:
Hàm này sẽ cung cấp các thông điệp trợ giúp bằng cách sử dụng lệnh echo để in ra các hướng dẫn sử dụng. Mỗi hướng dẫn sẽ được trình bày dưới dạng một chuỗi ký tự nằm trong dấu ngoặc kép. Bạn sẽ nhận thấy ở ví dụ dưới đây, một số chuỗi có ký tự escape \t hoặc \n xuất hiện ở đầu hoặc cuối. Đây là các ký tự escape cung cấp chỉ dẫn cụ thể về cách hiển thị chuỗi trong đầu ra của script:
-
\t biểu thị khoảng cách tab.
-
\n biểu thị xuống dòng.
Bạn có thể thêm bất kỳ chi tiết sử dụng nào hữu ích cho riêng mình giữa các dấu ngoặc nhọn (nhớ thêm lệnh echo trước mỗi chuỗi). Cho mục đích minh họa, chúng ta sẽ thêm các dòng sau:
Hàm showhelp() cuối cùng nên trông như sau:
Với phần hướng dẫn trợ giúp đã được đặt, chúng ta có thể chuyển sang thu thập các file cần sao lưu để upload lên Space.
Thu thập các file cần sao lưu
Trước khi script có thể chuyển bất cứ dữ liệu nào lên Space, nó cần phải tập hợp các file phù hợp và đóng gói chúng vào một gói duy nhất. Chúng ta có thể thực hiện điều này bằng cách sử dụng tiện ích tar và một câu lệnh điều kiện. Vì chúng ta sử dụng tar để tạo một file lưu trữ (đôi khi được gọi là file “zip”), chúng ta sẽ gọi hàm này là tarandzip().
Đầu tiên, khai báo hàm và thêm một lệnh echo để thông báo cho người dùng rằng script đã bắt đầu thu thập các file:
... tarandzip(){ echo "\n##### Gathering files #####\n" }
Sau lệnh echo, thêm lệnh tar để đóng gói và nén các file thành một file duy nhất:
tarandzip(){ echo "\n##### Gathering files #####\n" tar -czvf $GIVENNAME-$DATETIME.tar.gz $SRC }
Giải thích các tùy chọn của lệnh tar:
-
c: Tạo file lưu trữ.
-
z: Nén file sử dụng gzip.
-
v: Chế độ verbose, hiển thị thông tin chi tiết.
-
f: Chỉ định tên file lưu trữ sẽ được tạo.
-
$GIVENNAME-$DATETIME.tar.gz: Tên file sao lưu được tạo bằng cách kết hợp biến GIVENNAME và DATETIME, sau đó thêm đuôi .tar.gz.
-
$SRC: Đường dẫn nguồn của file/thư mục cần sao lưu.
Hàm này bây giờ nên có thể thực hiện được những gì chúng ta mong muốn, nhưng chúng ta có thể thêm một vài lệnh echo nữa để cung cấp cho người dùng thêm thông tin về cách script đang hoạt động. Việc này có thể được thực hiện bằng cách thêm một vài câu lệnh điều kiện, như sau:
Khi câu lệnh if được gọi, nó sẽ thực thi lệnh tar và chờ kết quả. Nếu kết quả của lệnh là tích cực (tức là, nó chạy thành công), các dòng lệnh nằm giữa then và else sẽ được thực thi. Những lệnh này bao gồm:
-
In ra một thông báo cho biết script đã hoàn tất quá trình tar thành công.
-
Trả về mã lỗi 0 để phần mã gọi hàm này biết rằng mọi thứ đã hoạt động bình thường.
Phần else của hàm này chỉ được thực thi nếu lệnh tar gặp lỗi trong quá trình thực thi. Trong trường hợp này, nhánh else của câu lệnh sẽ:
-
In ra một thông báo chỉ ra rằng lệnh tar đã thất bại.
-
Trả về mã lỗi 1, cho biết đã có sự cố xảy ra.
Cuối cùng, chúng ta kết thúc câu lệnh if/then/else bằng fi, điều này trong ngôn ngữ bash có nghĩa là câu lệnh if đã kết thúc.
Hàm tarandzip() hoàn chỉnh sẽ trông như sau:
Với hàm tarandzip() đã sẵn sàng, chúng ta đã có thể thiết lập script để chuyển các bản sao lưu.
Chuyển file sang Object Storage
Trong bước này, chúng ta sẽ sử dụng lệnh s3cmd để chuyển file sao lưu lên Space. Tương tự như hàm tarandzip(), chúng ta có thể thêm một số lệnh echo và sử dụng câu lệnh điều kiện if/then/else để thông báo cho người dùng biết script đang hoạt động như thế nào.
Đầu tiên, hãy khai báo hàm của chúng ta. Để đơn giản, đặt tên hàm là movetoSpace():
... movetoSpace(){ }
Bây giờ, chúng ta sử dụng s3cmd và các biến đã khai báo ở phần trên để xây dựng lệnh upload file sao lưu lên Space:
movetoSpace(){ s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST }
Giải thích từng phần của lệnh:
-
s3cmd: Gọi tới công cụ dòng lệnh s3cmd, được sử dụng để quản lý các bucket lưu trữ đối tượng.
-
put: Là lệnh của s3cmd dùng để upload dữ liệu vào một bucket.
-
$GIVENNAME-$DATETIME.tar.gz: Đây là tên file sao lưu sẽ được upload lên Space. Tên này được tạo từ biến GIVENNAME và DATETIME (được ghép nối và kết thúc bằng .tar.gz) được tạo ra bởi hàm tarandzip() ở trên.
-
s3://$DST: Đây là vị trí mà chúng ta muốn upload file. Chuỗi “s3://” là một schema URI được sử dụng để mô tả vị trí lưu trữ đối tượng trực tuyến, trong khi $DST là biến thứ ba mà chúng ta đã khai báo, chứa tên của Space.
Hiện tại, chúng ta đã có một hàm có thể upload file lưu trữ của mình lên Space. Tuy nhiên, hàm này chưa thông báo cho người dùng về trạng thái của quá trình upload. Hãy thay đổi nó bằng cách in ra một thông điệp trước lệnh để thông báo rằng quá trình đã bắt đầu, và sau khi lệnh kết thúc, in ra thông báo cho biết kết quả thành công hay thất bại.
Đầu tiên, thông báo cho người dùng rằng quá trình đã bắt đầu:
movetoSpace(){ echo "\n##### MOVING TO SPACE #####\n" s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST }
Vì lệnh sẽ chạy thành công hoặc thất bại (tức là, nó sẽ upload file lên Space hoặc không), chúng ta có thể thông báo cho người dùng bằng cách in ra một trong hai thông điệp trong một câu lệnh if/then/else, như sau:
... if s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST; then echo "\n##### Done moving files to s3://"$DST" #####\n" return 0 else echo "\n##### Failed to move files to the Space #####\n" return 1 fi
Câu lệnh điều kiện này nói với bash rằng: “Nếu lệnh s3cmd chạy thành công, thì in ra thông báo cho biết rằng script đã hoàn thành việc chuyển file lên Space. Ngược lại, in ra thông báo lỗi cho biết quá trình thất bại.”
Nếu quá trình s3cmd hoàn thành thành công, hàm sẽ in ra thông báo (dòng echo đầu tiên trong nhánh then) và trả về giá trị 0, báo cho phần code gọi hàm biết rằng quá trình đã hoàn tất. Nếu quá trình thất bại, nhánh else sẽ in ra thông báo lỗi và trả về giá trị 1, báo cho phần còn lại của script biết rằng đã xảy ra lỗi.
Tổng hợp lại, hàm movetoSpace() sẽ trông như sau:
Với hàm movetoSpace() đã được viết xong, chúng ta có thể tiếp tục đảm bảo rằng script được sắp xếp gọi các hàm theo thứ tự mong muốn bằng cách sử dụng các câu lệnh điều kiện để điều khiển luồng thực thi.
Thiết lập điều khiển luồng (Flow Control)
Mặc dù chúng ta đã xây dựng script với các hàm, nhưng chưa sắp xếp thứ tự chạy các hàm đó. Tại thời điểm này, chúng ta có thể giới thiệu một hàm gọi (calling function) để chỉ định chính xác cách và thời điểm chạy các hàm đã viết.
Giả sử mọi thứ đã được cấu hình đúng, khi chạy script nó sẽ đọc lệnh nhập vào, gán các giá trị cho các biến, thực hiện hàm tarandzip() và sau đó là hàm movetoSpace(). Nếu script gặp lỗi ở bất kỳ bước nào, nó sẽ in ra kết quả của hàm showhelp() để hỗ trợ người dùng khắc phục sự cố. Chúng ta có thể sắp xếp thứ tự này và bắt lỗi bằng cách thêm một loạt các câu lệnh if/then/else ở cuối file:
Câu lệnh if đầu tiên trong đoạn trên kiểm tra xem biến thứ ba được truyền vào (GIVENNAME) không rỗng. Cách thực hiện như sau:
-
[ ]: Dấu ngoặc vuông cho biết nội dung bên trong là một bài kiểm tra. Trong trường hợp này, bài kiểm tra nhằm kiểm tra xem một biến cụ thể có rỗng hay không.
-
!: Ký hiệu này có nghĩa là “không”.
-
-z: Tùy chọn này chỉ ra một chuỗi rỗng. Vậy kết hợp với dấu !, chúng ta đang kiểm tra biến đó không phải là chuỗi rỗng.
-
$GIVENNAME: Chúng ta chỉ định rằng chuỗi không được rỗng là giá trị được gán cho biến $GIVENNAME. Lý do chúng ta chọn cách này là vì biến này được gán giá trị từ tham số thứ ba khi gọi script từ dòng lệnh. Nếu chúng ta truyền vào ít hơn 3 tham số, code sẽ không có tham số thứ ba để gán cho $GIVENNAME, do đó nó sẽ nhận giá trị rỗng và bài kiểm tra này sẽ thất bại.
Nếu bài kiểm tra đầu tiên thành công, script sẽ tiếp tục với các câu lệnh if tiếp theo. Nếu bất kỳ câu lệnh if nào trả về lỗi, nhánh then sẽ gọi hàm showhelp() và in ra hướng dẫn trợ giúp. Về cơ bản, điều này “dính” tất cả các hàm mà chúng ta đã viết lại với nhau và cung cấp cho bash thông tin cần thiết để thực hiện chúng theo thứ tự đúng.
Script của chúng ta bây giờ đã hoàn chỉnh! Bạn có thể kiểm tra xem script của mình có trông giống như script hoàn chỉnh mà chúng ta đã xây dựng ở phần dưới không.
Script hoàn chỉnh
Dưới đây là script sao lưu hoàn chỉnh:
#!/bin/bash DATETIME=`date +%y%m%d-%H_%M_%S` SRC=$1 DST=$2 GIVENNAME=$3 showhelp(){ echo "\n\n############################################" echo "# bkupscript.sh #" echo "############################################" echo "\nThis script will backup files/folders into a single compressed file and will store it in the current folder." echo "In order to work, this script needs the following three parameters in the listed order: " echo "\t- The full path for the folder or file you want to backup." echo "\t- The name of the Space where you want to store the backup at (not the url, just the name)." echo "\t- The name for the backup file (timestamp will be added to the beginning of the filename)\n" echo "Example: sh bkupscript.sh ./testdir testSpace backupdata\n" } tarandzip(){ echo "\n##### Gathering files #####\n" if tar -czvf $GIVENNAME-$DATETIME.tar.gz $SRC; then echo "\n##### Done gathering files #####\n" return 0 else echo "\n##### Failed to gather files #####\n" return 1 fi } movetoSpace(){ echo "\n##### MOVING TO SPACE #####\n" if s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST; then echo "\n##### Done moving files to s3://"$DST" #####\n" return 0 else echo "\n##### Failed to move files to the Space #####\n" return 1 fi } if [ ! -z "$GIVENNAME" ]; then if tarandzip; then movetoSpace else showhelp fi else showhelp fi
Sau khi xác nhận script của bạn, hãy lưu và đóng file (CTRL+X, sau đó nhấn Y và ENTER nếu dùng nano).
Kiểm tra Script
Bây giờ, khi chúng ta đã hoàn thành việc xây dựng script, chúng ta có thể chuyển sang thử nghiệm nó. Việc này không chỉ cho chúng ta biết liệu script đã được viết đúng hay chưa, mà còn giúp chúng ta có cơ hội thực hành sử dụng script.
Khi thử nghiệm một script như thế này, thường là ý tưởng hay khi sử dụng các file mẫu (dummy files). Mặc dù chúng ta biết script không thể phá hủy hay xóa dữ liệu, nhưng để đảm bảo an toàn, bạn nên thử nghiệm với một số file không quan trọng. Đầu tiên, hãy tạo một thư mục bằng lệnh mkdir:
mkdir backupthis
Tiếp theo, tạo hai file rỗng bên trong thư mục này bằng lệnh touch:
sudo touch backupthis/file1.txt sudo touch backupthis/file2.txt
Bây giờ, chúng ta có thể thử nghiệm script bằng cách upload thư mục backupthis và nội dung của nó lên Space của bạn. Định dạng để gọi script sẽ như sau:
sh bkupscript.sh ./backupthis name_of_your_space testrun
Lưu ý: Vì hàm movetoSpace() tự động thêm tiền tố s3:// vào biến đích (tức là tên của Space), nên biến này chỉ cần là tên của Space chứ không phải URL đầy đủ. Ví dụ, nếu URL của Space là “https://example-space-name.nyc3.digitaloceanspaces.com”, bạn sẽ viết lệnh test như sau:
Lệnh trên sẽ khởi động script và trả về đầu ra như sau:
Output
Nếu bạn gặp bất kỳ lỗi nào, hãy xem lại script của bạn để đảm bảo nó khớp với ví dụ của chúng tôi. Đồng thời, hãy chắc chắn rằng cài đặt s3cmd của bạn đã được cấu hình đúng và cả access key lẫn secret key bạn đang sử dụng đều chính xác.
Tự động hoá sao lưu với Crontab
Sau khi kiểm tra thành công script sao lưu, chúng ta có thể thiết lập một cron job để gọi script này thực hiện sao lưu định kỳ lên Space. Trong bài hướng dẫn này, chúng ta sẽ cấu hình cron job thực thi script sao lưu mỗi phút.
-
Đầu tiên, làm cho script có thể thực thi được:
chmod +x bkupscript.sh
-
Sau đó, chỉnh sửa file crontab để chạy script mỗi phút:
crontab -e
Lần đầu tiên bạn chạy crontab -e
, hệ thống sẽ yêu cầu bạn chọn trình soạn thảo từ danh sách. Chọn một trình soạn thảo (ví dụ: nano).
Sau đó, thêm dòng sau vào cuối file:
no crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/ed 2. /bin/nano <---- easiest 3. /usr/bin/vim.basic 4. /usr/bin/vim.tiny Choose 1-4 [2]:
* * * * * ~/bkupscript.sh ~/backupthis nameofyourspace cronupload
Để lưu thay đổi, nhấn CTRL+X, sau đó Y và ENTER.
Sau khoảng một phút, một file mới sẽ xuất hiện trên dashboard của Space. Nếu bạn để cron job chạy mà không thay đổi, mỗi phút sẽ có một file mới được sao lưu và upload lên Space. Khi bạn xác nhận rằng cron đang chạy thành công, hãy điều chỉnh crontab theo khoảng thời gian sao lưu mong muốn.
Bạn đã có một script để định kỳ nén và chuyển các bản sao lưu lên DataOnline Space!
Kết luận
Trong bài hướng dẫn này, chúng ta đã tìm hiểu cách tạo các bản sao lưu định kỳ của các file quan trọng bằng cách sử dụng một script bash, crontab và DataOnline Spaces. Mặc dù script được trình bày ở đây chỉ nhằm mục đích minh họa, nó có thể được sử dụng làm nền tảng để xây dựng một phiên bản sản xuất sau này, có thể tích hợp với các giải pháp CI/CD như Jenkins, hoặc Travis CI.
DataOnline Spaces giúp bạn sao lưu dữ liệu dễ dàng, nhưng để tối ưu hóa hiệu suất, hãy cân nhắc thuê máy chủ VPS từ DataOnline. Với chi phí hợp lý và cấu hình linh hoạt, dịch vụ thuê máy chủ VPS đảm bảo tốc độ, bảo mật và sự ổn định cho mọi dự án.