gpt4 book ai didi

java - 高效的数据结构来存储数百万条记录

转载 作者:可可西里 更新时间:2023-11-01 17:00:20 36 4
gpt4 key购买 nike

我有一个包含数百万条记录的输入文件,每条记录又包含数千列,其中每一列都由分隔符分隔。

记录数和列数因文件而异。

我有一个要求,我必须解析这些记录并将它们存储在 java 对象中,以便它可以进一步传递给 Drools 框架以进行列级验证。

这就是我的输入数据和模式文件的样子。

输入文件:

John|Doe|35|10 Floyd St|132|Los Angeles|CA|USA ... and so on 
...
...
Millions records like this

架构文件:

firstName|String|false|20|NA
lastName|String|false|20|NA
age|Integer|false|3|NA
addressLine1|String|false|20|NA
addressLine2|String|false|20|NA
city|String|false|5|NA
state|String|false|10|NA
country|String|false|10|NA

我试图在 map 的帮助下实现这个解决方案,并创建了一个包含这个 map 的 Java 类。

class GenericRecord {
Map<String,FieldSpecification> properties; //used HashMap as an implementation
}

class FieldSpecification {
public String fieldName;
public String dataType;
public int length;
public String value;
public String format;
}

为了到达输入文件中的行,我正在创建一个 Record 对象并使用 map 来存储其列的值。除此之外,我还将有关列的元数据存储在 FieldSpecification 对象中,例如 dataType 、 length 、format 等。

对于我的输入文件中的几千行,它工作正常,但一旦行数开始增加,它就会因为内存问题而开始失效(正如预期的那样)。因为它正在创建数百万个包含数千个键的对象映射。

我知道这不是解决此类问题的有效解决方案。

所以我担心的是基于内存的解决方案是否适用于我的场景,或者我必须更喜欢基于磁盘的解决方案,如嵌入式数据库或基于磁盘的 map 。

请告知是否有任何其他我可以使用的开源 Map 实现。

注意:对于文件解析和数据验证,我使用的是 hadoop,它运行在一个 40 节点的集群上。

这是我的映射器的流程和实现:

接收作为完整行的值,稍后将此行传递给 Java 框架,Java 框架将其转换为相应的 GenericObject(如上所述),然后将此对象传递给 drools 框架以进行进一步验证。

映射器实现:

public void map(LongWritable key , Text value , Context context) throws IOException, InterruptedException {

//Convert the text value to string i.e line by line comes here
String record = value.toString();





// Develop a drools service that will take record as an input
// and will validate it on the basis of XL sheet provided
workingMemory = knowledgeBase.newStatefulKnowledgeSession();
DroolsObject recordObject = DroolsServiceImpl.validateByRecord(record, fileMetaData, workingMemory);



//Check to validate if the processed record
if(recordObject.isValid) {
context.getCounter(AppCounter.VALID_RECORD).increment(1);
mapperOutputKey.set("A");
mapperOutputValue.set(recordObject.toString());
context.write(mapperOutputKey,mapperOutputValue);
}

else {
context.getCounter(AppCounter.INVALID_RECORD).increment(1);
mapperOutputKey.set("R");
mapperOutputValue.set(recordObject.toStringWithErrors());
context.write(mapperOutputKey,mapperOutputValue);
}
}

最佳答案

由于您必须将文件中数据的每个字节都保存在内存中(分隔符可能除外),因此首先要查看文件的大小并将其与内存的大小进行比较。如果您的文件比内存大,请从头考虑将其保存在内存中的想法。

如果内存大于文件,你还有机会,但你需要仔细检查这个文件将来可能会如何增长,程序将运行在什么平台上等等。

所以假设它适合,您可以更有效地使用您的数据结构。一种节省内存的简单方法是废弃 map 并将每条记录保存为字符串(在文件中编码)。字符串数组应该具有最小的开销,但您需要确保在填充原始数组时不会不断调整其大小。

在数据变大时保持简单的数据结构可以节省大量内存开销。

此外,如果数据很容易装入内存,您可能需要对 JVM 进行一些调整以为其分配足够的内存(更改堆大小 using -Xmx )以使 JVM 足够大。我希望您在 64 位平台上使用 64 位 JVM。

关于java - 高效的数据结构来存储数百万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25067915/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com