亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 5411 | 回復(fù): 3
打印 上一主題 下一主題

[文本處理] [原]如何使用 aria2c + taskset + mawk 實(shí)現(xiàn)并發(fā)多任務(wù)、多線程下載并快速分割XML [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2013-07-20 22:23 |只看該作者 |倒序?yàn)g覽
本帖最后由 ailms 于 2013-07-22 10:32 編輯

原文鏈接 :http://blog.ailms.me/2013/07/20/ ... wk-for-xml-job.html

完整腳本 :http://static2.ailms.me/scripts/tuan-proc.tar.gz

受人之托寫一個(gè)腳本,需求如下

1、定時(shí)從多個(gè)團(tuán)購網(wǎng)站下載 XML (全量,有些超巨大)

2、要并發(fā)下載+實(shí)時(shí)處理。也就是不能一個(gè)下載完處理后,再下載第2個(gè),再處理 (話說這個(gè)要求是樓主自己提的 ..)

3、對(duì)下載的 XML 按照每文件1000個(gè)商品的數(shù)量進(jìn)行分割。XML 的格式如下 :<goods id=n></goods> 為一個(gè)商品

<?xml version=”1.0″ encoding=”UTF-8″?>
<data>
<apiversion><![CDATA[3.0]]></apiversion>
<site_name><![CDATA[滿座網(wǎng)]]></site_name>
<goodsdata>
<goods id=”1″>
<xxxx>
<yyyy>
</goods>
<goods id=”2″>
<xxxx>
<yyyy>
</good>
….


針對(duì)第一點(diǎn) :

如何快速下載。wget 是傳統(tǒng)的單線程,所以樓主搜索了一下,有一個(gè) aria2 ,看了一下 man ,非常滿意。實(shí)際測(cè)試速度也很不錯(cuò)。

另外這個(gè)東西功能過于強(qiáng)大,強(qiáng)大到可以支持 session 和 daemon 模式,具體樓主還沒研究,目前只是簡(jiǎn)單使用,其他等待以后吧。

另外有一個(gè)要注意的,因?yàn)椴皇菬o時(shí)無刻這些 XML 都在更新,所以并不需要每次都全量下載,所以樓主用了 HEAD 方法記錄這些

XML 文件的 ETag、Mtime、Size 并存成文件,下次下載前檢查一下這3項(xiàng)信息,并與磁盤上實(shí)際的文件大小比較,如果相同則不下載。

  1. declare -a aria2cOpts=()

  2. aria2cOpts+=("--log $tempDir/$i.log --log-level=info")

  3. aria2cOpts+=("--stop=$(($singleURLTimeout * 60)) --max-concurrent-downloads=10")

  4. aria2cOpts+=("--auto-file-renaming=false --continue")

  5. #aria2cOpts+=("--http-accept-gzip=true --enable-http-keep-alive=true")

  6. aria2cOpts+=("-d $tempDir/ -o ${i}.xml --quiet")

  7. aria2c ${aria2cOpts[*]} $url 2>$logDir/${i}/${i}.err
復(fù)制代碼
針對(duì)第二點(diǎn) :

后臺(tái)多任務(wù)這個(gè)簡(jiǎn)單,但多少才是合適呢? 這個(gè)樓主做了測(cè)試,先是用 wget 下載一個(gè) 500MB 的 XML 文件,記錄下耗時(shí)。

由于這個(gè)時(shí)候沒有指定 CPU cores ,所以默認(rèn)是bind 在任意一個(gè) Cores 都可以。接下來再用 taskset 啟動(dòng)相同的 wget 命令,

但這次不同的是,只bind 到一個(gè) core 。經(jīng)過多次測(cè)試,發(fā)現(xiàn)時(shí)間節(jié)省了 50% ! 所以樓主用下面的代碼實(shí)現(xiàn)了一個(gè)功能,就是

每一輪取出跟 cpu core 數(shù)量相同的下載任務(wù),然后分配到不同的 cpu core 上,再并發(fā)多任務(wù)下載。

  1. cpuCoreNum=$(cat /proc/cpuinfo | grep -c '^processor[[:space:]]')

  2. batchDownloadTask=$(egrep -v '^#|^[[:space:]]* $1 | xargs -n $cpuCoreNum)

  3. count=0

  4. while read line ; do

  5.    (
  6.       <spawn arai2c job>

  7.     ) &

  8.    backgroundJobPid=$!

  9.    sleep 0.5

  10.    taskset -c -p $count $backgroundJobPid &>/dev/null

  11.    info_log "$i" "bind pid [$backgroundJobPid] to cpu #$(taskset -c -p $backgroundJobPid 2>/dev/null | awk -F '[ :]+' '{print $NF}')"

  12.   ((count++))

  13. done  <<< "$batchDownloadTask"
復(fù)制代碼
針對(duì)第三點(diǎn) :

【方法1】一開始是想用 grep + sed 的。就是找到所有 <goods id=n></goods> 行的行號(hào),并把每個(gè) pair 湊成一行。然后

            每1000個(gè)pair做成一個(gè)文件,再取出文件的第一個(gè)和最后一個(gè)數(shù)字,這2個(gè)數(shù)字就是代表1000個(gè)商品的范圍,然

           后動(dòng)態(tài)生成 sed  命令,每次取出指定的范圍。但按照這個(gè)想法實(shí)現(xiàn)后,發(fā)現(xiàn)性能太差了,因?yàn)榧僭O(shè)有10w 個(gè)商品,

           那么需要切割為10次, 意味著需要訪問10次 XML 文件,性能自然不行了,實(shí)際測(cè)試也證明了這點(diǎn):將近10分鐘 ,

          所以不能接受

【方法2】因?yàn)榈谝环N方法的瓶頸是在于 sed 多次訪問XML 文件,所以這次的目的就是如何減少對(duì) XML 文件訪問的次數(shù)。前

             一種方法之所以需要多次訪問,是因?yàn)闆]有找到標(biāo)記“這里是第1000個(gè)商品”的類似信息,如果我們能提供這種信息

             ,那么就可以使用操作系統(tǒng)自帶的 csplit 命令來一次性分割了。所以這次放棄 grep + sed 的組合,先用 awk 讀取文

            件,每讀取1000 個(gè) </goods> 行就打印出一個(gè)標(biāo)記行“—cut-here—“ 。在所有標(biāo)記行打印完畢后,用 csplit 命令分

            割,分割之前需要 grep 檢查一共有多少個(gè)標(biāo)記行。

            

【方法3】第2種方法比起第1種是快了不少,但扔因?yàn)?cpslit 的使用而顯得不夠輕巧,因?yàn)?awk 已經(jīng)可以識(shí)別出每1000 個(gè)

             </goods> 行的所在,所以直接把遇到第n*1000個(gè) <\/goods> 行的內(nèi)容放入字符串,當(dāng)遇到第 n*1000個(gè)</goods>

            行時(shí)就直接 print 到文件,這樣可以最大程度的減少 IO 次數(shù)。但很不幸,這個(gè)方法失敗了,因?yàn)樽址罅耍瑢?dǎo)致

            mawk 執(zhí)行非常久,而且 cpu 的消耗達(dá)到了幾乎 100%

【方法4】既然方法3的字符串存儲(chǔ)行不通,那么就直接輸出到文件。每次打開一個(gè)文件,并將當(dāng)前行輸出到該文件,當(dāng)遇到

             第n*1000個(gè)</goods> 行時(shí),就關(guān)閉文件,同時(shí)設(shè)置一個(gè)新的文件名,繼續(xù)上面的循環(huán)。這個(gè)方法經(jīng)過測(cè)試是最

             快的,+500MB的文件,在30s內(nèi)可以完成切割,而且?guī)缀醪徽?cpu 和內(nèi)存。

————————————————————— 中途休息 —————————————————————————-

樓主用的是 Ubuntu 12.04 ,默認(rèn)安裝的是 mawk 。但對(duì)方是 centOS 5.8 ,安裝的是 gawk ,所以當(dāng)樓主把腳本給到對(duì)方

測(cè)試時(shí),發(fā)現(xiàn)很慢,通過檢查發(fā)現(xiàn)是 awk 的版本不同。所以讓對(duì)方安裝了 mawk ,則速度一下子就提高了非常多。樓主當(dāng)

即進(jìn)行了自測(cè),發(fā)現(xiàn)結(jié)果非常驚人,mawk 是30s 左右,而 gawk 竟然要1分27秒,相差了1.5倍左右。

mawk 是目前已知的性能最高的 awk的實(shí)現(xiàn)。怪不得 Ubuntu 12.04 默認(rèn)安裝的是 mawk

下面是用于切割 XML 文件的 shell 腳本完整代碼,整個(gè)腳本由于比較大,不好貼出,請(qǐng)點(diǎn)擊這里下載

  1. #!/bin/bash

  2. mawk -v _result_dir=$2  -v _flag_line="$3" -v _goods_per_file=$4 '

  3.   BEGIN { count=0 ; batch=0 ; }

  4.   {
  5.     output=_result_dir"/cut."sprintf("%03d",batch)

  6.     output_cmd="cat >>"output

  7.     if ( $0 !~ _flag_line ) {

  8.          print $0 | output_cmd

  9.     } else {

  10.          print $0 | output_cmd

  11.          count++

  12.          if ( count % _goods_per_file == 0 ) {

  13.               fflush(output_cmd)

  14.               close(output_cmd)

  15.               batch++
  16.          }

  17.    }

  18. }' $1

  19. cd $2

  20. lastCutFile=$(ls cut.??? | tail -n 1)

  21. for i in cut.000 $lastCutFile ; do

  22.   sed -r -n '/<goods id=/,/<\/goods>/p' $i > $i.new

  23.   mv $i.new $i

  24. done
復(fù)制代碼
腳本整體輸出如下(一共 2.3GB 的 XML ,5個(gè)) 。由于樓主的 VPS 是在米國,所以下載速度不如國內(nèi),如果是在國內(nèi)執(zhí)行,時(shí)間會(huì)比下面的小

論壇徽章:
15
2015年辭舊歲徽章
日期:2015-03-03 16:54:15雙魚座
日期:2015-01-15 17:29:44午馬
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉雞
日期:2014-04-02 12:24:51雙子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥豬
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大;照
日期:2013-04-17 11:48:45
2 [報(bào)告]
發(fā)表于 2013-07-21 13:25 |只看該作者
謝謝分享。并發(fā)和先比較再下載的主意不錯(cuò)。

論壇徽章:
5
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亞洲杯之朝鮮
日期:2015-03-13 22:47:33IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-09 06:20:00IT運(yùn)維版塊每周發(fā)帖之星
日期:2016-03-07 16:27:44
3 [報(bào)告]
發(fā)表于 2013-07-21 14:17 |只看該作者
回復(fù) 1# ailms


    不錯(cuò),學(xué)習(xí)。

論壇徽章:
1
辰龍
日期:2014-05-22 11:38:58
4 [報(bào)告]
發(fā)表于 2013-07-22 08:54 |只看該作者
好,學(xué)習(xí)了
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP