共计 3517 个字符,预计需要花费 9 分钟才能阅读完成。
【摘要】
本文剖析大文件计算的实现原理,如过滤、聚合计算、增加计算列、排序、分组聚合、topN 等,以及利用并行计算来进步计算速度,并用 esProc SPL 举例说明如何用简洁的脚本实现大文件计算。请点击大文件上的结构化数据计算示例理解详情
在数据分析过程中,常常会解决文本文件中的结构化数据(txt,csv 等),有时这些文件还会很大,计算机内存不足以一次性读入。这时,只能将数据分批读入内存,对每批数据计算出长期两头后果,分批解决完当前,再依照计算要求对分批处理结果进行失当的汇总解决,与一次性装入内存的小文件数据计算有很大的不同。
实现大文件计算须要理解一个重要的概念—游标。咱们以前比拟熟知的是数据库游标,在数据库中应用游标,能够每次返回局部数据,而不将所有数据同时读入内存。游标相似于一个指针,在读取时会通过挪动指针的地位来从后果集中每次提取局部记录。与数据库游标相似,在读取大文件数据时,也须要实现文件游标,它具备以下特点:
1、只用于获取数据,并不用来批改后果集。
2、在读取数据时从前向后只遍历一次。
有了游标对象,就能够把大文件计算步骤顺次附加在游标对象上,在进行最初计算时,再逐条取出记录,按附加的步骤进行计算。
本文将以结构化文本文件为例,给出大文件过滤、聚合计算、增加计算列、排序、分组聚合、topN 以及并行计算等指标工作的实现办法,并提供用 esProc SPL 编写的代码示例。esProc 是业余的数据计算引擎,其采纳的 SPL 中有欠缺的游标对象及运算,解决这些运算十分不便。
1. 过滤
过滤就是设置一个条件表达式,而后用每条记录的数据来计算表达式的值,如果计算结果值为真则本条记录无效,须要增加到最初取数的后果集里,否则就抛弃这条记录不必取出。对大文件过滤是一种提早计算,就是先把过滤表达式记在游标对象上,等到取某条记录时,再计算过滤表达式来决定是否将本记录退出后果集。
示例:在大数据学生问题文本文件 students_scores.txt 中,查找 10 班学生的问题。列数据间用 TAB 分隔,局部数据如下图:
esProc SPL 脚本如下:
2. 聚合计算
聚合计算是对大文件中的所有记录,执行某种统计计算,比方统计总和、平均值、最大值、最小值、计数等。循环遍历游标中所有记录,用每条记录数据计算出以后的聚合统计值,只把统计值存在内存中,而不必保留数据记录,就不会占据太多内存。遍历结束后就失去最终的统计值。
示例:在大数据学生问题文本文件 students_scores.csv 中,列数据间用逗号分隔,局部数据如下图:
计算语文问题总分,esProc SPL 脚本如下:
计算 10 班语文问题总分,esProc SPL 脚本如下:
3. 增加计算列
增加计算列是指用文件中的一列或几列通过某种指定计算,将计算结果记为一个新列的列值。这也是一种提早计算,当读取某条记录时,再计算表达式的值,将它赋给本记录的新列。
示例:在大数据学生问题文本文件 students\_scores\_.txt 中,列数据间用 | 分隔,局部数据如下图:
计算每位学生的总成绩,esProc SPL 脚本如下:
除了用 derive 减少新列,也能够用 new 函数创立新的数据结构,同时也能够减少新的列,例如:
当然,也能够先对数据进行过滤,再对须要的记录产生新列或生成新的构造。例如只取出 10 班的学生问题并新增总成绩列,esProc SPL 脚本如下:
在获取到最终计算结果之前,各种根本计算,如过滤、新增列、产生新构造、扭转字段值、排序等,都能够按需要先后附加到游标上。前面大节的示例中就不再一一列举这些了,只列出大节所讲的主题计算。
4. 排序
大文件排序因内存不足,不能读入所有数据来排序,实现的原理是这样的:先读入一批数据记录,读多少行适合要依据内存而定,将这批数据排序后存到一个临时文件,再读入下一批数据排序后存到另一个临时文件……直到所有数据处理完,最初对这些临时文件进行有序归并——读出每个临时文件的第一行,通过对排序字段值的比拟,找出应该排在最后面的那一行,写入到后果文件。而后从方才排第一的那个临时文件中再读出下一行,持续比拟找出最后面的一行写入后果文件。按此办法一直进行,直到所有数据行都写入后果文件。
示例:在大数据学生问题文本文件 students_scores.txt 中,按语文问题升序排列。
esProc SPL 脚本如下:
也能够同时按多个字段排序或按表达式计算值排序,如将 A2 单元格改为:
=A1.sortx(Chinese,Math) // 按语文、数学问题先后排序
=A1.sortx(Math+English+Chinese) // 按总成绩排序
5. 分组聚合
分组聚合是先对数据记录进行分组,对同一组的记录进行某种统计计算,最初失去每一组的统计值。大文件的分组聚合分两种状况:一是分组的后果不大 (组数少),所有分组后果都能在内存中放下,称之为小分组聚合;二是分组的后果很大 (组数十分多),内存中存不下所有的组,称之为大分组聚合。
小分组聚合的实现原理是:把分组键值和组统计值保留在内存中,在读取每条记录时,按分组表达式计算出分组键值,在保留的组里查找此键值,找到了则将本记录的数据与组统计值汇总,没找到则新退出一个组。最初直到所有行都解决完,就失去了所有的分组和本组的统计值。
示例:在大数据用户登录记录文件 user\_info\_reg.csv 中,统计各省用户的登录总次数及总时长。列数据间用逗号分隔,局部数据如下图:
esProc SPL 脚本如下:
大分组聚合因内存不足,不能把所有分组聚合的后果放在内存里,所以须要分批解决,并应用临时文件保留分批后果,最初再归并汇总,实现原理是这样的:逐行读入数据,依照小分组聚合的流程进行分组聚合,当保留的分组后果集大到肯定程序时 (后果集大小视内存决定),将此后果集按分组键值排序后存为临时文件,从内存中革除。持续读入数据作同样解决,当所有数据处理完当前,就失去了多个按分组键值排好序的临时文件。而后对这些临时文件的数据作有序归并 (与大文件排序的归并流程雷同),失去一个按分组键值排序、键值很可能有反复的大文件,最初把那些反复键值的组合并成一组,失去所有分组后果大文件,再返回用此文件创建的游标供调用者提取分组后果数据。
示例:在大数据用户登录记录文件 user\_info\_reg.csv 中,统计每个用户的登录总次数及总时长。
esProc SPL 脚本如下:
6. TopN
TopN 是对数据排序当前,查出前 N 条记录。有时须要对所有数据求前 N 条记录,有时还须要先对数据分组,再求每一组中的前 N 条记录。
但计算 TopN 时其实不须要对所有数据排序,那样会在排序上破费很多工夫,对大文件计算尤其如此。TopN 的实现原理是这样的:先读出 N 条记录,造成一个 N 条记录的小数据集并排好序,再读新的记录时,与小数据集的最初一条比拟,若排在它之后,则间接抛弃这条记录,若排在它之前,则将这条新记录插入到小数据集的适合地位,抛弃小数据集的最初一条记录。当所有数据都读出并解决完时,就失去了须要的前 N 条记录集。TopN 的实现形式和聚合运算很像。
示例:在大数据学生问题文本文件 students_scores.txt 中,查找数学问题排在前 10 的学生记录。
esProc SPL 脚本如下:
top 函数除了返回前 N 条记录,也能够返回前 N 个值。例如查找排在前 10 的数学问题,esProc SPL 脚本如下:
TopN 还能够应用到分组中,即每个组中取 TopN,其计算原理也相似,只是须要为每个分组放弃一个 N 条记录的小数据集。
示例:在大数据学生问题文本文件 students_scores.txt 中,查找各班数学问题排在前 10 的学生记录。
esProc SPL 脚本如下:
7. 并行提速
并行计算就是用多个线程同时分担一个计算工作,能充分利用多核 CPU 进步计算性能,这对于大文件特地有用。大文件计算经常须要将数据分批计算,最初再将分批计算结果进行合并汇总。并行计算也是如此,先将大文件分段,每个线程各自用大文件计算的形式解决一段数据,最初将各线程解决的后果进行汇总。示例:在大数据用户登录记录文件 user\_info\_reg.csv 中,统计各省用户的登录总次数,用 4 路并行计算进步速度。esProc SPL 脚本如下:
示例:在大数据学生问题文本文件 students_scores.csv 中,查问各班语文问题在 90 分以上且总成绩排在前 5 名的学生,并用 8 路并行进步速度,esProc SPL 脚本如下:
通过以上示例能够看出,在 SPL 中应用并行提速非常容易,与单线程代码相比,仅仅多一个游标选项与参数,让用户应用并行十分不便。
《SPL CookBook》中有更多麻利计算示例。