因为在真实环境中 一般方式:
如果一个数据一行:
cat number.txt|sort -n |uniq -c |sort -k1nr -k2nr |head -10|awk -F " " '{print $2}'
如果多个数据一行:
cat number.txt|awk '{for(i=1;i<=NF;i++) a[$i]++} END{for(i in a) print i,a[i]}' |sort -k1nr -k2nr |head -10|awk -F " " '{print $2}'
假如该数据是是个整数 long 类型 在64位 sizeof(long)=8 字节, 一亿个记录占用内存=762M (一亿一个记录占用内存762M) 一个普通云主机2G内存(足够) 计算过程: 这需要统计每个单词出现次数,并且按照次数,数值排序
sort -n: 对数字进行排序 按照从小到大顺序
uniq -c: 统计数字出现次数 ,uniq命令只能对相邻行进行去重复操作
sort -k1nr -k2nr : 根据第一列数据次数 排序,根据数值排序
|awk -F “ “ ‘{print $2}’: 输出结果
单个任务:
find ./ -name visit.log | xargs -n1 awk -F " " '{a[$1]+=1} END{for (i in a) {print i"-"a[i]}}' |sort -t'-' -k2nr |awk '{print $1 }'| head -n 10
多任务
1 大文件分割成小文件
split -l 10 visit.log new
2 统计小文件ip出现次数(8个进程并行处理124个任务,输出结果写到各自文件中)
find ./ -name visit.log | xargs -n1 -P 8 -I{} awk -F " " '{a[$1]+=1} END{for (i in a) {print i"-"a[i] >>"{}.99"}}' {}
2排序 (8个进程并行处理124个任务,输出结果写到各自文件中)
find ./ -name "*99"|xargs -n1 -I {} -P 8 sh -c 'sort -t'-' -k2nr {} -o{}'
3 最后输出ip
find ./ -name "*99" |xargs awk -F "-" '{print $1}'
多机器: parallel可以代替xargs
If you use xargs and tee today you will find GNU parallel very easy to use as GNU parallel is written to have the same options as xargs
初步估算:日志存储空间 16G
1个unsigned int占用4字节,40亿大约是4G个数不到,那么一共大约要用16G的内存空间
说明:下面信息来源网络:
简单来说数据量大,需要内存小,需要拆分文件批量处理, 批量处理特点就是耗时,就需要多线程。
有一个1GB大小的文件,里面的每一行是一个词,词的大小不超过16个字节,内存限制大小是10MB。返回频数最高的100个词。
10M内存还写什么程序,现实生活中还没有遇到这样的情况. 思路回到题目1和题目2 分析 可以参考 <<情景linux—shell如何实现多线程>> 可以简化成下面请看 parallel seq 1 10 |parallel -j10 “sleep 1;echo {}” //10秒的任务 变成1秒完成
关键字:shell 并发