如何优化文件写入速度,根据计算的分库分表,每次文件写入的位置都不同,如果有100w条数据,这样的文件IO是拖慢程序速度
看代码,求大神给优化意见
$inputfile="logs.txt";//输入日志文件,每字段以\t分隔,每行以\n结尾$fp=fopen($inputfile,'r');if(!is_resource($fp)){echo"打开文件".$inputfile."失败,分析日志程序终止";exit(1);}while(!feof($fp)){$row=fgets($fp,4096);str_replace(array("\r","\n"),array("",""),$row);//去除行中的换行符if($row==''){continue;}$arrRec=explode("\t",$row);//将一行字符串以\t分隔为数组$accountid=$arrRec[6];//账户id//下面由文字说明/***根据一行中的$accountid,调用底层函数算出分库分表位置*例如分库为groupid=5*分表名为table_0001*/$groupid=5;$tableid="table_0001";//在此处拼接要写入的文件路径$outputfile="tmp/".$groupid."/".$tableid;//这个值每读一行数据,根据accountid计算的的结果都会变$content="\t".$arrRec[0]."\t".$accountid."\t".$groupid."\n";//拼接要写入文件的内容if(file_put_contents($outputfile,$content,FILE_APPEND)){$success++;$content='';}else{$failure++;}}fclose($fp);
每次只能写入一条数据,100w条大约要30分钟,速度很慢,如何优化;经测试,如果目标文件路径不变,将全部要写入的内容拼接为一个长字符串,然后在while循环结束后面调用一次file_put_contents函数,一次性将全部内容写入文件速度回快很多;但现在遇到的问题是每次写入的目标路径都会改变,求优化意见
这个问题的文件IO的瓶颈在于文件写速度,以及每次循环计算出的分库分表位置都不同,解决方案是将建立一个数组,数组的key记录目标文件的dbid,tablid,三维数组,用于存放分库分表的结果,即通过数组将要写入的内容进行分组,然后在遍历完日志文件后,将每个分组的内容一次性写入文件中,优化后的流程是将原来的每条数据进行一次文件IO,改变为先将文件分组,以组为单位进行写入,这样减少了文件IO次数,每个分库分表文件只进行一次文件IO,这样大大提高的效率,唯一不足是占用的内存更大了
文件写入速度基本上和程序没太大关系。。瓶颈都在于硬件性能上。。
换SSD固态硬盘吧
把file_put_contents
换成fwrite
呢?
服务器换SSD
为什么要写到文件里?可以在Redis里建立多个数据结构,写到里面。
写到mongodb里行吗?适合数据比较多,但是价值不是很大的数据的存储。写到文件里,本身就不太优雅。
机器的瓶颈本来就是IO,优化硬件吧