龙空技术网

Elasticsearch 实战案例(索引切分、模板、别名、数据迁移)

互联网技术栈 2660

前言:

现时看官们对“nginx子目录indexphp”大约比较关注,同学们都需要了解一些“nginx子目录indexphp”的相关资讯。那么小编同时在网摘上收集了一些对于“nginx子目录indexphp””的相关内容,希望同学们能喜欢,咱们快快来了解一下吧!

背景

基于ELK搭建的日志平台,前期匆忙建设过程中一些参数和设计未做过多的考虑,上线后就需要不断根据实际情况做调整,而一些调整限于ELK的一些特性,一旦操作不当就会出现丢数据、数据写入异常、数据查不到等情况。

因此如何在这种背景下,做到对使用方无感知的动态调整是我们所要实现的目标。本文更加注重实践而非深层次的理论讲解,有兴趣深入了解的可以自行研习。

总体架构

CASES

CASE1:按日/月生成索引

创建的nginx access_log索引,开始采集2周后,数据达到25G+(number_of_replicas=1,因此总体数据超过50G),如果不进行索引拆分,该索引将越来越大,最终会严重影响查询效率,并且一旦出现索引损坏造成的风险也更大。

通过配置logstash ouput 插件实现按照日期生成新索引:

output { elasticsearch { hosts => ["192.168.0.1:9200"] index => "php-nginx-log-%{+YYYY.MM.DD}" #按照天生成索引 }}

通过我们的配置,目前会存在2个index,分别为历史的php-nginx-log索引和以php-nginx-log.2019-01-15索引。

CASE2:Kibana查询所有数据

由于目前我们的索引不再是指定的具体索引,还是一类按照事先约定的命名格式索引集合,这时我们想要能够在Kibana查询数据时不受影响,能够正常查询到数据,此时主要有两种解决方式:

1、更改Kibana的Create index pattern,使用通配符关联出所有index

2、使用index aliases,详情:

Elasticsearch的别名,就类似数据库的视图,别名不仅仅可以关联一个索引,它能聚合多个索引,下文还会提到别名的更重要的特性。

通过别名的方式是更加建议的方式。

POST /_aliases{ "actions" : [ { "add" : { "index" : "new_index1", "alias" : "alias1" } } ]}

说明:这里使用Elasticsearch的REST API进行设置,具体详情参考官网: ,下文中的类似代码块都是此类调用。

CASE3:通过模板创建Index

创建index后,如果未指定具体mapping,则在插入具体doc数据时,会自动生成,具体数据字段的数据类型Elasticsearch会做一定的动态识别,但是大部分都将以string定义,这种情况下我们在使用数据时 ,就会出现一些不便,如 Kibana一些函数必须是整型类型、ip类型的字段才可以使用,另外全部默认为string类型会导致查询效率的低下和存储容量的浪费。

这时就需要我们去指定index的mapping,而很重要的一点:mapping中的filed一点指定后(无论是默认生成还是手动声明)就无法进行update filed操作,如果要修改通常只能进行create 新的index。因此我们往往会在index写入数据前就创建好index的mapping,如下:

PUT new_index1{ "settings" : { "number_of_shards" : 1 }, "mappings" : { "_doc" : { "properties" : { "field1" : { "type" : "text" } } } }}

而通过CASE1中,已经说明了我们的index都是由Logstash按照日期自动创建的,因此手动通过API的方式无法满足我们的需求,这时我们就需要使用Elasticsearch的template特性:

创建template:

PUT _template/template_nginx_log{ "index_patterns": ["php-nginx-log*"], "settings": { "number_of_shards": "5", "number_of_replicas": "1" }, "aliases": { "php-nginx-log": {} }, "mapping": { "doc": { "properties": { "@timestamp": { "type": "date" }, "geoip": { "type": "object" }, "geoip_city_name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "geoip_continent_code": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "geoip_country_code2": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } },  "user_device_os_name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }}

具体说明:

index_patterns:指定index匹配表达式,这个特性十分重要,如果配置为 ”php-nginx-log*“,则所有以php-nginx-log为前缀的索引都将自动使用该template进行索引创建,而不需要特殊指定aliases:为索引指定一个别名,同样的,通过该配置就能实现我们前面提到的问题,让按照日期创建的新index能够被正确的查询到

CASE4:原index数据迁移(mapping有修改)

1)CASE3开头的时候提到过,需要按照固定的mapping创建index,来达到生成的index能使用规范的数据类型的目的,而历史index中数据想要修改mapping只能重新创建,这时我们通常使用Elasticsearch的reindex特性:

POST _reindex?slices=5&refresh{ "source": { "index": "php-nginx-log-2019.01", "size": 10000 }, "dest": { "index": "php-nginx-log-2019.01.15" } }

说明:

默认情况下,_reindex使用1000进行批量操作,您可以在source中调整batch_size,如上面设置为了1万Reindex支持Sliced Scroll以并行化重建索引过程。 这种并行化可以提高效率,并提供一种方便的方法将请求分解为更小的部分,如上面设置为了slices=51)slices大小的设置可以手动指定,或者设置slices设置为auto,auto的含义是:针对单索引,slices大小=分片数;针对多索引,slices=分片的最小值。

2)当slices的数量等于索引中的分片数量时,查询性能最高效。slices大小大于分片数,非但不会提升效率,反而会增加开销。

3)如果这个slices数字很大(例如500),建议选择一个较低的数字,因为过大的slices 会影响性能。如果要进行大量批量导入,请考虑通过设置index.number_of_replicas来禁用副本:0。主要原因在于:复制文档时,将整个文档发送到副本节点,并逐字重复索引过程。这意味着每个副本都将执行分析,索引和潜在合并过程。

相反,如果使用零副本进行索引,然后在提取完成时启用副本,则恢复过程本质上是逐字节的网络传输。 这比复制索引过程更有效。

2)我们要保证新旧index的数据平滑迁移对用户无感知,此时可以使用前文提到的alias,流程为:

1 . 就index使用alias,数据使用方通过alias查询数据

2 . reindex生成的新index不要创建别名,进行数据reindex操作

3 . 待数据复制完成后,调用remove+add alias接口,该操作为原子操作,可以保证数据无缝迁移,具体代码如下:

POST /_aliases{ "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } }, { "add" : { "index" : "test2", "alias" : "alias1" } } ]}
总结

至此我们就总结完了一些Elasticsearch及ELK架构下常用CASE,通过合理的使用组件的特性,来满足我们的业务需求。

后面我们还将总结一些Logstash的经典CASE。

欢迎关注 高广超的简书博客 与 收藏文章 !

欢迎关注 头条号:互联网技术栈 !

标签: #nginx子目录indexphp