1. 程式人生 > >shell 例程 —— 解決redis讀取穩定性

shell 例程 —— 解決redis讀取穩定性

code $2 獲取 給定 tag spa zha analyze html

問題背景: php讀取線上redis數據,常常不穩定,數據響應時有時無。
解決方法:多次讀取。每次讀取全部上一次沒讀出的數據,直到全部獲取。

本文實現用shell進行多次redis數據讀取, 每次取出當中的有效值(對於我們的樣例中,就是給key,能在redis上取得其value的為有效值。其它無效),並將無效值重跑一遍,以此叠代,直到全部redis數據被取出。PS:redis數據能夠由php或C讀出,給定接口的話很easy,詳細能夠參考phpredis。。因為可能涉密,本文中不給出這塊的實現。





  1. 方法概述:

    1. 將source中的key分為N個文件。丟入redis並行get value
    2. 實時統計N個文件get value輸出結果的總行數,以及當中有效的行數
    3. N個文件統計結束後, 將其全部結果合並,放入result/step/stepx.res
    4. 刪除原先並行的的source文件,結果文件
    5. 將result中未獲取到的key放入source/step2/contsigns。作為下一輪的輸入。再次將其分為N個文件,運行(這裏的contsign就是redis的key)
    6. 最後將各個step所得結果都寫入final.res文件。cat result/steps/step*.res >> final.res


  2. 項目結構:

    技術分享


    • getredis.php: 實現獲取redis數據
    • all.sh: 主程序,並行運行getredis.php;
    • analyze_result.sh: 實時分析redis獲取數據運行情況(第2步), 加參數後實現上面的第3-5步(詳細見下一節凝視);
    • source/:存儲輸入數據,當中all/下為原始全部redis的輸入。 step2/為這一輪中未獲取到的key,將作為下一輪獲取redis的輸入, 其余(如xaa)為當前這一輪中key分成的N個文件;
    • result/: 存儲結果。當中source/包括當前一輪source下全部N個文件的輸出;steps/包括各輪輸出後的合並結果



  3. 詳細實現:


    all.sh :

#Author:Rachel Zhang
#Email: [email protected] for file in source/* do { echo "processing source $file" if test -f $file then php getredis.php $file > result/$file fi echo "$file done..." }& done






analyze_result.sh:

#Author:Rachel Zhang
#Email: [email protected]

Filefolder=result/source/*
#Filefolder=source/*

echo "##################################"
echo "     In Folder $Filefolder"
echo "##################################"
nl=0
hv=0
for file in $Filefolder
do
    if test -f $file
    then
        fline=`wc -l $file | awk ‘{print $1}‘`
        nl=$(($nl+$fline))
        fvalue=`cat $file |awk ‘BEGIN{x=0;}{if($2) x=x+1;}END{print x;}‘`
        hv=$(($hv+$fvalue))
    fi
done


echo "totally $nl lines"
echo "$hv lines have tag value"


##################################
#combine results into one file

if [ "$#" -gt 0 ]
then
    if test -e "result/all.result"
    then
        mv result/all.result result/all.result.bak
    fi

    for file in $Filefolder
    do
        if test -f $file
        then
            cat $file >> result/all.result
        fi
    done
    echo "all the output are write in result/all.result"




    # put null-value keys into source/step2/contsigns
    if  test -e source/step2
    then
        mkdir source/step2
    fi
    cat result/all.result| awk ‘{if($2==null) print}‘ > source/step2/contsigns
    Nnull_value=`wc -l source/step2/contsigns | awk ‘{print $1}‘`
    echo "remaining ${Nnull_value} keys to be processed"




    # put has-value key-value into result/steps/step${step_id}.res
    step_id=1
    while test -e result/steps/step${step_id}.res
    do
        step_id=$(($step_id+1))
    done
    cat result/all.result | awk ‘{if($2) print}‘ > result/steps/step${step_id}.res
    echo "current valid results are writen in result/steps/step${step_id}.res"



    # remove the current source files, generate new source files and re-run all.sh
    echo "remove current source and result files?

(y/n)" read answer if [ $answer == "y" ]; then if [ $Nnull_value -gt 10 ]; then rm source/* rm result/source/* cd source && split -l 5000 step2/contsigns && cd ../ echo "now re-run sh ./all.sh?

(y/n)" read answer if [ $answer == "y" ]; then sh all.sh fi fi fi fi




PS: 以上analyze_result.sh 還能夠去掉analyze_result.sh中的interactive部分(無需用戶輸入)。通過crontab進行定時,進一步自己主動化運行。



shell 例程 —— 解決redis讀取穩定性