插入RavenDB;最快的方式

时间:2012-06-24 11:01:06

标签: c# asynchronous insert nosql ravendb

我想从文本文件中导入1亿个条目(每行是一个类似csv的条目)到RavenDB数据库中。最快的方法是什么?

附加说明:

我还没有任何索引(我会在插入数据后创建它们)。 RavenDB在本地计算机上以服务模式运行,没有任何安全性增强(但是因为我还在测试RavenDB)。该测试将在2台不同的机器上运行,1)2芯4GB内存2)8芯12 GB内存。

我已经将这部分数据(200万个条目)插入到RavenDB中,但它没有我想要的那么快。通过使用OpenAsyncSession并为每1024条记录调用SaveChangesAsync并再次通过调用OpenAsyncSession创建一个新会话,而不是在500'000条目之后等待返回任务(由SaveChangesAsync返回),我得到一个“索引超出范围”异常我无法根除。但是,如果我等待任务结束(通过创建与核心数相同的任务),过程将会成功,但速度不够快。

此代码成功运行:

using (var reader = new StreamReader(@"D:\*\DATA.TXT", Encoding.UTF8))
{
    string line = null;
    IAsyncDocumentSession session = null;

    var tasks = new List<Task>();
    var locCount = 0;

    while ((line = reader.ReadLine()) != null)
    {
        if (string.IsNullOrWhiteSpace(line)) continue;

        var loc = Parse(line);

        if (session == null) session = documentStore.OpenAsyncSession();

        session.Store(loc);
        locCount++;

        if (locCount % 1024 == 0 && session != null)
        {
            try
            {
                var t = session.SaveChangesAsync();
                tasks.Add(t);
                session = null;
            }
            catch (Exception x)
            {
                // ... something ...
            }
        }

        if (tasks.Count >= NUMBER_OF_CORES)
        {
            Task.WaitAll(tasks.ToArray());
            tasks.Clear();
        }
    }

    if (session != null)
    {
        if (tasks.Count > 0)
        {
            Task.WaitAll(tasks.ToArray());
            tasks.Clear();
        }
        session.SaveChangesAsync().Wait();
        session = null;
    }
}

由于

1 个答案:

答案 0 :(得分:5)

卡韦赫,

这里有很多问题。

1)RavenDB模型很少映射到CSV文件。如果你有一个CSV文件,你通常有表格格式,这不是一个很好的格式来移植到RavenDB。通过获得好的模型,你可能会得到更好的结果。

2)您的代码在没有if (tasks.Count >= NUMBER_OF_CORES)的情况下,将生成尽可能多的任务(受限于从文件读取行的限制,真的快。 这将导致生成数千个并发任务,并且会使RavenDB可以一次插入的请求数量超载。

3)使用标准会话,批量大小为1,024 - 2,048。然后让它运行。 RavenDB在优化方面非常出色,我希望你能够轻松地每秒看到数千个插件。

但是,再次,你可能错误地设计了一些东西。