繁体   English   中英

处理大型CSV文件的最佳方法是什么?

[英]What is the best way to process large CSV files?

我有一个第三方系统,每天生成大量数据(这些是存储在FTP上的CSV文件)。 正在生成3种类型的文件:

  • 每15分钟(2个文件)。 这些文件非常小(约2 Mb
  • 每天下午5点(约200 - 300 Mb
  • 每个午夜(此CSV文件约为1 Gb

总体而言,4 CSV的大小为1.5 Gb 但是我们应该考虑到每15分钟生成一些文件。 这些数据也应该汇总(不是那么难的过程,但肯定需要时间)。 我需要快速回复。 我正在考虑如何将这些数据和整体存储在实现上。

我们有java堆栈。 该数据库是MS SQL Standard 根据我的测量结果, MS SQL Standard与其他应用程序无法处理此类负载。 我想到了什么:

  • 这可能是使用单独的服务器升级到MS SQL Enterprise
  • 在单独的服务器上使用PostgreSQL 现在我正在为这种方法开发PoC。

你会在这推荐什么? 可能有更好的选择。

编辑#1

这些大文件是每天的新数据。

您可以考虑查看Apache Spark项目。 验证和策划数据后,可以使用Presto运行查询。

您可以使用uniVocity解析器尽快处理CSV,因为这个库附带了最快的 CSV解析器。 我是这个库的作者,它是开源和免费的(Apache V2许可证)

现在要将数据加载到数据库中,您可以尝试使用univocity框架 (商业)。 我们使用它可以非常快速地将大量数据加载到SQL Server和PostgreSQL等数据库中 - 从25K到200K行/秒,具体取决于数据库及其配置。

这是一个简单的示例,说明从CSV迁移的代码如何:

public static void main(String ... args){
    //Configure CSV input directory
    CsvDataStoreConfiguration csv = new CsvDataStoreConfiguration("csv");
    csv.addEntitiesFromDirectory(new File("/path/to/csv/dir/"), "ISO-8859-1");

    //should grab column names from CSV files
    csv.getDefaultEntityConfiguration().setHeaderExtractionEnabled(true);

    javax.sql.DataSource dataSource = connectToDatabaseAndGetDataSource(); //specific to your environment

    //Configures the target database
    JdbcDataStoreConfiguration database = new JdbcDataStoreConfiguration("database", dataSource);

    //Use only for postgres - their JDBC driver requires us to convert the input Strings from the CSV to the correct column types.
    database.getDefaultEntityConfiguration().setParameterConversionEnabled(true);

    DataIntegrationEngine engine = Univocity.getEngine(new EngineConfiguration(csv, database));

    //Creates a mapping between data stores "csv" and "database"
    DataStoreMapping mapping = engine.map(csv, database);

    // if names of CSV files and their columns match database tables an their columns
    // we can detect the mappings from one to the other automatically
    mapping.autodetectMappings();

    //loads the database.
    engine.executeCycle();

}

为了提高性能,该框架允许您管理数据库模式并执行诸如删除约束和索引,加载数据以及重新创建数据等操作。 如果需要,还可以很好地支持数据和模式转换。

希望这可以帮助。

好的。 花了一些时间解决这个问题(包括阅读,咨询,试验,做几个PoC)。 我提出了以下解决方案。

文艺青年最爱的

数据库PostgreSQL因为它适用于CSV,免费和开源。

工具Apache Spark非常适合此类任务。 很好的表现。

D B

关于数据库,决定是一件重要的事情。 选择什么以及将来如何使用这么多数据。 它绝对应该是一个单独的服务器实例,以便不在主数据库实例上生成额外的负载而不阻止其他应用程序。

NoSQL的

我在这里考虑过使用Cassandra ,但是这个解决方案现在太复杂了。 Cassandra没有临时查询。 Cassandra数据存储层基本上是一个键值存储系统。 这意味着您必须围绕所需的查询“建模”数据,而不是围绕数据本身的结构。

RDBMS

我不想在这里过度工程。 我在这里停止了选择。

MS SQL Server

这是一种方法,但这里的重大缺点是定价。 很贵。 考虑到我们的硬件,企业版需要花费很多钱。 关于定价,您可以阅读此政策文件

这里的另一个缺点是支持CSV文件。 这将是我们的主要数据来源。 MS SQL Server既不能导入也不能导出CSV。

  • MS SQL Server静默方式截断文本字段。

  • MS SQL Server的文本编码处理出错。

MS SQL Server抛出错误消息,因为它不理解引用或转义。 有关该比较的更多信息可以在文章PostgreSQL与MS SQL Server中找到

PostgreSQL的

这个数据库是一个成熟的产品,也经过了很好的战斗测试。 我从其他人那里听到了很多积极的反馈(当然,还有一些权衡)。 它具有更经典的SQL语法,良好的CSV支持,而且它是开源的。

值得一提的是, SSMSPGAdmin更好。 SSMS具有自动完成功能,具有多个结果(当您运行多个查询并在一个查询中获得多个结果时,但在PGAdmin中您只获得最后一个结果)。

无论如何,现在我正在使用JetBrains的DataGrip

处理工具

我查看了Spring BatchApache Spark Spring Batch对于此任务来说有点太低级了,而且如果将来需要它, Apache Spark还提供了更容易扩展的能力。 无论如何, Spring Batch也可以做这项工作。

关于Apache Spark示例,代码可以在learning-spark项目中找到。 我现在选择的是Apache Spark

Pentaho数据集成(或类似的ETL工具)可以处理将数据导入SQL数据库,并可以即时进行聚合。 PDI具有社区版本,可以独立运行或通过Java API运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM