php比对两组数据库,PHP多进程解决4.2G文件与库2.5亿条数据比对取出异同数据

34f5fe359d4160a88ff2f069d91186f9.png

一、多进程主函数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);

}

三、查看后台是子进程的脚本是否运行

90262eacb8ab150b847752000071e026.png

四、确认后即可,杀死进程

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

输出格式要求: <2><1363655799068800>1363655799068800>2>

上代码:

for i in {0..199}

do

comm

| awk '{("echo -n "$0"| md5sum ")|getline a; print $0"\t"a}' \

| awk '{printf "<2>""\n"}' >> deleteAllresult.txt2>

done &

注意了: 在执行这段代码的时候直接在命令窗口执行,不要放入到shell中,要不然总报错command substitution: `comm

后续:

目的虽然实现了,那这样是否是最好的呢,于是乎我之前把 4.2G的源文件 跟 5.3G的数据库文件直接对比。

comm

| awk '{("echo -n "$0"| md5sum ")|getline a; print $0"\t"a}' \

| awk '{printf "<2>""\n"}' >> __TestDeal.txt &2>

来看下CUP和内存使用率

91da79e70aae6fa2097dc34480fc4fb7.png

发现100% 死个熊的了,具体是谁跑死的CPU呢,再看下面. 有个sort, 单独查下sort是啥东西.

f7d304252c912215f12c3833fa34a844.png

是对比,发现这种方案不行, kill 掉

总结: 在任何的项目场景中根据手头资源和项目的可应用性而定使用何种解决方案,没有最好的,只有最合适的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值