redis-dump之can‘t find gem redis-dump
一、redis-dump工具簡單說明
退出bash shell窗口重新登錄bash
[root@MQ1-S ~]# find / -name redis-dump
/usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump
/usr/local/rvm/gems/ruby-2.3.7/gems/redis-dump-0.4.0/bin/redis-dump
未加載rvm,直接執行redis-dump時報錯
[root@MQ1-S ~]# /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump -u 192.168.2.106:10306 -a ‘DH56ji2(3u4‘ > test.json /usr/local/rvm/rubies/ruby-2.3.7/lib/ruby/2.3.0/rubygems.rb:241:in `bin_path‘: can‘t find gem redis-dump (>= 0.a) (Gem::GemNotFoundException) from /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump:22:in `<main>‘
於是重新加載rvm後再次執行redis-dump成功
[root@MQ1-S ~]# source /usr/local/rvm/scripts/rvm [root@MQ1-S ~]# ruby --version ruby 1.8.7 (2013-06-27 patchlevel 374) [x86_64-linux] [root@MQ1-S ~]# rvm --create ruby-2.3.7 Using /usr/local/rvm/gems/ruby-2.3.7 [root@MQ1-S ~]# ruby --version ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-linux] [root@MQ1-S ~]# [root@MQ1-S ~]# /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump -u 192.168.2.106:10306 -a ‘DH56ji2(3u^4‘ > test.json [root@MQ1-S ~]# [root@MQ1-S ~]# du -sh test.json 87M test.json [root@MQ1-S ~]#
於是簡單總結如下:
redis-dump工具是基於ruby編寫的腳本,所以必須在ruby環境下才能執行此命令工具
所以在執行redis-dump命令前必須先加載ruby環境,source /etc/profile.d/rvm.sh就是加載ruby環境或者是source /usr/local/rvm/scripts/rvm
由於一開始服務器安裝的ruby是2.3.7的版本rvm install 2.3.7,所以要切換到ruby-2.3.7 下
rvm --create ruby-2.3.7
二、redis數據備份腳本分析
2.1、原備份腳本:
[root@MQ1-S scripts]# vim dump_redisdata.sh #!/bin/bash source /etc/profile.d/rvm.sh rvm --create ruby-2.3.7 & >/dev/null DATENOW=`date +%Y%m%d` DIR=/data1/backup/redisdb/"$DATENOW" DATETIME=`date +%H%M` if [ ! -d "$DIR" ] then mkdir -p $DIR fi /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump -u 192.168.2.106:10239 -a ‘DJKjK0e=4‘ |gzip >"$DIR"/redis$DATETIME-json.gz oldDate=$(date -d "-6 days" "+%Y%m%d") cd /data1/backup/redisdb for folder in $(ls -d */) do [ ${folder%/*} -lt $oldDate ] && rm -rf $folder done
上面的腳本直接在shell執行時有問題的,導致寫入定時任務後,備份redis數據失敗
2.2、失敗的分析過程
先加載ruby環境以及切換到ruby-2.3.7下
source /etc/profile.d/rvm.sh
rvm --create ruby-2.3.7
ruby --version
[root@MQ1-S ~]# sh dump_redisdata.sh
RVM is not a function, selecting rubies with ‘rvm use ...‘ will not work.
You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.
雖然shell界面還有warn輸出,但是查看redis-dump 進程,腳本已經成功運行,
[root@MQ1-S 20180725]# ps -ef|grep redis-dump
root 26675 26667 72 17:48 pts/3 00:00:14 /usr/local/rvm/rubies/ruby-2.3.7/bin/ruby /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump -u 192.168.2.106:10306 -a DH56ji2(3u^4
root 26836 22679 0 17:49 pts/4 00:00:00 grep redis-dump
[root@MQ1-S 20180725]#
但是不在服務器的shell 命令行先執行命令加載ruby環境以及切換到ruby-2.3.7環境下 就直接在服務器bash shell命令行手動執行腳本,就會報如下錯,腳本執行失敗,自動退出
[root@MQ1-S ~]# sh dump_redisdata.sh
/usr/local/rvm/rubies/ruby-2.3.7/lib/ruby/2.3.0/rubygems.rb:241:in `bin_path‘: can‘t find gem redis-dump (>= 0.a) (Gem::GemNotFoundException)
from /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump:22:in `<main>‘
[root@MQ1-S ~]#
RVM is not a function, selecting rubies with ‘rvm use ...‘ will not work.
You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.
已經足夠說明未加載rvm和切換到ruby2.3.7環境下
直接把原來的備份腳本寫入定時任務,這也是備份腳本沒執行成功的根本原因。
2.3、關於/bin/bash --login的分析
[root@MQ1-S ~]# sh dump_redisdata.sh
RVM is not a function, selecting rubies with ‘rvm use ...‘ will not work.
You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.
雖然出現/bin/bash --login 輸出,並不影響腳本的執行,但是看著怪不舒服的。於是想辦法解決。
於是網上查資料,才發現是服務器的環境變量加載的問題。
現在簡單普及下環境變量的
關於環境變量的介紹:
/etc/profile:此文件為系統的每個用戶設置環境信息,當用戶第一次登錄時,該文件被執行.
並從/etc/profile.d目錄的配置文件中搜集shell的設置.
/etc/bashrc:為每一個運行bash shell的用戶執行此文件.當bash shell被打開時,該文件被讀取.
~/.bash_profile:每個用戶都可使用該文件輸入專用於自己使用的shell信息,當用戶登錄時,該文件僅僅執行一次!默認情況下,他設置一些環境變量,執行用戶的.bashrc文件.
~/.bashrc:該文件包含專用於你的bash shell的bash信息,當登錄時以及每次打開新的shell時該文件被讀取.
~/.bash_logout:當每次退出系統(退出bash shell)時,執行該文件.
為了能做到在執行腳本前能夠提前自動加載ruby的環境,所以選擇了~/.bashrc 加載這個環境變量的文件
同時要在這個文件後面添加下面2行代碼來加載ruby換進變量
[root@MQ1-S ~]# cat /root/.bashrc
#.bashrc
#User specific aliases and functions
alias rm=‘rm -i‘
alias cp=‘cp -i‘
alias mv=‘mv -i‘
#Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
#####
[[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm"
rvm --create ruby-2.3.7
[root@MQ1-S ~]#
2.4、修改後的成功的腳本
[root@MQ1-S scripts]# cat dump_redisdata.sh
#!/bin/bash
. /root/.bashrc
DATENOW=`date +%Y%m%d`
DIR=/data1/backup/redisdb/"$DATENOW"
DATETIME=`date +%H%M`
if [ ! -d "$DIR" ]
then
mkdir -p $DIR
fi
redis-dump -u 192.168.2.106:10306 -a ‘DH56ji2(3u^4‘ |gzip >"$DIR"/redis$DATETIME-json.gz
oldDate=$(date -d "-6 days" "+%Y%m%d")
cd /data1/backup/redisdb
for folder in $(ls -d */)
do
[ ${folder%/*} -lt $oldDate ] && rm -rf $folder
done
寫入定時任務:
[root@MQ1-S ~]# crontab -l|grep dump_redisdata.sh
12 17 * * * /bin/bash /data/scripts/dump_redisdata.sh & >/dev/null
查看進程,可知,此時腳本已經可以寫入定時任務自動執行了
[root@MQ1-S ~]# ps -ef|grep redis-dump
root 22250 22045 72 17:12 ? 00:00:22 /usr/local/rvm/rubies/ruby-2.3.7/bin/ruby /usr/local/rvm/gems/ruby-2.3.7/bin/redis-dump -u 192.168.2.106:2503 -a DP5HJKGF0
root 22529 21776 0 17:12 pts/3 00:00:00 grep redis-dump
到此redis-dump備份redis數據腳本的修改完畢。
redis-dump之can‘t find gem redis-dump