`

一个千万级数据的统计方法尝试

阅读更多

现在,我们有一个文件,样子长成这个样子的:

该数据共有两列数据,col1,col2.col1是字符串类型的,col2为数字类型。这样的数据一共有多少呢?

一共有:25165824。

 

现在我们的目标是统计col1中每个值出现的次数,并把对应的col2的值加起来,并且得到平均值。

这样是放在关系数据库里,用SQL的话,十分容易搞定,SQL如下:

 

 

select col1                        name
         ,count(1)                 count
         ,sum(col2)               sum
         ,sum(col2)/count(1) avg
from   table_t
group by col1;

 

就这么简单。

 

然而假如没有数据库,怎么办呢?

 

其实解决方案很多,本文尝试使用一种最简单的,不需要使用任何第三放的软件或者代码支持的方法搞定这个问题。

面对这种格式固定的流式数据,最好的统计方法就是awk。(在求count的问题上,作者也曾尝试使用sort | uniq -c 的方法,但数据量太大,sort太慢,最终放弃。)

 

方案一:

直接扫描25165824条数据,逻辑如下:

BEGIN{
    FS=",";
}
{
    if($1 in count){
        count[$1]+=1;
    }
    else{
        count[$1] =1;
    }
    if($1 in sum){
        sum[$1] +=$2;
    }
    else{
        sum[$1] = $2;
    }
}
END{
    for(x in count){
        print x":"count[x]":"sum[x];
    }
} 

简单吧,逐行扫描全部数据,分别统计count、和sum值。最后求avg就是一个除法的问题了,此处不讨论。

改方案在本人thinkpad r61i上耗时18s~20s。

 

方案二:

 

将全部数据分成不同的分,分别计算每份数据结果,然后进行汇总求值。呵呵,思想有点类似map/reduce。只不过我就一台电脑哈。

在该方案中,作者尝试了不同的划分方法。

分别将数据每10000000、5000000、3000000分成一份。

然后分别进行统计,在全部统计之后,将结果汇总起来。

在计算正确的前提下,耗时分别为13s、11s、10s (经过多次测试之后的平均值,在测试时,基本完全消耗一核CPU。由于是双核系统,cpu load基本上在0.9~1.1之间。)

 

显然,该方案比直接跑全部数据要来的快。基本上减少了6~7s的时间。但也发现,在不同的数据分割方案之间,时间相差不大。可能是计算任务已经占满了CPU,在该条件下已经极限了吧。

 

下面是计算逻辑,以每5000000条数据为一份举例:

 

首先是整体计算逻辑:

cal.sh

#!/bin/bash

rm a b c d e f

awk -f map.awk taa > a &
awk -f map.awk tab > b &
awk -f map.awk tac > c &
awk -f map.awk tad > d &
awk -f map.awk tae > e &
awk -f map.awk taf > f &

while true
do
    if [ -s a ] && [ -s b ] && [ -s c ] && [ -s d ] && [ -s e ] && [ -s f ] ; then
        break;
    fi
done

cat a>>f
cat b>>f
cat c>>f
cat d>>f
cat e>>f


awk -f reduce.awk f

通过代码,不难理解其中的逻辑吧。

 

其次是用来统计每份数据的map.awk文件:

map.awk:      

BEGIN{
    FS=",";
}
{
    if($1 in count){
        count[$1]+=1;
    }
    else{
        count[$1] =1;
    }
    if($1 in sum){
        sum[$1] +=$2;
    }
    else{
        sum[$1] = $2;
    }
}
END{
    for(x in count){
        print x":"count[x]":"sum[x];
    }
}

该逻辑与之前全部数据扫描的逻辑一致,只是每次面对的数据不同而已。

 

最后是用于将每份数据汇总起来,计算最终结果的逻辑:

reduce.awk:

BEGIN{
    FS=":";
    printf("%20s%20s%20s%20s","col1","count","sum","avg");
}
{
    if($1 in count){
        count[$1] += $2;
    }
    else{
        count[$1]  = $2;
    }
    if($1 in sum){
        sum[$1] += $3;
    }
    else{
        sum[$1]  = $3;
    }
}
END{
    for(x in count){
        printf("%20s%20i%20i%20.2f\n",x,count[x],sum[x],sum[x]/count[x]);
    }
}

其实将每份数据汇总到一起的逻辑是cal.sh中的那一堆"cat >>",该reduce.awk只是将每份数据计算的结果汇总,计算并打印最终结果,最终结果如下:

 

 

总结:

 

本文尝试使用awk解决数据统计的问题,通过切分数据充分利用cpu资源进行数据统计。

如果该任务跑在分布式存储系统上,并通过真正的map/reduce进行并行计算,我想想过会更好的吧。

 

呵呵,敬请期待,探索还在继续...

  • 大小: 11.4 KB
1
3
分享到:
评论

相关推荐

    java快速插入千万级数据

    java快速插入千万级数据,亲测91秒插入1700万数据!!!

    实现千万级数据的分页显示

    在处理大规模数据集时,如何高效地进行分页显示成为了一个关键的技术挑战。传统的分页方法在面对数百万甚至上千万的数据记录时,往往会出现性能瓶颈,导致用户体验下降。本文将详细介绍一种能够在5秒内获取1448万条...

    批量导出CVS-千万级数据处理

    如果需要处理大量的数据,POI的分块写入功能无疑是一个更好的选择,它可以确保在处理千万级数据时系统稳定运行,不会因为内存溢出而崩溃。 总结,批量导出CSV文件,特别是面对千万级数据时,理解并合理运用POI的...

    mysql快速导入百万级千万级数据.zip

    mysql快速导入百万级千万级数据 mysql快速导入百万级千万级数据 mysql快速导入百万级千万级数据 mysql快速导入百万级千万级数据 mysql快速导入百万级千万级数据 mysql快速导入百万级千万级数据

    千万级数据分页查询存储过程SQLServer

    总的来说,利用SQL Server的存储过程进行千万级数据分页查询,结合合理的索引策略和优化技巧,能够有效提升查询性能,降低系统负载,为用户提供流畅的浏览体验。请参考“分页.txt”和“使用方法.txt”文件,了解更多...

    java实现csv导出千万级数据实例

    本实例聚焦于“java实现csv导出千万级数据实例”,旨在提供一个高效、稳定的解决方案,避免因数据量过大而导致的性能问题,如Java中的栈溢出(Stack Overflow)。CSV(Comma Separated Values)格式因其简单、通用性...

    使用Python Pandas处理亿级数据的方法

    在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,Hadoop才是一个合理的技术选择。这次拿到近亿条日志数据,千万级数据...

    千万级数据Sql Server 与Mysql分析

    SQL Server 2008 基于 Windows 平台,它提供了一个大型的资源网络、行业领先的性能和企业级的可扩展性、最高级的安全性、一个广泛的商业智能平台——以一个较低的总体拥有成本(TCO)提供所有这些。Mysql 是一种轻量级...

    数据库迁移 数据迁移 千万级 亿万级数据MySQL oracle关系型

    现需要开发一套程序用来快速迁移数据库,要求如下: 1.使用人员可以指定迁移数据库类型 如:(orcal,sqlServer,csv 迁移至mysql) 2.在迁移数据库时,可以只迁移指定字段. ...4.保护数据完整性,设计失败处理

    mysql千万级数据脚本测试shardingjdbc-course.zip

    本案例涉及的是一个针对MySQL数据库的千万级数据脚本测试,使用了ShardingJDBC这一分布式数据管理框架。接下来,我们将深入探讨相关知识点。 首先,MySQL是一个广泛使用的开源关系型数据库管理系统,其在处理大量...

    千万级数据分页操作方法

    数据库优化操作实现数据分页,数据量在千万级分页效果依然很流畅,该文件已经在实际项目中应用,并且效果很不错的!

    实现千万级数据分页的存储过程

    本文介绍了一个用于实现千万级数据分页的SQL存储过程。该存储过程名为`GetRecordFromPage`,由作者铁拳于2004年7月4日创建。经过测试,在含有14,483,461条记录的数据集中,查询第100,000页(每页10条记录)时,无论...

    oracle千万级别数据简单操作

    - 此命令用于向 `test1` 表添加一个新分区 `P20160501`,其中包含所有交易日期小于2016年6月1日的数据,并将其存储在 `S2` 表空间中。 3. **优化策略**: - **定期调整分区**:随着数据的增长或变化,可能需要...

    mysql 千万级数据优化

    _mysql 千万级数据优化_ MySQL 是一种流行的开源关系数据库管理系统,在大规模数据处理中,MySQL 的性能优化变得非常重要。下面我们将从查询优化和 SQL 编写注意事项两个方面来讨论 MySQL 千万级数据优化。 查询...

    千万级数据分页存储过程

    本文将深入探讨如何设计和实现一个用于处理千万级数据分页的存储过程,并基于提供的"存储过程分页.sql"文件进行解析。 首先,我们需要理解分页的基本概念。分页是将大量数据分成小块(页)进行显示,以避免一次性...

    千万级数据的分页显示

    mssql实现千万级数据的分页显示,超级好用

    mysql 千万数据表 t_order.zip

    在数据库管理领域,MySQL是一个广泛使用的开源关系型数据库系统,尤其在处理大量数据时,其性能和效率备受赞誉。本文将深入探讨如何管理和优化存储着千万级别数据的表,以"t_order"为例,该表可能存在于您提供的...

    最快的排序算法 千万级亿级数组排序最快的实现方法,排序算法数据结构

    在文章的部分内容中,我们可以看到,作者实现了一个使用哈希表(HashMap)来对大规模数据进行排序的算法。该算法的思路是将数组中的元素存储到哈希表中,然后根据哈希表中的键值对进行排序。该算法的时间复杂度为O(n...

    千万级数据sql优化_索引

    千万级数据sql优化_索引,大概从12个角度层次阐述哪些可以通过索引进行优化,哪些关键词会影响到索引的使用

Global site tag (gtag.js) - Google Analytics