• ELK系列--实时日志分析系统ELK 部署与运行中的问题汇总


    前记:

    去年测试了ELK,今年测试了Storm,最终因为Storm需要过多开发介入而放弃,选择了ELK。感谢互联网上各路大神,目前总算是正常运行了。

    logstash+elasticsearch+kibana的搭建参考:http://wsgzao.github.io/post/elk/。由于搭建过程比较简单就不赘述,主要分享几个坑。

    正文:

    1、日志如何获取

     无论是storm方案还是elk,都涉及这个关键问题。为减少和运维、开发的交叉,尽可能独立、快速,加之当时发现了justniffer这个“神器”,遂决定采用交换机流量镜像的方式。

     但是在经历了申请机器、增加网卡之后,痛苦的发现存在掉包问题。一旦流量超过30--40M狂掉包,就别提TCP流还原了。justniffer是调用修改过的libnids,而libnids调用libpacap。因此转向libpcap优化。

     看了很多国内外的论文和研究文档,使用pf-ring会有大幅改善掉包情况。在同事协助下经历了N次的源码调试后,无奈的发现:即使启用了pf-ring,掉包情况依然。可能是网卡太差了。。。

     询问了青藤云安全的大牛,他们的包捕获与流还原技术不卖- -|

     由于涉及justniffer、libpacap、pf_ring的版本对应问题、网卡驱动和源码调试,上述过程耗时其实非常长,最终的结果让人心碎,自己能力不够啊

     无奈放弃流量镜像,转而采用在应用服务器上安装客户端的做法。如果有童鞋有好的方案,希望能分享,谢谢!

    2、缺乏访问权限控制

    由于kibana默认没有设置访问权限控制,因此,直接访问url即可访问。同时elasticsearch也缺乏权限控制,提交相关请求即可查看索引、模板,删除索引。 所以需要设置权限保护,分2个层面:

    1)阻止未授权的用户对ELK平台的访问

    2)为用户设置的index访问权限

     详情参考:http://eligao.com/shield-on-elasticsearch/

    3、无法搜索特殊字符

    由于混杂了kibana、elasticsearch、lunece,导致这个问题比较复杂。谷歌之可以发现,很多内容都是提到:在kibana中搜索时,搜索特殊符号需要使用转义符号转义。但是问题是方法无效!!!

    幸得搜索同事指导,加上自己学习,基本搞清楚情况:

    1)Kibana的搜索完全是传递给Elasticsearch处理的,因此问题出在Elasticsearch;

    2)在创建索引的时候,Elasticsearch默认的索引模板使用了默认的分析器(analyzer)standard对logstash提交的数据进行分析。,而standard默认的分词器(tokenizer)是会剔除特殊字符。也就是说,特殊字符在建立索引的过程中就被剔除了,因此即使使用转义符号也无法搜索特殊字符;相关概念解释见文末说明。

    解决方法:

    1)定制分析器

    官方文档参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-custom-analyzer.html。

    借助Elasticsearch提供的nGram分词器,定制了一个单字符分析器。

    官网的做法是通过API提交。我偷个懒,直接修改了Elasticsearch的配置文件elasticsearch.yml,在最后增加:

    index:
    
      analysis:
    
        tokenizer:
    
          my_ngram_tokenizer:
    
            type: nGram
    
            min_gram : 1
    
            max_gram : 1
    
            token_chars : []
    
        analyzer:
    
          special_analyzer:
    
              type: custom
    
              filter: [lowercase]
    
              tokenizer: my_ngram_tokenizer

    修改后,需要重启Elasticsearch

    2)修改默认模板

    (不推荐新增索引模板,使用非logstash开头的索引模板会导致raw字段丢失。如果已经遇到这个问题,参考https://bbrauns1.wordpress.com/2015/06/04/missing-raw-fields-in-logstashkibana-after-new-index-creation/)

    注意,通过http://localhost:9200/_template/logstash?pretty获取的索引模板和我们需要改的索引模板稍有不同,去掉  "logstash" : {及倒数第二个}保存成logstash.json

    修改上面获得的模板,主要是修改dynamic_templates部分,默认的模板是将所有string类型字段内容进行分析和索引,使用的是默认的standard分析器。同时对raw字段不分词(如cookie.raw等,是logstash自动生成的)

    参考官方文档:https://www.elastic.co/guide/en/elasticsearch/guide/current/custom-dynamic-mapping.html

        "mappings" : {
    
          "_default_" : {
    
            "dynamic_templates" : [ {
    
              "string_fields" : {
    
                "mapping" : {
    
                  "index" : "analyzed",
    
                  "omit_norms" : true,
    
                  "type" : "string",
    
                  "fields" : {
    
                    "raw" : {
    
                      "index" : "not_analyzed",
    
                      "ignore_above" : 256,
    
                      "type" : "string"
    
                    }
    
                  }
    
                },
    
                "match" : "*",
    
                "match_mapping_type" : "string"
    
              }
    
            }

     因此,我们需要增加指定特定字段,比如:

            {
    
              "request" : {
    
                "mapping" : {
    
                  "index" : "analyzed",
    
                  "analyzer" : "special_analyzer",
    
                  "type" : "string",
    
                  "fields" : {
    
                    "raw" : {
    
                      "index" : "not_analyzed",
    
                      "ignore_above" : 256,
    
                      "type" : "string"
    
                    }
    
                  }
    
                },
    
                "match" : "request",
    
                "match_mapping_type" : "string"
    
              }
    
            }, 

    代表我们对request字段内容使用special_analyzer进行分析,同时保留对raw不分析。如果缺少二次映射,则无法获取raw字段,则会对visualize造成影响。

    如果不需要对相关字段进行是分词,则如此配置:

            {
    
              "cookie" : {
    
                "mapping" : {
    
                  "index" : "not_analyzed",
    
                  "type" : "string",
    
                  "fields" : {
    
                    "raw" : {
    
                      "index" : "not_analyzed",
    
                      "ignore_above" : 256,
    
                      "type" : "string"
    
                    }
    
                  }
    
                },
    
                "match" : "cookie",
    
                "match_mapping_type" : "string"
    
              }
    
            },

    3)提交索引模板:

    cd /path/to/logstash.json

    curl -u user -XPUT localhost:9200/_template/logstash -d @logstash.json

    成功后,会返回:{"acknowledged":true}

    4)删除索引,索引模板

    查看现有的所有索引:http://localhost:9200/_cat/indices?v 

    删除所有索引:curl -u user -XDELETE localhost:9200/index

    通过kibana的设置功能,删除之前建立的index pattern

    5)重新添加index pattern

    注:配合kibana的搜索语法,使用双引号""搜索完全匹配,即可解决搜索特殊字符的问题。如果不带双引号,则会搜索字符串中的每个字符。

    4、logstash无法启动,提示bind address 

     原因:

     1)配置目录下存在多个配置文件,而logstash会加载所有conf格式的文件

     解决方案:删除不必要的文件,保留一个conf文件即可

    2)进程未结束

     解决方案:kill -9 pid 强制结束进程,再启动服务即可

    5、字段无法解析 _grokparsefailure 

     kibana无法解析出相应的字段

     原因:正则存在问题或者日志不符合正则格式

     解决方案:在http://grokdebug.herokuapp.com/上调试正则,同时确保日志中不存在多余空格等异常

    还有一种常见原因:空格、空格、空格,重要的事情说三遍!

    6、日志量大,磁盘紧张

    日志量增加非常快,磁盘空间不够用怎么办?可以通过删除较早的索引来缓解

    因此,logstash的配置文件中最好早设置索引带有时间后缀:如logstash-%{+YYYY.MM.dd}"

    说明:

    分析器相关概念:全文搜索引擎会用某种算法对要建索引的文档进行分析, 从文档中提取出若干Token(词元), 这些算法称为Tokenizer(分词器), 这些Token会被进一步处理, 比如转成小写等, 这些处理算法被称为Token Filter(词元处理器), 被处理后的结果被称为Term(词), 文档中包含了几个这样的Term被称为Frequency(词频)。 引擎会建立Term和原文档的Inverted Index(倒排索引), 这样就能根据Term很快到找到源文档了。 文本被Tokenizer处理前可能要做一些预处理, 比如去掉里面的HTML标记, 这些处理的算法被称为Character Filter(字符过滤器), 这整个的分析算法被称为Analyzer(分析器)。 

    详情请参考:http://www.cnblogs.com/buzzlight/p/elasticsearch_analysis.html

    后记:

    不敢想象如果没有google,上面的问题还能不能解决,还要多花多少时间。

  • 相关阅读:
    Pytorch手写线性回归
    numpy+sklearn 手动实现逻辑回归【Python】
    如何用TensorFlow实现线性回归
    进程、线程和携程的通俗解释【刘新宇Python】
    即时通信WebSocket 和Socket.IO
    gRPC【RPC自定义http2.0协议传输】
    Django中MySQL事务的使用
    模拟电磁曲射炮_H题 方案分析【2019年电赛】【刘新宇qq522414928】
    Gitflow工作流
    雪花算法【分布式ID问题】【刘新宇】
  • 原文地址:https://www.cnblogs.com/phoenix--/p/4935778.html
Copyright © 2020-2023  润新知