听老歌 发表于 2012-02-24 23:22

awk一种内存溢出的解决


awk一种内存溢出的解决









首先声明这次awk用途,是从一个nginx的access_log中抽取一些关键字,进行访问次数的排序。希望实现的功能很简单,但是日志文件非常庞大,文件大小会超过40G。


步骤一:


在用awk进行解析的时候,报错

awk: (FILENAME=- FNR=4894190) fatal: str2wstr: *ptr: can't allocate 676 bytes of memory (Cannot allocate memory)


也就是说程序内存控制出了问题,有未释放的内容,积累起来出现问题。


代码如下:



view plaincopy
01.awk -F\" '{ if( match($2, "kfuin=(+)") ) print substr($2,RSTART+6,RLENGTH-6)}' log_file > aaa.txt




步骤二:




在awk运行过程中,用top命令进行查看,发现awk占用内存一直在增加。初步分析认为,可能是awk将过多的内容读入内存,进行处理。那么换一种方式是否可以,逐行读入交给awk处理:


view plaincopy
01.cat log_file | awk -F\" '{ if( match($2, "kfuin=(+)") ) print substr($2,RSTART+6,RLENGTH-6)}' > aaa.txt
这种方式会引发同类型的错误:awk: (FILENAME=- FNR=4892857) fatal:Memory exhausted

写一个最简单的awk来验证








view plaincopy
01.<span style="color:#000000;">awk -F\" '{ print $1 }' > aaa.txt</span>

用top命令查看,内存占用几乎为0,而且不会增长。由此判断很有可能awk调用方式的问题。




在google搜索相应内容,有人可能是match函数问题,如果在函数中使用match函数,会引发类似问题。链接地址:http://objectmix.com/awk/115064-memory-exhausted-error-when-match-function-called-two-different-regexp.html





但是显然不是希望的答案,尝试按照里面的方式给正则表达式赋值,和预期一样,问题依然存在。





用man命令,查看match函数的文档

match(s, r [, a])

返回匹配正则表达式r在s中的位置,如果不存在返回0,会将位置和长度信息赋值给RSTART和RLENGTH变量。注意参数顺序与~操作符一样。str ~ re。如果传入第三个数组,a的值会覆盖,将匹配的圆括号中的表达式,从1到n填充给a。a的第0个元素,完整匹配正则r的部分字符串s





步骤三:




尝试使用match函数的第三个参数进行改造




view plaincopy
01.awk -F\" ' match($2, /kfuin=(+)/, matches) { print matches }' log_file > aaa.txt

运行起来,一切正常。





分析:

调用substr产生问题,推断不能在循环中使用substr,结论还有后续验证。





--------------------------------------------------------------------------------------------------------------------------------------------

网上有人分析过sed, awk, head分析大文件的效率。awk效率最高,其次为head,sed效率最低。

# time sed -n '31268618,33573328p' design.acl >/dev/null

real 1m15.584s
user 1m6.727s
sys 0m0.880s
# time awk 'NR>=31268618;NR==33573328{exit}' design.acl >/dev/null

real 0m29.460s
user 0m14.713s
sys 0m0.938s
# time head -33573328 design.acl | tail -31268618 >/dev/null

real 1m8.819s
user 0m3.761s
sys 0m5.090s




好的工具还是要正确使用

Shell_HAT 发表于 2012-02-25 09:42

网上有人分析过sed, awk, head分析大文件的效率。awk效率最高,其次为head,sed效率最低。
这个分析以偏概全了
页: [1]
查看完整版本: awk一种内存溢出的解决