Elasticsearch and .NET

6
我们正在考虑从Solr/Solr.net转换到Elasticsearch。我们开始使用NEST。我们在搜索索引中只有4个文档。
private static void Main(string[] args)
{
    var node = new Uri("http://localhost:9200");
    var settings = new ConnectionSettings(
        node, "my-application");

    var client = new ElasticClient(settings);

    var stopwatch = Stopwatch.StartNew();
    var sr = client.Get<Movie>(1);

    Console.WriteLine(stopwatch.ElapsedMilliseconds);
}

上面的代码需要大约250毫秒,而使用HttpClientJsonSerializer的相同代码需要30-45毫秒。仅为4个文档花费250毫秒的时间太长了。
NEST能否用于高流量新闻网站,还是您建议使用HttpClient+JsonSerializer组合?搜索页面是我们网站2013年最受欢迎的页面。
提前致谢。

4
尝试发送多个请求,我猜想 NEST 在第一次请求后会进行某种缓存以极大地提高性能,否则没有人会使用它。 - ryudice
你是对的。第一次 client.Getclient.Search 请求很慢,但随后的请求会快得多。 - šljaker
这是真的,NEST只需要缓存强类型属性访问,即p=>p.Name和类型/索引推断。最大的延迟因素是需要预热的JSON.NET序列化缓存。 - Martijn Laarman
2个回答

4
有两个条件必须满足,NEST才能发出第一次请求。
  1. 在这种情况下,Json序列化程序(Json.net)必须缓存类型,以便知道如何序列化和反序列化你发送和接收的对象。

  2. Nest具有自己的流畅语言来查询,必须将其从表示流畅查询语言的初始类型翻译成JSON格式,然后传递给Elasticsearch。这些文档类型也必须被Json序列化程序学习。

  3. 必须启动HTTP客户端以进行请求。

我目前在单个索引中拥有超过4M个文档,并使用NEST,在服务器到客户端的互联网查询中,使用NEST的搜索时间为50-70毫秒。 但是像您一样,冷启动后第一次请求很慢。

1
只是为了添加一个数据点,我有超过1亿个单一分片跨多个服务器,并且NEST对原始弹性响应时间的开销很小。 - Basic

2

我建议你使用https://github.com/ServiceStack/ServiceStack.Text,这是C#最快的JSON序列化程序。

对于驱动程序,请使用底层的http://nest.azurewebsites.net/elasticsearch-net/quick-start.html

以下是我开始编写详细记录和分析应用程序的代码。虽然还有待完善,但可以作为一个良好的开端。

using System;
using System.Configuration;
using Elasticsearch.Net;
using Elasticsearch;
using Elasticsearch.Net.Connection;
using Elasticsearch.Net.ConnectionPool;

namespace Common {

    /// <summary>
    /// Elastic search. Singletone, open connection and thread safe to be open for all the time
    /// the app is running, so we send ours logs to ealsticsearch to be analyzed, assychronly
    /// See the fourth version;
    /// http://csharpindepth.com/articles/general/singleton.aspx
    /// </summary>
    public sealed class ElasticSearch {
        // our instance of ourself as a singleton
        private static readonly ElasticSearch instance = new ElasticSearch();

        ElasticsearchClient client;
        string connectionString = ConfigurationManager.ConnectionStrings["Elasticsearch"].ConnectionString;

        /// <summary>
        /// Initializes a new instance of the <see cref="Common.ElasticSearch"/> class.
        /// Follow this: http://nest.azurewebsites.net/elasticsearch-net/connecting.html
        /// We use a ConnectionPool to make the connection fail-over, that means, if the 
        /// connection breaks, it reconnects automatically
        /// </summary>
        private ElasticSearch() {
            var node = new Uri(connectionString);
            var connectionPool = new SniffingConnectionPool(new[] { node });
            var config = new ConnectionConfiguration(connectionPool);
            client = new ElasticsearchClient(config);   // exposed in this class
        }

        static ElasticSearch() {
        }

        /// <summary>
        /// Gets the instance of our singleton class
        /// </summary>
        /// <value>The instance.</value>
        public static ElasticSearch Instance {
            get {
                return instance;
            }
        }

        /// <summary>
        /// Log the specified module, id and json.
        /// </summary>
        /// <param name="type">Here the entity you want to save your log,
        /// let's use it based on classes and StateMachines</param>
        /// <param name="id">Identifier. alwayes the next</param>
        /// <param name="json">Json.</param>
        public void Log(string type, string id, string json) {
            client.Index("mta_log", type, id, json);
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接