【问题标题】:C# Serializing large datasetsC# 序列化大型数据集
【发布时间】:2014-09-17 11:17:13
【问题描述】:

我正在尝试将数据从 Microsoft SQL 数据库移动到 Elasticsearch。我正在使用 EF 6 生成模型(来自数据库的代码优先)和 NEST 将对象序列化到 Elasticsearch 中。

如果我使用延迟加载,它可以正常工作,但速度慢得令人难以置信(慢到无法使用)。如果我通过添加此行切换到 Eager 加载:

public MyContext() : base("name=MyContext")
{
    this.Configuration.LazyLoadingEnabled = false;
}

并像这样进行序列化:

ElasticClient client = new ElasticClient(settings);

var allObjects = context.objects
    .Include("item1")
    .Include("item2")
    .Include("item2.item1")
    .Include("item2.item1.item");

client.IndexMany(allObjects);

我最终得到一个 System.OutOfMemoryException,在序列化发生之前(所以只是通过加载数据)。我有大约 2.5 GB 的可用内存,我们正在谈论数据库中的 110.000 个项目。

我曾尝试对数据进行排序,然后使用 Skip 和 Take 一次只序列化一定数量的对象,但是在内存不足之前我只设法将 60.000 个对象插入 Elasticsearch。垃圾收集器似乎没有释放足够的内存,即使我在将一定数量的对象插入 Elasticsearch 后明确调用了它。

有没有办法急切加载特定数量的对象?还是序列化大型数据集的另一种方法?

【问题讨论】:

  • 查看GC.AddMemoryPressure()
  • 感谢您的提示。不幸的是,它似乎不会影响我的应用程序中的内存使用。

标签: c# entity-framework serialization elasticsearch nest


【解决方案1】:

事后看来,这是一个愚蠢的错误。通过这样做,我成功地实现了我的目标:

int numberOfObjects;

using (var context = new myContext())
{
    numberOfObjects = context.objects.Count();
}

for (int i = 0; i < numberOfObjects; i += 10000)
{
    using (var context = new myContext())
    {
        var allObjekts = context.objects.OrderBy(s => s.ID)
            .Skip(i)
            .Take(10000)
            .Include("item1")
            .Include("item2")
            .Include("item2.item1")
            .Include("item2.item1.item");

            client.IndexMany(allObjekts);
    }
}

这允许 Gargage 收集器完成它的工作,因为上下文被包装在 for 循环中。我不知道是否有更快的方法,我可以在大约 400 秒内在 Elasticsearch 中插入大约 100.000 个对象。

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 2018-08-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多