由网络副手--寻路人于2016.01.19 14:19:00发布在编程语言 PHP多进程解决4.2G文件与库2.5亿条数据比对取出异同数据 阅读3486 评论0 喜欢0 ![225153110603554301.jpg][1] 一、多进程主函数ThreadsMain.php 注:计算进程数 = 服务器内核数 * (2~3)倍在多就不太灵了. // @Desc : 查询数据库200个表分多个进程执行 // @Author : BraveDu // @Date : 2016-01-18 class ThreadsMain{ private $dataArr; private $excePath; //指定执行PHP的path private $phpShell = '/usr/local/bin/php'; /* * @Exp * $dataArr = array( array => array('./deal.php','param1','param2',...'paramn', ) 这里面第一个参数即为$excePath */ function __construct($data,$excePath=''){ $this->dataArr = $data; $this->excePath = $excePath ? $excePath : ''; } public function runThreads(){ if(!is_array($this->dataArr)) return false; foreach($this->dataArr as $data){ $pid=pcntl_fork(); if($pid==-1){ //进程创建失败 die('fork child process failure!'); } else if($pid){ //父进程处理逻辑 pcntl_wait($status,WNOHANG); } else{ //子进程处理逻辑 $this->excePath ? array_unshift($data,$this->excePath) : $data; pcntl_exec($this->phpShell,$data); } } } } $array = array( array('1'), array('a'), array('x'), ); $thread = new ThreadsMain($array,'./test.php'); $result = $thread->runThreads(); 二、处理数据库的文件就是普通接收参数查询,这里用test.php 做模拟. for($i=0;$i<1000;$i++){ file_put_contents('test_result_'.$argv[1].'.txt',"{$i} \n",FILE_APPEND); sleep(1); } 三、查看后台是子进程的脚本是否运行 ![ps-ev.jpg][2] 四、确认后即可,杀死进程 ps -ef |grep test.php | awk '{print $2}' | xargs kill -9 五、把4.2G的文件进行分割,然后根据数据id分桶到0~199个文件里面 split -b 30m 文件名. 先把4.2G 打文件分割成小块文件 fileNums=`ls x* | wc -l` for i in `ls x*` do echo "~~excue~~$i~~~"; for c in `cat $i` do if [ $c -eq 0 ] then continue fi echo $c >> ../engfile/result_eng_$(( 10#$c%200 )) done sleep 1 done 到这里文件分桶就完成了. 目前的文件目录为: engfile/result_eng_0~199 dbfile/result_db_0~199 接下来就相同编号的文件进行对比,输出结果. 输出结果要求: 源文件中是如此格式 :1363655799068800 输出格式要求: 上代码: for i in {0..199} do comm <(sort engfile/result_eng_$i|uniq) <(sort dbfile/result_db_$i|uniq) -2 -3 \ | awk '{("echo -n "$0"| md5sum ")|getline a; print $0"\t"a}' \ | awk '{printf """\n"}' >> deleteAllresult.txt done & 注意了: 在执行这段代码的时候直接在命令窗口执行,不要放入到shell中,要不然总报错command substitution: `comm <(sort 后续: 目的虽然实现了,那这样是否是最好的呢,于是乎我之前把 4.2G的源文件 跟 5.3G的数据库文件直接对比。 comm <(sort engsouce/all.doc.final|uniq) <(sort dbfile/dbfile_all.txt|uniq) -2 -3 \ | awk '{("echo -n "$0"| md5sum ")|getline a; print $0"\t"a}' \ | awk '{printf """\n"}' >> __TestDeal.txt & 来看下CUP和内存使用率 ![cpu.jpg][3] 发现100% 死个熊的了,具体是谁跑死的CPU呢,再看下面. 有个sort, 单独查下sort是啥东西. ![sort.jpg][4] 是对比,发现这种方案不行, kill 掉 总结: 在任何的项目场景中根据手头资源和项目的可应用性而定使用何种解决方案,没有最好的,只有最合适的. [1]: http://blogimg.bravedu.com/2016/01/2976719939.jpg [2]: http://blogimg.bravedu.com/2016/01/889673198.jpg [3]: http://blogimg.bravedu.com/2016/01/1882129267.jpg [4]: http://blogimg.bravedu.com/2016/01/3681813147.jpg 赞 0 分享 赏 您可以选择一种方式赞助本站 支付宝扫码赞助 BraveDu 署名: 网络副手~寻路人