#
算法導論 - 算法入門 ,一小節(插入排序,復雜度)
# 插入排序 - 復雜度
def insertion_sort(arr): # 1
for j in xrange( 1,len(arr) ): # n-1
key = arr[j] # n-1
i=j-1 # n-1
while i>=0 and arr[i]> key : # n(n-1)/2
arr[i+1] = arr[i] # n(n-1)/2
i=i-1 # n(n-1)/2
arr[i+1] = key # n-1
print arr # n-1
驗證結果 :
>>> arr=[5,2,4,6,1,3]
>>> insertion_sort(arr)
[2, 5, 4, 6, 1, 3]
[2, 4, 5, 6, 1, 3]
[2, 4, 5, 6, 1, 3]
[1, 2, 4, 5, 6, 3]
[1, 2, 3, 4, 5, 6]
驗證復雜度:
z = 5(n-1)+1+3n(n-1)/2
我們測試數據 為 n=6
當數據極端情況就是需要全部重新排列
就是 [6,5,4,3,2,1] 要排出 [1,2,3,4,5,6] 這樣
>> z = 71
一種比較笨的 驗證方法 供大家拍磚 :
def insertion_sort(arr):
ii=0
ii+=1
for j in xrange( 1,len(arr) ):
ii+=1
key = arr[j]
ii+=1
i=j-1
ii+=1
while i>=0 and arr[i]> key :
ii+=1
arr[i+1] = arr[i]
ii+=1
i=i-1
ii+=1
arr[i+1] = key
ii+=1
print arr
ii+=1
print "----",str(ii)
>>> arr=[6,5,4,3,2,1]
>>> insertion_sort(arr)
[5, 6, 4, 3, 2, 1]
[4, 5, 6, 3, 2, 1]
[3, 4, 5, 6, 2, 1]
[2, 3, 4, 5, 6, 1]
[1, 2, 3, 4, 5, 6]
---- 71 #復雜度驗證為 71
羅嗦下 n(n-1)/2
極端情況下
i=1 ; j 需要挪動 1次
i=2 ; j 挪動 1+2次
i=3 ; j 挪動 1+2+3次
....
i=n ; j 挪動 1+2....+n
我們又找到 (1+n)+(2+n-1)+(3+n-2).... = (1+n)n/2
我們這 的 i 是從 2 次開始的 也就是說 (n-1)n/2 了
def tn(ii):
ti=0
for i in xrange(ii) :
for j in xrange(i) :
ti+=1
print ti
print tn(2) #1 = 1
print tn(3) #3 = 1+2
print tn(4) #6 = 1+2+3
..
發現 自己寫個小程序 - 文本存儲二叉結構的hashMap。 那個費勁! 痛下決心 仔細學習 算法 。
(如果大家有興趣就跟我一起 - 《算法導論》,也望大家監督我能每天拿出一小時和大家分享算法,算法代碼我會盡量使用 py 和 解決一些分析日志的應用上靠 (其實,上面費勁的 二叉hash 是為了分析日志中 - 希望能實現 多個大文件不需要合并就能根據某列排序輸出! 目前的解決辦法 find .. -exec cat {} \; | perl |sort 的笨方法 )
1. 算法在計算中的作用 (筆記) :
算法(algorithm):就是定義良好的計算過程,它取一個或一組作為輸出,并產生一個或一組自作為輸出。
一些函數運行級別 # http://www.wolframalpha.com/ 函數都可在網站里運行
這里 n=一億條數據 :
log_2(n) 30
n^0.5 31622
n 10^9
n*log_2(n) 2.9^10
n^2 10^18
n^3 10^27
2^n 無窮
n! 10^362880
需要知道的復雜度 - 在某一個臨界點后 合并會別插入要快的
插入排序 復雜度 n^2 http://www.wolframalpha.com/input/?i=n^2
合并排序 復雜度 n*log_2(n) http://www.wolframalpha.com/input/?i=n*log_2%28n%29+
網上的查找到的一些名稱:參考 http://www.51testing.com/?uid-130868-action-viewspace-itemid-66729
1.1 穩定排序 非穩定排序 -
穩定排序是所有相等的數經過某種排序方法后,仍能保持它們在排序之前的相對次序,。反之,就是非穩定的排序。
1.2 內排序 外排序
在排序過程中,所有需要排序的數都在內存,并在內存中調整它們的存儲順序,稱為內排序; 在排序過程中,只有部分數被調入內存,并借助內存調整數在外存中的存放順序排序方法稱為外排序。
1.3 算法的時間復雜度 空間復雜度
所謂算法的時間復雜度,是指執行算法所需要的計算工作量。 一個算法的空間復雜度,一般是指執行這個算法所需要的內存空間。
幾種常見的算法復雜度:
2.1冒泡排序 (Bubble Sort) O(n^2)
2.2選擇排序 (Selection Sort) O(n^2 )
2.3插入排序 (Insertion Sort) O(n^2)
2.4堆排序 O( nlog(n) )
2.5歸并排序 O( nlog_2(n) )
2.6快速排序 最好 O( nlog_2(n) ) 最壞 O(n^2)
wiki 參考 :http://zh.wikipedia.org/wiki/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95
穩定的
- 冒泡排序(bubble sort) — O(n2)
- 雞尾酒排序 (Cocktail sort, 雙向的冒泡排序) — O(n2)
- 插入排序 (insertion sort)— O(n2)
- 桶排序 (bucket sort)— O(n); 需要 O(k) 額外空間
- 計數排序 (counting sort) — O(n+k); 需要 O(n+k) 額外空間
- 合併排序 (merge sort)— O(n log n); 需要 O(n) 額外空間
- 原地合併排序 — O(n2)
- 二叉排序樹排序 (Binary tree sort) — O(n log n)期望時間; O(n2)最壞時間; 需要 O(n) 額外空間
- 鴿巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 額外空間
- 基數排序 (radix sort)— O(n·k); 需要 O(n) 額外空間
- Gnome sort — O(n2)
- Library sort — O(n log n) with high probability, 需要 (1+ε)n 額外空間
[編輯] 不穩定
- 選擇排序 (selection sort)— O(n2)
- 希爾排序 (shell sort)— O(n log n) 如果使用最佳的現在版本
- Comb sort — O(n log n)
- 堆排序 (heapsort)— O(n log n)
- Smoothsort — O(n log n)
- 快速排序 (quicksort)— O(n log n) 期望時間, O(n2) 最壞情況; 對於大的、亂數串列一般相信是最快的已知排序
- Introsort — O(n log n)
- Patience sorting — O(n log n + k) 最壞情況時間,需要 額外的 O(n + k) 空間,也需要找到最長的遞增子序列(longest increasing subsequence)
[編輯] 不實用的排序演算法
環境設置:如果有系統字符編碼 沖突,在當前
vim ~/.bash_profile 下加入
LANG=zh_CN
LC_ALL=zh_CN.UTF8
export LANG LC_ALL
字符編碼轉化:
# 由decode解析,默認會使用 系統編碼 輸出
# 在 linux 下面其實等價 encode("UTF-8", decode("GBK",$_));
perl -MEncode -ne 'print decode("GBK",$_);' file.txt
判斷數據是否符合輸出:
echo "121" |perl -ne 'print if /2/;' #print 123
匹配正則group輸出:
echo "abc121a" |perl -ne 'print $1 if /(\D+)/;' #print abc
大小寫轉化:
# 全部 大小轉小寫
echo "ABC1C2cGJ" |perl -ne 'tr/[A-Z]/[a-z]/; print ;' #print
# "L 中間全部小寫 "E ; "U 中間全部大寫 "E ↓
echo "ABC1C2cGJ" |perl -ne 's/(.*?1)(.*?)(2.*?)/$1\L$2\E$3/g; print ;' #print ABC1c2cGJ
源文件替換:
echo "ABC 123" > te
sed -i 's/ABC/abc/g' te
或者 : perl -i -pe 's/ABC/abc/g' te
cat te # print abc 123
外部傳參:
tt="cc"
echo "gg" |perl -ne ' print "'$tt'" ;'
輸出:cc
perl -e 'print "$ARGV[0]\t$ARGV[1]\n" ' 'par1' 'par2' #print par1 par2
重復列輸出:
cat xx.txt | awk -F" " 'a[$1]++'
或者 :
cat xx.txt |perl -F"\t" -ane '$a{$F[1]}++;END{
while(($k,$v)=each(%a)){ print "$k = $v "n"; }
}'
結果比如:
百度手機在線 = 7
中興 = 2
萬信恒通 = 2
還比如:查看各用戶 有多少個進程
ps -ef |perl -ane '$a{$F[0]}++;END{
while(($k,$v)=each(%a)){ print "$k = $v \n"; }
}'
求 兩項 交集
cat BuyMusic.20090525| perl -ne 'BEGIN{
$p1="600902000005416300";
$p2="600902000006211983";
$p_col=30;
$mob_col=0;
}END{
my @inter = grep {$a{$_}} keys %b; # 求交集
#print $p1,"=",join(",",keys %a),""n";
#print $p2,"=",join(",",keys %b),""n";
print "產品 $p1:",scalar keys %a," "n";
print "產品 $p2:",scalar keys %b," "n";
print "交集:",scalar @inter," "n";
}
chomp;
@lis=split /\|<>\|/ ;
if( $lis[ $p_col] eq $p1 ){
$a{$lis[$mob_col]}++;
}
if( $lis[$p_col] eq $p2 ){
$b{$lis[$mob_col]}++;
}
'
關鍵字 Top 10 ,輸出源文本數據 :
perl -e '
my $num=10; # top 10
open(MYFILE, "<$ARGV[0]");
open(MYFILE2, "<$ARGV[0]");
# 關鍵字列數
while(<MYFILE>){@lis=split /\|<>\|/;$fck{$lis[1]}++ }
foreach $k (sort { $fck{$b} <=> $fck{$a} } keys %fck){
if(++$row>$num){last; }
$arr[@arr] = $k;
}
while(<MYFILE2>){@lis=split /\|<>\|/;
if(grep { $arr[$_] eq $lis[1] } 0..$#arr){
# print "$fck{$lis[1]}:$_"; #帶 關鍵字出現次數輸出
print ;
}
}
' qdSearch.log
如果你不想使用mysql的自動遞增,但又想實現主鍵序列號的功能,可以使用下面的方法,通過函數用一張表去維護生成多個表的序列號,簡單又實用
1.創建生成多個表的序列號的數據維護表
CREATE TABLE seq (
name varchar(20) NOT NULL,
val int(10) UNSIGNED NOT NULL,
PRIMARY KEY (name)
) ENGINE=MyISAM DEFAULT CHARSET=UTF-8
2.插入幾條初始化數據
INSERT INTO seq VALUES('one',100);
INSERT INTO seq VALUES('two',1000);
3.創建函數以生成序列號
CREATE FUNCTION seq(seq_name char (20)) returns int
begin
UPDATE seq SET val=last_insert_id(val+1) WHERE name=seq_name;
RETURN last_insert_id();
end
4.測試
-
mysql> SELECT seq('one'),seq('two'),seq('one'),seq('one');
-
+------------+------------+------------+------------+
-
| seq('one') | seq('two') | seq('one') | seq('one') |
-
+------------+------------+------------+------------+
-
| 102 | 1002 | 103 | 104 |
-
+------------+------------+------------+------------+
-
1 row IN SET (0.00 sec)
在定制 數學公式的時候 可能 希望有個直觀的 展現
我們前一段時間用到的 { 推薦分值 90 天 遞減公式,如果這東西早發現 公式就不會錯了!}
目前我們遞減的公式
y=-x/90+1
在比如我們優化下 90天改成
(y*10)^2=-x+90
2009-11-05
雖然 mysql,oracle 和 Berkeley DB,sqlite3 等數據庫已經很好
但是當我初略學習下 數據挖掘方面的一些知識發現,關系數據庫遠遠不夠來存儲,查詢 etl 后的數據
比如:我希望原始日志數據進行某一字段的排序,是不是很簡單 。
有人說 - 數據導入數據庫 load into table ... , select order by 。之
還有人說 - linux sort -n...
恩!很好,下面我們對大小為 1TB 的數據開始進行這個簡單的操作 -- 傻眼了 !!
關于挖掘 - TB 級別的數量在我目前學習挖掘不到半年,就遇到過3-4次之多
解決辦法:
對于這個問題 - 我現在希望能有個 大的鏈表 - (大到內存裝不下),
鏈表中的struct 結構為 :
>> 排序屬性文件歸屬
>> 排序屬性整條數據在文件中的 起始位置 - 結束位置
>> 在排序中的排位 ( 鏈表結構,只記入比自己小的 屬性在此鏈表的位置 )
比如 :
1. 文件1內容 =>
說明:
完整數據描述 : 此數據在文件中的 起始位置(當然是通過程序取得的,這為了方便我標出)
..c . 0 - 22
..a . 23 - 55
..b . 56- 76
..d . 77 - 130
..f . 131 - 220
..e . 221 - 243
2. 數據結構預開空間 100 byte
3. 文件存儲在描述 : # 鏈表排序我就不介紹了,數據結構的最基本技能,修改數據結構中的比自己小的指向
我這就給出結果
{ /tmp/文件1, 0-22 , 300 } #說明 c : 在鏈表位置 0
{ /tmp/文件1, 23-55 , 200 } # a : 100
{ /tmp/文件1, 56-76 , 0 } # b : 200
{ /tmp/文件1, 77-130 , 500 } # d : 300
{ /tmp/文件1, 131-220 , } # f : 400
{ /tmp/文件1, 221-243 , 400 } # e : 500
4. 倒敘輸出 由小到到
假設預存最小 為 200 鏈表位置
找出 使用 open /tmp/文件1
并使用 seek 文件游標 定位 23-55 取出 ..a...
根據 鏈表中 200 到 seek 56 76 取出 ..b...
等等
當然 上面
數據結構你可以使用 雙向鏈表, btree , 紅黑 , 斐波那契。。。( 數據結構終于感覺有用了,不枉費我考的軟證啊!)
通過說明,我這 給大家提供個 可能需要的 技術細節 (py),不足之處 歡迎拍磚!!
1. 二進制文件 結構化 寫,修改
#指定修改 190 byte 處的 內容
import os
from struct import *
fd = os.open( "pack1.txt", os.O_RDWR|os.O_CREAT )
ss = pack('ii11s', 3, 4, 'google')
os.lseek(fs, len(ss)*10, 0)
os.write(fs,ss)
os.fsync(fs)
#os.close( fs )
2. seek 指定位置結構化讀取
from struct import *
file_object = open('pack1.txt', 'rb')
def ts(si,ss=len(ss)):
file_object.seek(si*ss)
chunk = file_object.read(ss)
a,b,c=unpack('ii11s', chunk )
print a,b,c
ts(10)
#輸出 3 4 google
1. 其他語言的 使用
struct 結構定義 ,在 python 中 使用 struct 包,這樣序列出來的數據到文件中其他語言也可以使用
參考: http://www.pythonid.com/bbs/archiver/?tid-285.html
pack1.py
from struct import *
# i 為 int(4) 11s 為預留 11 位置 的 string
# 此數據類型 為 19 byte ss = pack('ii11s', 1, 2, 'hello world')
f = open("pack1.txt", "wb")
f.write(ss)
f.close()
上面的代碼往C的結構中寫入數據,結構包括兩個整型和一個字符串。
pack1.c
#include <stdio.h>
#include <string.h>
struct AA
{
int a;
int b;
char c[64];
};
int main()
{
struct AA aa;
FILE *fp;
int size, readsize;
memset(&aa, 0, sizeof(struct AA));
fp = fopen("pack1.txt", "rb");
if (NULL == fp) {
printf("open file error!"n");
return 0;
}
readsize = sizeof(struct AA);
printf("readsize: %d"n", readsize);
size = fread(&aa, 1, readsize, fp);
printf("read: %d"n", size);
printf("a=%d, b=%d, c=%s"n", aa.a, aa.b, aa.c);
fclose(fp);
return 0;
}
結果輸出:
C:"Documents and Settings"lky"桌面"dataStructure>a
readsize: 72
read: 57
a=1, b=2, c=hello word
最后羅嗦下:
能用數據結構了,很多東西都可以根據自己邏輯定制 存儲很方便 。 不再受 關系數據庫 , key 數據庫 或 mapreduce 的限制
參考:
http://docs.python.org/library/struct.html#module-struct #官方struct 包 說明
http://blog.csdn.net/JGood/archive/2009/06/22/4290158.aspx # 使用 struct 的前輩留下的
http://www.tutorialspoint.com/python/os_lseek.htm #一個小demo
Python天天美味(17) - open讀寫文件
我們這就是有 企業挖掘中最常用的 《流失用戶分析》來說明:
數據挖掘流程:
1. 定義主題 :天啊,我在干什么!( 此模塊絕大多數主觀意識上完成,有少量客觀驗證)
1.1 明確主題用戶在各用戶群中的分布 - 流失用戶在各用戶群中比例
不同客戶群的流失程度如:某渠道,某軟件版本,頁面布局,功能等主觀上去分析。
盡量把影響流失比較大的因素詳細羅列出來 如: 概率分布,頁面布局變化影響等
1.2 明確主題用戶特征 - 流失用戶特征
對流失用戶影響比較大的字段如:金額,軟件版本(缺少最需要的功能),客服對問題的處理的時間
2. 數據選擇 :什么樣的選民,選出什么樣的總統!
在此模塊中有個比較難把握的地方: 維度越高越能準確的定義數據,但也會越復雜度 。
你大概不會希望花3天分析出2天前的流失用戶吧!! :)
2.1 分區收集
在用戶流失分析中,若采集時間過長,可能在流失判斷出來時客戶已然流失;若采集時間過于緊密或者實時采集則需要考慮運營商現有系統的支撐能力。因此對數據采集時間間隔的設置顯得尤為重要。
2.2 減少數據噪音
2.3 剔除部分冗余數據
此間要注意的是在客戶流失分析上,從數據倉庫中采集數據的主要目的是調查客戶信息的變化情況。一些不必要的數據就去除掉吧
3. 分析數據 : 熱身,很重要!
3.1 數據抽樣
多說了,在這信息爆炸的時代,別說你把上百TB的數據放到應用分析庫中去!
3.2 數據轉換
比如時間方面:可以把上午轉換為 1 ,中午轉換為 2 等等.便于分析
3.3 缺損數據處理
3.4 樣本生成
建模樣本:為下個階段準備
測試樣本: 對模型進行修正和檢驗
4. 模型建立 : 找個合得來的過這一輩子吧!
對數據進行分析并利用各種數據挖掘技術和方法在多個可供選擇的模型中找出最佳模型,這個過程是一個循環迭代的過程.
建立模型通常由數據分析專家配合業務專家來完成
4.1 常用的流失分析模型主要有 決策樹 / 貝葉斯網絡 / 神經網絡等
5. 模型的評估與檢驗 : 開花!
6. 應用模型 : 終于,結出好果(結果)!
$>流失分析中需要注意的問題
>>過度抽樣
國內電信企業每月的客戶流失率一般在1%~3%左右,如果直接采用某種模型(比如決策樹、人工神經網絡等)可能會因為數據概率太小而導致模型的失效
因此我們需要加大流失客戶在總樣本中的比例,但是這種過度抽樣必須謹慎小心,要充分考慮它的負面效應
>> 模型的有效性
預測出結果,但用戶已經流失 ,主要要關注采樣時間跨度問題
>> 模型的流失后分析
數據挖掘在客戶流失管理中的重要應用不僅僅應包括對客戶流
失的提前預警,還應包括客戶流失后的問題分析。按照不同的客戶信息緯度,查找最容易流失的客戶群,同業務部門人員配合,輔以相關調查,力求發現客戶流失的
癥結所在。然而,這一部分往往由于過度專注于挖掘模型本身的擬合度而忽略了流失管理的實際價值所在。
謝謝 同事 吳 的指導,這他的原話 轉出來供大家學習
0. 我覺得做bi和技術最大的一點差別就是
bi是數據導向,需求的優先級要低于數據
1. 沒數據的話,需求就沒戲了
2. 技術是需求導向,只要有需求,技術基本上都能做出來
3. 數據的加載、加工、清洗,叫做etl,其實和你現在做的事情很像
4. etl是挖掘里非常重要的一部分
參考:數據挖掘在電信客戶流失分析中的應用
http://www.teleinfocn.com/html/2007-02-12/3448.html
beanstalk 消息隊列 小結
協議說明和各狀態轉換情況
基本知識點:
1. 對于beanstalk 消息隊列中每條數據都為 job
2. beanstalk service端 ,會維護 tubes[多個管道]
3. client端可以監聽,使用多 tube
4. client端可以指定 use 管道[ client生成一個新的job時會把此job提交到 指定管道]
5. client端可以指定 watch 管道 [ client接收處理job時會到 指定管道得到待處理的job]
官方示意圖:
put reserve delete
-----> [READY] ---------> [RESERVED] --------> *poof*
一般情況:
1. 任務提交到service端,job 管理放入內存空間并為其標記狀態 [READY]
2. client通過輪訓競爭得到次狀態, job 改為 [RESERVED]
2.1 當在默認時間 120 秒內沒處理完 , job.stats.timeouts 就會大于 0
同時其他 輪訓競爭client會拿到這個job【 注意了 每次timeouts時,在輪訓的客戶端就會得到次job,狀態都為 ready,timeouts>0 】
3. 隨便其中一臺client處理完 job.delete , 其他 client 中的此job 都會 *poof*
deom - python beanstalkc 中 job.stats 參考:
使用 easy_install beanstalkc
API 參考 : http://github.com/earl/beanstalkc/blob/master/TUTORIAL
剛生成的 beanstalk
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120,
'age': 6, 'pri': 2147483648L, 'delay': 0, ' state': ' reserved', ' time-left': 114,
'kicks': 0, 'id': 2}
以timeout了的 beanstalk,并且在其他client輪訓到 job
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 1, 'ttr': 120,
'age': 417, 'pri': 2147483648L, 'delay': 0, ' state': ' reserved', ' time-left': 110,
'kicks': 0, 'id': 2}
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 1, 'ttr': 120, 'age': 415,
'pri': 2147483648L, 'delay': 0, ' state': ' reserved', ' time-left': 4294967163L,
'kicks': 0, 'id': 2}
當沒所有client 的 job 都到期 了 狀態
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 2, 'ttr': 120,
'age': 417, 'pri': 2147483648L, 'delay': 0, ' state': ' ready', ' time-left': 4294967161L,
'kicks': 0, 'id': 2}
{'buries': 0, 'releases': 0, 'tube': 'default', 'timeouts': 2, 'ttr': 120, 'age': 415,
'pri': 2147483648L, 'delay': 0, ' state': ' ready', ' time-left': 4294967163L,
'kicks': 0, 'id': 2}
其中 client1 job.delete
client1 job.stats *poof*
client2 job.stats *poof*
比較全的狀態說明 - [官方文檔]
http://github.com/kr/beanstalkd/blob/v1.1/doc/protocol.txt?raw=true
官方示意圖:
先簡單說明下(完全自己理解的,歡迎拍磚。本人E人太差~看官檔費勁,諒解下):
job.stats狀態 = [READY] 待處理, [RESERVED] 正處理, [DELAYED]延遲狀態 , [BURIED] 隱藏狀態
1. 延遲提交
py.client1.put>>> beanstalk.put('yes!', delay=10)
py.client3.reserve>>> job = beanstalk.reserve()
# 等待 10 秒
2. 管道測試
put-job到service端 可以指定 put的tube管道
如:
py.client1.put>>> beanstalk.use('foo')
py.client1.put>>> beanstalk.put('hey!')
py.client2.reserve>>> job = beanstalk.reserve()
# 一直擁塞,應為 他 watch 管道 'default'
py.client3.reserve>>> beanstalk.watch('foo')
# beanstalk.ignore('bar') 放棄監聽 bar
py.client3.reserve>>> job = beanstalk.reserve()
py.client3.reserve>>> job.body #輸出 'hey!'
3. 隱藏狀態 現在吧 client 1/2/3 的 use watch 的管道都調回 default
py.client2.reserve>>> job = beanstalk.reserve()
py.client3.reserve>>> job = beanstalk.reserve()
py.client1.put>>> beanstalk.put('隱藏狀態!')
py.client2.reserve>>> job.bury() #2 輪訓得到 并且 修改 job 為隱藏狀態
# 120 秒后 client3 沒有輪訓得到 此job
py.client2.reserve>>> job.stats()
{'buries': 1, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120,
'age': 188, 'pri': 2147483648L, 'delay': 0, 'state': 'buried',
'time-left': 4294967228L, 'kicks': 0, 'id': 11}
py.client2.reserve>>> beanstalk.kick( job.stats()['id'] ) #修改狀態為 reserved
# 立刻 client3 得到 job
py.client3.reserve>>> job.stats()
{'buries': 1, 'releases': 0, 'tube': 'default', 'timeouts': 0, 'ttr': 120, 'age': 313,
'pri': 2147483648L, 'delay': 0, 'state': 'reserved',
'time-left': 110, 'kicks': 1, 'id': 11}
# 這時候 client2 / 3 同時 有 job 11 狀態 'buries': 1,'timeouts': 0,'state': 'reserved'
4. peek 窺見
可以得到 一個 stats - read 的 job ,其他 client 可以 job = beanstalk.reserve()
后馬上 job.stats 會變成 [RESERVED]
py.client2.reserve>>> job = beanstalk.peek_ready()
取得 job 并看 本 client 能 處理能
>>> job = beanstalk.peek(3)
>>> job.body
'yes!'
>>> job.stats()['state']
'ready'
這種形式西 job 不能 bury 等修改狀態,但 可以 delete
peek 系類
peek_buried
peek_ready
首先 好東西
http://kr.github.com/beanstalkd/
其次 真的是好東西 支持 java , python ,perl,ruby,erlang 和我不知道的 語言
官方的原文介紹:
$ ./beanstalkd -d -l 10.0.1.5 -p 11300
This starts up beanstalkd as a daemon listening on address 10.0.1.5, port 11300.
Use It
Here’s an example in Ruby (see the client libraries to find your favorite language).
First, have one process put a job into the queue:
beanstalk = Beanstalk::Pool.new(['10.0.1.5:11300'])
beanstalk.put('hello')
Then start another process to take jobs out of the queue and run them:
beanstalk = Beanstalk::Pool.new(['10.0.1.5:11300'])
loop do
job = beanstalk.reserve
puts job.body # prints "hello"
job.delete
end
Thanks
Many thanks to memcached
for providing inspiration for simple protocol design and for the
structure of the documentation. Not to mention a fantastic piece of
software!
使用rsync同步網絡備份
一. 簡介
rsync常用的備份工具, 它目前是由 rsync.samba.org 維護.
rsync使用所謂的"rsync算法",提供一個非常快速的檔案傳輸方法, 使local和遠端二部主機之間的檔案達到同步,它主要是傳送二個檔案的異動部份,而非每次都整份傳送, 因此速度相當地快.
rsync它可以搭配rsh或ssh,也可以當成daemon模式使用直接的socket連接, 所以rsync可以當做一個優異的備份工具來使用.
我這簡單介紹運用rsync備份遠程網路主機檔案的基本方法。
在這,我們是給rsync當成linux的一種daemon模式來運行.
首先,先給個簡單的定義:當然要一臺主機跑rsync daemon模式, 我們就稱這臺機器為一rsync Server, 或者說這臺主機是一臺備份主機( Backup Server).
備份主機會開啟一個873的端口(port), 等待對方rsync連接.所以服務器記的要開這個端口
連接時, rsync Server 會檢查密碼是否相符, 若通過密碼查核, 則開始進行檔案傳輸.
第一次連通完成時, 會把整份檔案傳輸一次, 下一次就只傳送二個檔案之間異動的部份.
以上是rsync client (欲加以備份的遠程網路主機) 和rsync server 的運作方式。
藉由上述方法, 我們當然也可以設立多部備份主機, 使網路主機上重要的檔案能分散至數部主機中, 以分散風險.
一旦完成備份, 我們可以對這些備份主機再做進一步的儲存動作, 如使用tar打成tar的包, 把檔案備份到硬盤之類.
以下內容,我用Ubuntu 7.10做客戶機,Centos5做服務器測試過.
二. 安裝法
rsync目前最新版是 2.6.8, 可以到rsync.samba.org 下載.
若您使用 rpm 套件,請用下面的方法安裝,當然rhel5和centos5中默認就安裝了
#rpm -ivh rsync*.rpm
#yum install rsync
它的設定檔位置在 /etc/rsyncd.conf,奇怪,我的沒有自動生成這個文件,那我們就來自己配置他
三. 設定 rsync server: (假設這臺主機名稱為 rsync.x111.com)
rsync server 端要設定以下四項:
1.規劃建立備份目錄區
2.啟動xinetd中的rsync
3.設定: /etc/rsyncd.conf
4.設定: 密碼檔
依次說明如下:
1. 規劃建立備份目錄區:
建議您準備一個容量較大且獨立的分割區, 并在其中開好備份目錄, 如此 /blackup/x99
2. 啟動xinetd中的rsync
系統默認沒有安裝xinetd。
# yum install xinetd
#service xinetd restart
#chkconfig rsync on
以上的操作,主要是要打開rsync這個daemon,一旦有rsync client要連接時,xinetd會把它轉介給rsyncd (port 873).
3. 設定 /etc/rsyncd.conf :
全局設置
uid = root
gid = root
use chroot = no # 不使用chroot
max connections = 4 # 最大連接數為4
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log # 日志記錄文件
以下的部分,代表開放給某一臺rsync client 主機的設定, 簡單范本如下:
[x99]
path = /blackup/x99/x99_backup
auth users = x99_backup
secrets file = /etc/rsyncd.secrets
read only = no
以上文件的注解:
[x99] 代表要備份的主機代號, 名稱自己設置.
path 用來設定備份檔案要存放在那一個目錄.這個可先要mkdir開好,可以自己設置
auth users 代表授權的帳號, 可以自己設置.
secrets file 代表儲存帳號密碼的密碼檔, 其放置的路徑檔名.
當然, 這臺備份主機, 可以容納許多 rsync client 連接, 只要在 rsyncd.conf中設置對應的多個部分即可.
以下例子,代表二個主機x99及x100欲備份進來:
[x99]
path = /blackup/x99/x99_backup
comment = XXXXX
auth users = x99_backup
secrets file = /etc/rsyncd.secrets
read only = no
[x100]
path = /blackup/x100/x100_backup
auth users = x100_backup
secrets file = /etc/rsyncd.secrets
read only = no
4. 設定密碼文件:
rsyncd.secrets 的內容很容易, 格式為"帳號:密碼";
如以下例子:
x99_backup:x99pass
注意! 上述設定只是一個例子,你自己設置可一定千萬不要直接套用.
接下來, 要將 rsyncd.secrets 這個密碼檔的檔案屬性設為root擁有, 且權限要設為600, 否則無法備份成功!
因此, 請下:
#chown root.root rsyncd.secrets
#chmod 600 rsyncd.secrets
至此, rsync的服務器這端已設定完成, 若欲查看備份日志.
#tail -f /var/log/rsyncd.log
接下來是 client 端(即欲備份的網絡主機) 的設定.
四. 設定 rsync client (假設這臺主機 IP 為 : 11.22.33.44)
步驟:
1.設定密碼檔
2.測試rsync命令是否可以正常
3.將rsync指令放入定時任務(crontab)
另外, 假設x99這臺主機是網路上的服務器, 現打算把/var/www/html這個目錄加以備份至backup server(上面講的rsync.x111.com),
但不想備份下面的目錄中的內容/html/log,(也就是說要把/html/log目錄排除), 整個操作方式如下:
1. 假設把密碼檔放在 /root/rsyncd.secrets, 內容只要含有密碼一行即可:
x99pass
注意: rsyncd.secrets 的權限屬性必須設為600,設置方法見上面.
2. 測試指令是否可以成功?
/usr/bin/rsync
-rvztopglHpogDtS --progress --password-file=/root/rsyncd.secrets
/var/www/html --exclude /html/log x99_backup@rsync.x111.com::x99
若
出現傳輸目錄檔案的畫面,
即表示測試成功.上面這個命令行中-rv里的v是verbose,z是壓縮,r是遞歸,字目錄一直,topg都是保持文件原有屬性如屬主、時間的參數。
--progress是指顯示出詳細的進度情況,--delete是指如果服務器端刪除了這一文件,那么客戶端也相應把文件刪除,保持真正的一致。后面的
x99_backup@ip中,的x99_backup是指的用戶名
3. 置入工作排程, 假設每天凌晨5點開始備份:
crontab -u root -e
0
5 * * * /usr/bin/rsync -rvlHpogDtS --password-file=/root/rsyncd.secrets
/var/www/html --exclude apache /html/log x99_backup@rsync.x111.com::x99
若您有其它目錄(如 /home)要備份, 則如法泡制: 20 5 * * * /usr/bin/rsync
-rvlHpogDtS --password-file=/root/rsyncd.secrets /home
x99_bakup@rsync.x111.com::x99
當然您覺得備份一臺Backup Server不夠,還可再按上述方法,自行增加任意多臺Backup Server, 以分散風險!
五. 安全性:
防火墻的 iptables 指令, 來限制 rsync client 的連線范圍, 例子如下:
iptables -A INPUT -p tcp -s ! xx.xx.xx.xx --dport 873 -j DROP
如此, 只有 xx.xx.xx.xx 這個 client IP 能連入這臺 rsync server.
附:
詳細格式說明:
-v, --verbose 詳細模式輸出
-q, --quiet 精簡輸出模式
-c, --checksum 打開校驗開關,強制對文件傳輸進行校驗
-a, --archive 歸檔模式,表示以遞歸方式傳輸文件,并保持所有文件屬性,等于-rlptgoD
-r, --recursive 對子目錄以遞歸模式處理
-R, --relative 使用相對路徑信息
-b, --backup 創建備份,也就是對于目的已經存在有同樣的文件名時,將老的文件重新命名為
~filename。可以使用--suffix選項來指定不同的備份文件前綴。
--backup-dir 將備份文件(如~filename)存放在在目錄下。
-suffix=SUFFIX 定義備份文件前綴
-u, --update 僅僅進行更新,也就是跳過所有已經存在于DST,并且文件時間晚于要備份的文件。
(不覆蓋更新的文件)
-l, --links 保留軟鏈結
-L, --copy-links 想對待常規文件一樣處理軟鏈結
--copy-unsafe-links 僅僅拷貝指向SRC路徑目錄樹以外的鏈結
--safe-links 忽略指向SRC路徑目錄樹以外的鏈結
-H, --hard-links 保留硬鏈結
-p, --perms 保持文件權限
-o, --owner 保持文件屬主信息
-g, --group 保持文件屬組信息
-D, --devices 保持設備文件信息
-t, --times 保持文件時間信息
-S, --sparse 對稀疏文件進行特殊處理以節省DST的空間
-n, --dry-run現實哪些文件將被傳輸
-W, --whole-file 拷貝文件,不進行增量檢測
-x, --one-file-system 不要跨越文件系統邊界
-B, --block-size=SIZE 檢驗算法使用的塊尺寸,默認是700字節
-e, --rsh=COMMAND 指定替代rsh的shell程序
--rsync-path=PATH 指定遠程服務器上的rsync命令所在路徑信息
-C, --cvs-exclude 使用和CVS一樣的方法自動忽略文件,用來排除那些不希望傳輸的文件
--existing 僅僅更新那些已經存在于DST的文件,而不備份那些新創建的文件
--delete 刪除那些DST中SRC沒有的文件
--delete-excluded 同樣刪除接收端那些被該選項指定排除的文件
--delete-after 傳輸結束以后再刪除
--ignore-errors 及時出現IO錯誤也進行刪除
--max-delete=NUM 最多刪除NUM個文件
--partial 保留那些因故沒有完全傳輸的文件,以是加快隨后的再次傳輸
--force 強制刪除目錄,即使不為空
--numeric-ids 不將數字的用戶和組ID匹配為用戶名和組名
--timeout=TIME IP超時時間,單位為秒
-I, --ignore-times 不跳過那些有同樣的時間和長度的文件
--size-only 當決定是否要備份文件時,僅僅察看文件大小而不考慮文件時間
--modify-window=NUM 決定文件是否時間相同時使用的時間戳窗口,默認為0
-T --temp-dir=DIR 在DIR中創建臨時文件
--compare-dest=DIR 同樣比較DIR中的文件來決定是否需要備份
-P 等同于 --partial --progress 顯示備份過程
-z, --compress 對備份的文件在傳輸時進行壓縮處理
--exclude=PATTERN 指定排除不需要傳輸的文件模式
--include=PATTERN 指定不排除而需要傳輸的文件模式
--exclude-from=FILE 排除FILE中指定模式的文件
--include-from=FILE 不排除FILE指定模式匹配的文件
--version 打印版本信息
--address 綁定到特定的地址
--config=FILE 指定其他的配置文件,不使用默認的rsyncd.conf文件
--port=PORT 指定其他的rsync服務端口
--blocking-io 對遠程shell使用阻塞IO
-stats 給出某些文件的傳輸狀態
--progress 在傳輸時現實傳輸過程
--log-format=FORMAT 指定日志文件格式
--password-file=FILE 從FILE中得到密碼
--bwlimit=KBPS 限制I/O帶寬,KBytes per second
-h, --help 顯示幫助信息
轉自 http://blog.csdn.net/KataDoc360/archive/2009/03/16/3995559.aspx
|