在c#中插入Elasticsearch中的记录花费的时间太长

时间:2015-06-26 09:13:05

标签: c# oracle elasticsearch nest

以下代码从两个表table1和table2中提取数据,对它们执行JOIN,在字段3上并将其编入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.");
        }

任何帮助表示赞赏! :)

2 个答案:

答案 0 :(得分:0)

您可以尝试使用较低级别的客户端,即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更快。

谢谢, 萨米尔

答案 1 :(得分:0)

我们有40-50个数据库,我们每月重新索引。每个DB具有1到8密耳的行。不同之处在于我从MongoDB获取数据。我正在做的更快的是使用Parallel.Foreach运行32个线程并插入弹性。我只需要插入一条记录,因为我需要为每个记录计算东西,但是你只需要从DB中取出它们并插入它们在弹性,所以批量插入似乎更好。您可以尝试使用3-4个线程和批量插入。 所以将你的桌子分成4个然后开始不同的线程,批量插入弹性。从我所看到的,我非常确定你从DB读取的部分占用了大部分时间。另外我认为你应该尝试使用批量&gt; 100。