在Elasticsearch中将读取优先于写入

时间:2014-02-19 20:46:37

标签: search locking elasticsearch

我有一台运行Elasticsearch 0.9的EC2服务器,带有一个用于读/写访问的nginx服务器。我的索引有大约750k的中小型文档。我对内容有一个非常连续的最小写入(主要是更新)流。我通过搜索获得的速度/一致性对我来说很好,但是multi-get (/_mget)我有一些零星的超时问题。

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

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

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

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

我确定其他人之前遇到过此问题,通常的解决方案是确保用户始终可以优先于写入从索引中读取数据。如果需要,我会考虑增加服务器功率。目前我们有2个m2x大的EC2实例。一个是主要副本和副本,每个都有4个分片。

来自失败请求的cURL信息的示例转储(错误为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":""
}

1 个答案:

答案 0 :(得分:2)

在使用Paramedic插件进行更多监控之后,我注意到当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。