標籤:
問題背景: php讀取線上redis資料,經常不穩定,資料響應時有時無。
解決方案:多次讀取,每次讀取所有上一次沒讀出的資料,直到全部擷取。
本文實現用shell進行多次redis資料讀取, 每次取出其中的有效值(對於我們的例子中,就是給key,能在redis上取得其value的為有效值,其他無效),並將無效值重跑一遍,以此迭代,直到所有redis資料被取出。PS:redis資料可以由php或C讀出,給定介面的話非常簡單,具體可以參考phpredis,,由於可能涉密,本文中不給出這塊的實現。
方法概述:
- 將source中的key分為N個檔案,丟入redis並行get value
- 即時統計N個檔案get value輸出結果的總行數,以及其中有效行數
- N個檔案統計結束後, 將其所有結果合并,放入result/step/stepx.res
- 刪除原先並行的的source檔案,結果檔案
- 將result中未擷取到的key放入source/step2/contsigns,作為下一輪的輸入,再次將其分為N個檔案,運行(這裡的contsign就是redis的key)
- 最後將各個step所得結果都寫入final.res檔案。cat result/steps/step*.res >> final.res
項目結構:
- 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/包含各輪輸出後的合并結果
具體實現:
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=0hv=0for file in $Filefolderdo 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)) fidoneecho "totally $nl lines"echo "$hv lines have tag value"###################################combine results into one fileif [ "$#" -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 fifi
PS: 以上analyze_result.sh 還可以去掉analyze_result.sh中的interactive部分(無需使用者輸入),通過crontab進行定時,進一步自動化執行。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
<shell>迭代讀取redis解決資料不穩定問題