2

我正在使用Elasticsearch - 盆景在我的其中一个Ruby on Rails项目。所以,事情进展得很顺利。但是,当我们向最终用户和人们开始使用该应用程序的那一刻,我们注意到一个弹性搜索查询需要5-7秒的时间才能做出响应(对我们来说真的是糟糕的体验) - 虽然,我们有8-2x Web Dynos到位。Rails - Elasticsearch(盆景)和Heroku - 性能问题

所以,我们决定升级盆景附加到盆景10也加入NewRelic的附加(留意在一个查询需要多少时间作出回应)

下面是我们的环境设置:

Ruby: 2.2.4 
Rails: 4.2.0 
elasticsearch: 1.0.15 
elasticsearch-model: 0.1.8 

所以,我们再次导入数据到Elasticsearch,这里是我们的ElasticSearch集群健康:

pry(main)> Article.__elasticsearch__.client.cluster.health 
=> {"cluster_name"=>"elasticsearch", 
    "status"=>"green", 
    "timed_out"=>false, 
    "number_of_nodes"=>3, 
    "number_of_data_nodes"=>3, 
    "active_primary_shards"=>1, 
    "active_shards"=>2, 
    "relocating_shards"=>0, 
    "initializing_shards"=>0, 
    "unassigned_shards"=>0, 
    "delayed_unassigned_shards"=>0, 
    "number_of_pending_tasks"=>0, 
    "number_of_in_flight_fetch"=>0} 

及以下的ES调用 ES calls data in NewRelic

这表明一个很大的理由担心NewRelic的数据。

我的模型下面article.rb

class Article < ActiveRecord::Base 
    include Elasticsearch::Model 

    after_commit on: [:create] do 
    begin 
     __elasticsearch__.index_document 
    rescue Exception => ex 
     logger.error "ElasticSearch after_commit error on create: #{ex.message}" 
    end 
    end 

    after_commit on: [:update] do 
    begin 
     Elasticsearch::Model.client.exists?(index: 'articles', type: 'article', id: self.id) ? __elasticsearch__.update_document :  __elasticsearch__.index_document 
    rescue Exception => ex 
     logger.error "ElasticSearch after_commit error on update: #{ex.message}" 
    end 
    end 

    after_commit on: [:destroy] do 
    begin 
     __elasticsearch__.delete_document 
    rescue Exception => ex 
     logger.error "ElasticSearch after_commit error on delete: #{ex.message}" 
    end 
    end 

    def as_indexed_json(options={}) 
    as_json({ 
     only: [ :id, :article_number, :user_id, :article_type, :comments, :posts, :replies, :status, :fb_share, :google_share, :author, :contributor_id, :created_at, :updated_at ], 
     include: { 
     posts: { only: [ :id, :article_id, :post ] }, 
     } 
    }) 
    end 
end 

现在,如果我看的盆景10计划的Heroku,它给了我20碎片但随着集群的当前状态,它仅使用1个活动主碎片和2个活动碎片。我的脑海中突然出现了一些问题:

  1. 增加碎片数量到20会有帮助吗?
  2. 它可以缓存ES查询 - 你也建议一样吗? - 它有没有什么优点和缺点?

请帮我找到减少时间和提高ES工作效率的方法。

UPDATE

这里的一小段代码https://jsfiddle.net/puneetpandey/wpbohqrh/2/,我创造了(作为参考),以显示究竟为什么我需要这么多的呼叫ElasticSearch

在上面的例子中,我显示几个计数(在每个复选框元素的前面)。为了显示这些罪名,我需要通过敲击ES

好了,看完意见后取的我得到的数字,在这里找到了一个很好的文章:How to config elasticsearch cluster on one server to get the best performace on search我想我已经在

有足够的重新构造

最佳,

普尼特

回答

0

你有3个ES节点,最佳性能要求每个节点的至少一个碎片。 Heroku可能会报告其他内容。碎片是ES内部某个索引的属性,而不是ES集群本身,因此检查索引有多少碎片。但即使只有一个分支,你的查询也不会太慢,可能文档索引是错误的。您提供了关于您的索引,查询和负载的信息太少。

缓存可能对任何存储系统都有帮助,缺点和专业人员总是一样的。

1

尼克与盆景在这里。如果您通过[email protected]联系我们的支持团队,我们总是乐于帮助解决性能问题,并且可以访问更多更详细的日志以帮助解决这些问题。与此同时,我想我可以在这里分享一些足够一般的建议...

在这种情况下,您的New Relic报告中有趣的统计数字是“Average calls(per txn):109。”如果我正确地理解了这一点,它看起来应用程序平均每个Web请求对Elasticsearch的调用次数超过100次。这似乎非常高。

如果所有100个以上的请求的平均值为3,000ms,那么对Elasticsearch的请求大约需要30毫秒。这也比我们平时的平均速度慢一点,但对于单个请求来说,要比3,000ms更合理。 (我们可以通过更多的私人支持通信与您分享更具体的数字。)

您可能想要关注减少Elasticsearch请求的数量。如果无法减少总请求数量,则可以考虑将它们组合起来以节省每个请求和每个连接的开销。盆景还支持HTTP保持活动状态,因此您可以重复使用请求之间的连接,有助于减少初始TLS握手的开销。

为了整合更新,您可以使用Bulk API。还有Multi Search API用于搜索,Multi Get API用于单文档获取请求。

如果减少和整合都不可能,那么您可能有其他一些用例,这对于单独进行所有这些搜索很重要。如果是这样的话,我会建议在UI中使用Ajax来后期加载这些搜索。这样,您的应用就可以提供快速的初始响应,并向用户展示一些进展,同时逐渐填充其余部分。

+0

感谢您的快速回复@尼克..我完全同意你,每个Web请求,我打ES超过100次以获取页面中每个属性的记录。减少通话总数当然有帮助,我也在考虑你的第三种选择,其中我可以使用/调用AJAX请求 –

+0

如果你曾经在数据库调用中处理过“N + 1查询”问题,这听起来像你在Elasticsearch中为自己创建了一个类似的情况:-) –

+0

不幸的是@ nick-zadrozny,我没有看到任何减少ES调用的选项。这是一小段代码片段(https://jsfiddle.net/puneetpandey/wpbohqrh/2/)。因为您会看到在高级搜索中显示每个属性的计数,所以我必须查询ElasticSearch。让我知道,如果解释! –