# curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.disk.watermark.low" : "85%", "cluster.routing.allocation.disk.watermark.high" : "10gb", "cluster.info.update.interval" : "1m" } }'
# curl -s -XPUT http://127.0.0.1:9200/logstash-2015.05.08/_settings -d '{ "index": { "routing.allocation.total_shards_per_node" : "5" } }'
注意,这里配置的是 5 而不是 4。由于咱们须要预防有机器故障,分片发生迁移的状况。若是写的是 4,那么分片迁移会失败。
此外,另外一种方式则更加玄妙,Elasticsearch 中有一系列参数,相互影响,最终联合决定分片分配:
cluster.routing.allocation.balance.shard 节点上分配分片的权重,默认为 0.45。数值越大越倾向于在节点层面均衡分片。
cluster.routing.allocation.balance.index 每一个索引往单个节点上分配分片的权重,默认为 0.55。数值越大越倾向于在索引层面均衡分片。
cluster.routing.allocation.balance.threshold 大于阈值则触发均衡操做。默认为1。html
# curl -XPOST 127.0.0.1:9200/_cluster/reroute -d '{ "commands" : [ { "allocate_stale_primary" : { "index" : "logstash-2015.05.27", "shard" : 61, "node" : "10.19.0.77", "accept_data_loss" : true } } ] }'
curl -XPOST 127.0.0.1:9200/_cluster/reroute -d '{ "commands" : [ { "move" : { "index" : "logstash-2015.05.22", "shard" : 0, "from_node" : "10.19.0.81", "to_node" : "10.19.0.104" } } ] }'
curl -XPUT 127.0.0.1:9200/_cluster/settings -d '{ "transient" :{ "cluster.routing.allocation.exclude._ip" : "10.0.0.1" } }'
Elasticsearch 集群就会自动把这个 IP 上的全部分片,都自动转移到其余节点上。等到转移完成,这个空节点就能够毫无影响的下线了。和 _ip 相似的参数还有 _host, _name 等。此外,这类参数不单是 cluster 级别,也能够是 index 级别。下一小节就是 index 级别的用例。node
Elasticsearch 集群一个比较突出的问题是: 用户作一次大的查询的时候, 很是大量的读 IO 以及聚合计算致使机器 Load 升高, CPU 使用率上升, 会影响阻塞到新数据的写入, 这个过程甚至会持续几分钟。因此,可能须要仿照 MySQL 集群同样,作读写分离。1算法
实施方案apache
N 台机器作热数据的存储, 上面只放当天的数据。这 N 台热数据节点上面的 elasticsearc.yml 中配置 node.tag: hot
以前的数据放在另外的 M 台机器上。这 M 台冷数据节点中配置 node.tag: stale
模板中控制对新建索引添加 hot 标签:
{
“order” : 0,
“template” : “*”,
“settings” : {
“index.routing.allocation.require.tag” : “hot”
}
}
天天计划任务更新索引的配置, 将 tag 更改成 stale, 索引会自动迁移到 M 台冷数据节点编程
# curl -XPUT http://127.0.0.1:9200/indexname/_settings -d' { "index": { "routing": { "allocation": { "require": { "tag": "stale" } } } } }'
GC
[垃圾回收]
等缘由会偶尔没及时响应 ping ,通常建议稍加大 Fault Detection 的超时时间。discovery.zen.ping.unicast.hosts: ["es0","es1", "es2","es3","es4"] # 集群自动发现 discovery.zen.fd.ping_timeout: 120s # 超时时间(根据实际状况调整) discovery.zen.fd.ping_retries: 6 # 重试次数,防止GC[Garbage collection]节点不响应被剔除 discovery.zen.fd.ping_interval: 30s # 运行间隔
# curl -XPOST http://127.0.0.1:9200/logstash-2015.06.21/testlog -d '{ "date" : "1434966686000", "user" : "chenlin7", "mesg" : "first message into Elasticsearch" }'
命令返回响应结果为:api
{"_index":"logstash-2015.06.21","_type":"testlog","_id":"AU4ew3h2nBE6n0qcyVJK","_version":1,"created":true}
# curl -XGET http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK # curl -XGET http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK/_source GET apache-2016.12.30/testlog/AVlPEWLkYdfL4HTWelef/_source GET apache-2016.12.30/testlog/AVlPEWLkYdfL4HTWelef?fields=user # 指定字段
# curl -XDELETE http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK 删除不单针对单条数据,还能够删除整个整个索引。甚至能够用通配符。 # curl -XDELETE http://127.0.0.1:9200/logstash-2015.06.0* 在 Elasticsearch 2.x 以前,能够经过查询语句删除,也能够删除某个 _type 内的数据。如今都已经再也不内置支持,改成 Delete by Query 插件。由于这种方式自己对性能影响较大!
已经写过的数据,一样仍是能够修改的。有两种办法,一种是全量提交,即指明 _id 再发送一次写入请求。
# curl -XPOST http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK -d '{ "date" : "1434966686000", "user" : "chenlin7", "mesg" " "first message into Elasticsearch but version 2" }' 另外一种是局部更新,使用 /_update 接口: # curl -XPOST 'http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK/_update' -d '{ "doc" : { "user" : "someone" } }' 或者 # curl -XPOST 'http://127.0.0.1:9200/logstash-2015.06.21/testlog/AU4ew3h2nBE6n0qcyVJK/_update' -d '{ "script" : "ctx._source.user = \"someone\"" }'
PUT /_cluster/settings{
"transient": { "cluster.routing.allocation.disk.watermark.low": "80%", "cluster.routing.allocation.disk.watermark.high": "5gb", "cluster.info.update.interval": "1m" } }
全文搜索
# curl -XGET http://127.0.0.1:9200/logstash-2015.06.21/testlog/_search?q=first # curl -XGET http://127.0.0.1:9200/logstash-2015.06.21/testlog/_search?q=user:"chenlin7" { "took": 2, Elasticsearch 执行这个搜索的耗时,以毫秒为单位 "timed_out": false, 搜索是否超时 "_shards": { 指出多少个分片被搜索了,同时也指出了成功/失败的被搜索的shards 的数量 "total": 5, "successful": 5, "failed": 0 }, "hits" : { 搜索结果 "total" : 579, 匹配查询条件的文档的总数目 "max_score" : 0.12633952, "hits" : [ 真正的搜索结果数组(默认是前10个文档) { "_index" : "logstash-2015.06.21", "_type" : "logs", "_id" : "AVmvfgGaSF0Iy2LFN0EH", "_score" : 0.12633952, "_source" : { "user" : "chenlin7" } } ......
term query 的写法数组
# curl -XGET http://127.0.0.1:9200/_search -d ' { "query": { "term": { "user": "chenlin7" } } }'
$ curl -XGET 127.0.0.1:9200/_cluster/health?pretty安全
主分片缺失
。这部分数据彻底不可用。而考虑到 ES 在写入端是简单的取余算法,轮到这个分片上的数据也会持续写入报错。接口请求的时候,能够附加一个 level 参数,指定输出信息以 indices 仍是 shards 级别显示。固然,通常来讲,indices 级别就够了。bash
对不了解 JVM 的 GC 的读者,这里先介绍一下 GC(垃圾收集)以及 GC 对 Elasticsearch 的影响。
Java is a garbage-collected language, which means that the programmer does not manually manage memory allocation and deallocation. The programmer simply writes code, and the Java Virtual Machine (JVM) manages the process of allocating memory as needed, and then later cleaning up that memory when no longer needed. Java 是一个自动垃圾收集的编程语言,启动 JVM 虚拟机的时候,会分配到固定大小的内存块,这个块叫作 heap(堆)。JVM 会把 heap 分红两个组:
Young 新实例化的对象所分配的空间。这个空间通常来讲只有 100MB 到 500MB 大小。Young 空间又分为两个 survivor(幸存)空间。当 Young 空间满,就会发生一次 young gc,还存活的对象,就被移入幸存空间里,已失效的对象则被移除。
Old 老对象存储的空间。这些对象应该是长期存活并且在较长一段时间内不会变化的内容。这个空间会大不少,在 ES 来讲,一节点上可能就有 30GB 内存是这个空间。前面提到的 young gc 中,若是某个对象连续屡次幸存下来,就会被移进 Old 空间内。而等到 Old 空间满,就会发生一次 old gc,把失效对象移除。
听起来很美好的样子,可是这些都是有代价的!在 GC 发生的时候,JVM 须要暂停程序运行,以便本身追踪对象图收集所有失效对象。在这期间,其余一切都不会继续运行。请求没有响应,ping 没有应答,分片不会分配……
固然,young gc 通常来讲执行极快,没太大影响。可是 old 空间那么大,稍慢一点的 gc 就意味着程序几秒乃至十几秒的不可用,这太危险了。
JVM 自己对 gc 算法一直在努力优化,Elasticsearch 也尽可能复用内部对象,复用网络缓冲,而后还提供像 Doc Values 这样的特性。但无论怎么说,gc 性能老是咱们须要密切关注的数据,由于它是集群稳定性最大的影响因子。
若是你的 ES 集群监控里发现常常有很耗时的 GC,说明集群负载很重,内存不足。严重状况下,这些 GC 致使节点没法正确响应集群之间的 ping ,可能就直接从集群里退出了。而后数据分片也随之在集群中从新迁移,引起更大的网络和磁盘 IO,正常的写入和搜索也会受到影响。服务器
1. 关闭分片自动均衡 PUT /_cluster/settings { "transient" : { "cluster.routing.allocation.enable" : "none" } } 2). 升级重启该节点,并确认该节点从新加入到了集群中 3). 其余节点重复第2步,升级重启。 4. 最后全部节点配置更新完成后,重启集群的shard均衡 curl -XPUT http://192.168.1.2/_cluster/settings -d' { "transient" : { "cluster.routing.allocation.enable" : "all" } }'