【问题标题】:Insert into RavenDB; Fastest way插入 RavenDB;最快的方式
【发布时间】:2012-06-25 15:40:35
【问题描述】:

我想将文本文件中的 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;
    }
}

谢谢

【问题讨论】:

  • 如果你不等待完成,它当然看起来很快。因为处理还没有完成。这不是一个有效的基准。
  • 文档数据库与“记录”无关。您可能希望了解如何对这些数据进行建模以适合文档数据库。有关类似场景的示例,请参阅 ayende.com/blog/154401/…ayende.com/blog/156386/…
  • @synhershko 我知道 - 在某种程度上 - 这是关于文件的,我在这里使用了“记录”这个词,因为当时我没有更好的词; “进入”也许? “目的”? “信息”?我不知道...谢谢!
  • 我的观点 - 你可能需要做的插入比你想象的要少得多。最快的方法是使用一个简单的控制台应用程序批量执行此操作 - 如果您对每一组调用 SaveChanges,会话 API 将为您执行此操作。大多数情况下,您会发现从您的来源读取数据将花费大部分时间。
  • @usr 处理已完成,RavenDB 为 ACID。索引可能没有赶上,但所有信息都已经可用。

标签: c# asynchronous insert nosql ravendb


【解决方案1】:

卡维,

这里有很多问题。

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

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

3) 使用标准会话,使用 1,024 - 2,048 的批量大小。让它运行。 RavenDB 在优化方面非常出色,我希望您可以轻松地看到每秒数千次插入。

但是,再一次,您可能是在建模错误。

【讨论】:

    猜你喜欢
    • 2018-06-29
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多