shell版本:
Q1 为什么 用这个方式实现?
因为在真实环境中
一般方式:
- 首先通过脚本,excel等工具,(很多公司也是excel完成事情)
可以快速验证,出结果. - 然后利用strom等大数据分析平台,通过写对应的jobs来统计指标。
第一题
问: 从一亿个数据中找出 出现次数最多的前10个值?
答:
如果一个数据一行:
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}': 输出结果
第二题
问: 海量日志数据,提取出某日访问百度次数最多的那个IP。
答 :
单个任务:
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的内存空间
-
初步估算:IP个数 16G
IP地址是32位,共有N=2^32=4G个不同的IP地址。
一个IP地址 sizeof(int)=4, 存储ip需要消耗 4G*4=16G
-
初步拆分数据(日志存储空间=IP存储空间)
单核允许的内存空间512M
512M/4=128M 即512M内存可以统计128M个不同的IP地址的访问次数.而N/128M =4G/128M = 32 ,
所以只要把IP地址划分成32个不同的区间。因为4核:
32*4=124个小文件
文件大小 128M/4=62M -
初步估算开启并发进程数量:16
假设单cpu单位时间处理 8个任务, 4个任务/8个任务=0.5 ,负载为0.5
为了重复利用cpu 开启4*4=16个进程。系统整体负载为2。
系统正常运行;
理解Linux系统负荷 参考
http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html
说明:下面信息来源网络:
- 就像2018 年春晚直播期间「淘宝崩溃事件」,也估算错误过一次,
- 文件大小 3.2G,需要一小时来统计
简单来说数据量大,需要内存小,需要拆分文件批量处理,
批量处理特点就是耗时,就需要多线程。
第三题
问:
有一个1GB大小的文件,里面的每一行是一个词,词的大小不超过16个字节,内存限制大小是10MB。返回频数最高的100个词。
答:
10M内存还写什么程序,现实生活中还没有遇到这样的情况.
思路回到题目1和题目2
分析
可以参考 <<情景linux--shell如何实现多线程>>
可以简化成下面请看 parallel
seq 1 10 |parallel -j10 "sleep 1;echo {}" //10秒的任务 变成1秒完成
参考
- 情景linux--shell如何实现多线程
-
https://www.codeword.xyz/2015/09/02/three-ways-to-script-processes-in-parallel/
https://www.jianshu.com/p/33ea8390e7c4
关键字:shell 并发
网友评论