2014-02-19 38 views
2

我有一台运行Elasticsearch 0.9的EC2服务器,并带有一个nginx服务器用于读/写访问。我的索引大约有750,000个中小型文档。我有一个非常连续的小写(主要是更新)的内容。我用搜索收到的速度/一致性很好,但我有一些零星的超时问题multi-get (/_mget)Elasticsearch提供读取优先级写入

在我的应用程序的某些页面上,我们的服务器将请求一打打到几千个文档(通常需要不到1-2秒)。失败的请求失败,并且nginx服务器的超时时间为30,000毫秒。我假设发生这种情况是因为索引因写入/优化目的而被暂时锁定。有没有人对我在这里可以做什么有任何想法?

临时解决方案是降低超时时间并返回一个用户友好的消息,说明无法检索文档(但是他们仍然需要等待大约10秒才能看到错误消息)。

我的一些其他想法是让阅读优先于写入。任何时候有人试图读取索引的一部分,不要允许对该部分进行任何写入/锁定。我不认为这可能是可扩展的,甚至可能不可能?

最后,我想我可以有一个只读的别名和一个只写的别名。我可以弄清楚如何通过文档设置它,但我不确定它是否会像我期望的那样工作(并且我不确定如何在本地环境中可靠地测试它)。如果我设置这样的别名,只读别名是否仍然存在索引被锁定的时刻,因为信息是通过只写别名写入的?

我确定别人之前遇到过这种情况,确保用户始终可以从索引中读取数据的优先级高于写入的典型解决方案。如果需要,我会考虑增加我们的服务器功率。目前我们有2个m2x的大型EC2实例。一个是主要和副本,每个有4个碎片。

从失败的请求卷曲信息的例子转储(与Operation timed out after 30000 milliseconds with 0 bytes received错误):

{ 
    "url":"127.0.0.1:9200\/_mget", 
    "content_type":null, 
    "http_code":100, 
    "header_size":25, 
    "request_size":221, 
    "filetime":-1, 
    "ssl_verify_result":0, 
    "redirect_count":0, 
    "total_time":30.391506, 
    "namelookup_time":7.5e-5, 
    "connect_time":0.0593, 
    "pretransfer_time":0.059303, 
    "size_upload":167002, 
    "size_download":0, 
    "speed_download":0, 
    "speed_upload":5495, 
    "download_content_length":-1, 
    "upload_content_length":167002, 
    "starttransfer_time":0.119166, 
    "redirect_time":0, 
    "certinfo":[ 

    ], 
    "primary_ip":"127.0.0.1", 
    "redirect_url":"" 
} 

回答

2

使用护理人员插件的详细监测后,我注意到,我会得到超时当我的CPU会打〜 80-98%(索引/搜索流量没有明显的峰值)。我终于在Elasticsearch论坛上偶然发现了一个helpful thread。看起来这是在索引进行刷新并发生大量合并时发生的。

Merges can be throttled在群集或索引级别,我已将它们从indicies.store.throttle.max_bytes_per_sec从默认的20mb更新为5mb。这可以在运行期间使用cluster update settings API完成。

PUT /_cluster/settings HTTP/1.1 
Host: 127.0.0.1:9200 

{ 
    "persistent" : { 
     "indices.store.throttle.max_bytes_per_sec" : "5mb" 
    } 
} 

到目前为止,Parmedic正在显示CPU使用率下降。从平均约5-25%下降到平均约1-5%。希望这可以帮助我避免之前锁定查询的90%+峰值,如果我没有任何问题,我会通过选择此答案来报告。

作为一个方面说明,我想我可以选择更平衡的EC2实例(而不是内存优化)。我认为我对目前的选择感到满意,但我的下一次购买也将考虑更多的CPU。