如何使用可扩展的解决方案从 java 中的一个非常大的文件中查找唯一记录?
How to find unique records from a very big file in java using a scalable solution?
我有一个文件(为方便起见,假设为 csv 文件)可以包含多达数百万条记录。该文件可能包含多个重复项。可以说我想查找唯一记录但仅基于某些列(可以说它们是主要列)。假设我们有一个文件:
在此文件中,前 2 条记录并不完全相同。但是,如果我认为 column1 是主要的,那么前 2 条记录对我来说是重复的(因为它们在 column1 中具有相同的值)并且我只希望其中的 1 条出现在我的最终结果中。
在我目前的方法中,我使用的是 Map,其中键值是我的主列数据,对应的映射值是整个记录。
通过这种方式,我遍历了所有记录,并且对于每条记录,我分别将其主列数据作为键值并将整个记录作为映射值。这样,每当在迭代过程中遇到重复的主列时,它只是用相同的主键数据替换存在的记录(因为 Map 不允许重复)。
虽然此方法工作正常,但我无法将其扩展到更大的文件,因为它可能 运行 超出堆 space。时间复杂度也不好。谁能推荐更好的方法?
你需要的是堆外数据结构。试试 Hazelcast 或 Redis。否则,如果您不能使用其他任何东西,您可以大大减少内存需求,如果您只存储唯一记录的行号,然后再写输出。您还可以增加堆大小,甚至超过您的物理内存,但交换会降低性能。如果这还不够,您需要编写自己的堆外代码。您可以使用 ByteBuffer.allocateDirect() 分配内存并将数据写入其中,并使用映射存储数据的偏移量。
我有一个文件(为方便起见,假设为 csv 文件)可以包含多达数百万条记录。该文件可能包含多个重复项。可以说我想查找唯一记录但仅基于某些列(可以说它们是主要列)。假设我们有一个文件:
在我目前的方法中,我使用的是 Map,其中键值是我的主列数据,对应的映射值是整个记录。 通过这种方式,我遍历了所有记录,并且对于每条记录,我分别将其主列数据作为键值并将整个记录作为映射值。这样,每当在迭代过程中遇到重复的主列时,它只是用相同的主键数据替换存在的记录(因为 Map 不允许重复)。
虽然此方法工作正常,但我无法将其扩展到更大的文件,因为它可能 运行 超出堆 space。时间复杂度也不好。谁能推荐更好的方法?
你需要的是堆外数据结构。试试 Hazelcast 或 Redis。否则,如果您不能使用其他任何东西,您可以大大减少内存需求,如果您只存储唯一记录的行号,然后再写输出。您还可以增加堆大小,甚至超过您的物理内存,但交换会降低性能。如果这还不够,您需要编写自己的堆外代码。您可以使用 ByteBuffer.allocateDirect() 分配内存并将数据写入其中,并使用映射存储数据的偏移量。