【发布时间】:2019-06-17 04:50:40
【问题描述】:
我有一个大约 10 GB 的文本文件,包含 5000 万行。对于文件中的每一行,如果记录尚不存在,我将插入该记录,否则将与现有记录的 ID 和当前行 ID 进行比较,如果当前 ID 小于记录 ID,则更新.
目前,插入/比较记录大约需要 8 小时
文本文件中的示例数据:
Md5,Id
d41d8cd98f00b204e9800998ecf8427e,1000
e358efa489f58062f10dd7316b65649e,1001
626726e60bd1215f36719a308a25b798,1002
d41d8cd98f00b204e9800998ecf8427e,5002
d41d8cd98f00b204e9800998ecf8427e,0953
626726e60bd1215f36719a308a25b798,0152
我已经尝试实现生产者/消费者模式,但是生产者会太快并且消耗大量内存,从而导致 OutOfMemory 异常。
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
int lineCount = 0;
foreach(var f in File.ReadLines(@"big_text_file.txt").Skip(1))
{
lineCount++;
string[] lines = null;
lines = f.Split(",")
if (!db.KeyExists(lines[2]))
{
db.StringSet(lines[2], lines[0]);
}else //contains key
{
var keypair = db.StringGet(lines[2]);
if(Convert.ToInt32(lines[0]) < Convert.ToInt32(keypair))
{
db.StringSet(lines[2], lines[0]);
}
}
【问题讨论】:
-
您能否将密钥保存在内存中,而不是检查数据库中的每条记录?你能做检查并插入两个单独的线程吗?
-
如果我只使用 Hashset 将密钥存储在内存中,我最终会得到内存不足的错误。
-
嗯,50M 乘以一个 MD5 哈希加上一点额外的大约是 2GB。这不应该是敌人。我相信有序列表更适合存储密钥。也许您必须实现自己的二进制搜索。