【问题标题】:Taking too long to insert records in Elasticsearch in c#在 C# 中的 Elasticsearch 中插入记录花费的时间太长
【发布时间】:2015-07-10 17:13:52
【问题描述】:

以下代码从两个表 table1 和 table2 中提取数据,在字段 3 上对它们执行 JOIN 并将其索引到 Elasticsearch。需要索引的总数或行数约为 5 亿。该代码在一小时内插入了 500 万条记录,因此这样需要 100 小时才能完成。有什么方法可以让它更快吗?

        public static void selection()
        {
            Uri node = new Uri("http://localhost:9200");
            ConnectionSettings settings = new ConnectionSettings(node);
            ElasticClient client = new ElasticClient(settings);

            int batchsize = 100;
            string query = "select table1.field1, table2.field2 from table1 JOIN table2 ON table1.field3=table2.field3";

            try
            {
                OracleCommand command = new OracleCommand(query, con);
                OracleDataReader reader = command.ExecuteReader();

                List<Record> l = new List<Record>(batchsize);
                string[] str = new string[2];
                int currentRow = 0;

                while (reader.Read())
                {
                    for (int i = 0; i < 2; i++)
                        str[i] = reader[i].ToString();
                    l.Add(new Record(str[0], str[1]));

                    if (++currentRow == batchsize)
                    {
                        Commit(l, client);
                        l.Clear();
                        currentRow = 0;
                    }
                }
                Commit(l, client);
            }
            catch(Exception er)
            {
                Console.WriteLine(er.Message);
            }

        }

        public static void Commit(List<Record> l, ElasticClient client)
        {
            BulkDescriptor a = new BulkDescriptor();
            foreach (var x in l)
                a.Index<Record>(op => op.Object(x).Index("index").Type("type"));
            var res = client.Bulk(d => a);
            Console.WriteLine("100 records more inserted.");
        }

感谢任何帮助! :)

【问题讨论】:

标签: c# oracle elasticsearch nest


【解决方案1】:

您可以尝试使用较低级别的客户端,即 ElasticSearchClient 吗?

这里是示例 -

//Fill data in ElasticDataRows

StringBuilder ElasticDataRows = new StringBuilder()
ElasticDataRows.AppendLine("{ \"index\":  { \"_index\": \"testindex\", \"_type\": \"Accounts\" }}");
ElasticDataRows.AppendLine(JsonConvert.SerializeXmlNode(objXML, Newtonsoft.Json.Formatting.None, true));

var node = new Uri(objExtSetting.SelectSingleNode("settings/ElasticSearchURL").InnerText);
var config = new ConnectionConfiguration(node);
ElasticsearchClient objElasticClient = new ElasticsearchClient(config);

//Insert data to ElasticSearch
var response = ExtractionContext.objElasticClient.Bulk(Message.ElasticDataRows.ToString());

ElasticSearchClient 不像 NEST 那样是强类型的。因此,您可以使用 NewtonSoft.JSON 将您的 Class 对象数据转换为 JSON。

根据我的测试,这比 NEST API 更快。

谢谢, 萨米尔

【讨论】:

    【解决方案2】:

    我们每个月都会重新索引大约 40-50 个数据库。每个数据库有 1 到 8 百万行。不同之处在于我从 MongoDB 获取数据。为了让它更快,我正在做的是使用 Parallel.Foreach 运行 32 个线程并插入到弹性中。我只插入一条记录,因为我需要为它们中的每一个计算东西,但你只需从数据库中取出它们并插入它们有弹性,所以散装插件看起来更好。您可以尝试使用 3-4 个线程和批量插入。 因此,将您的表分成 4 个,然后启动将批量插入弹性的不同线程。从我所看到的情况来看,我很确定您从 DB 中读取的部分占用了大部分时间。另外我认为您应该尝试使用 > 100 的批次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      相关资源
      最近更新 更多