转载请标明原处:http://blog.csdn.net/hu948162999/article/details/50563110

本来这块业务 是放到SolrCloud上去的 , 然后 採用solr的facet统计查询,

详细代码參考之前写的文章:http://blog.csdn.net/hu948162999/article/details/50162643

近期遇到SolrCloud 遇到一些问题。。查询db时间过长,SolrCloud的长连接CloudSolrServer老timeout。索引的效率也不够满

意。为了稳定。临时先还原solr单机版本号(上线时,被运维打回来了)。搜索日志就用elasticsearch实时去处理。

大概流程:

基于日志系统ELK 的原型下。參考ELK处理nginx日志文章:http://blog.csdn.net/hu948162999/article/details/50502875

还是用logstash正则去解析搜索日志。搜索日志採用log4j生成。logstash检測到传递给elasticsearch。

log4j:

log4j.appender.E.layout.ConversionPattern= %d|%m%n

logstash配置

新增logstash_search.conf:

input {
file {
type => "searchword"
path => ["/home/work/log/hotword/data"]
}
}
filter {
grok {
match => [
"message", "%{TIMESTAMP_ISO8601:timestamp}\|\{%{GREEDYDATA:kvs}\}"
]
}
kv {
source => "kvs"
field_split => ","
value_split => "="
trimkey => " "
}
date {
match => ["timestamp" , "YYYY-MM-dd HH:mm:ss,SSS"]
}
}
output {
elasticsearch {
hosts => ["host1:9200", "host2:9200", "host3:9200", "host4:9200"]
index => "searchword-%{+YYYY.MM.dd}"
}
}

这里要注意聚合操作的时候。

Logstash 自带有一个优化好的模板。其默认的mapping,string类型都是analyzer。

也就是说,默认分

词是採用单字分词的。

改动默认的logstash mapping模板。參考 http://udn.yyuap.com/doc/logstash-best-practice-cn/output/elasticsearch.html

结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

启动logstash:

nohup  bin/logstash -f conf/logstash_search.conf &

运行搜索測试。

能够立即在elasticsearch的插件上看到该搜索行为日志的数据索引。这就是elk的实时性了。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

elasticsearch java端

參考指定mapping和聚合查询代码:

	Client client=esobj.getClient();
SearchResponse response = client.prepareSearch("searchword*").setTypes("searchword").addAggregation(AggregationBuilders.terms("hotword").field("keyword")).execute().actionGet();
Terms terms = response.getAggregations().get("hotword");
	/**
* 初始化索引
* @param client
* @param indexName
* @param indexType
* @param cols
* @return 初始化成功,返回true。否则返回false
* @throws Exception
*/
public static boolean initIndexMapping(Client client, String indexName, String indexType, List<ColumnInfo> cols) throws Exception {
if(StringUtil.isEmpty(indexName) || StringUtil.isEmpty(indexType)) {
return false;
}
indexName = indexName.toLowerCase();
indexType = indexType.toLowerCase();
//推断索引库是否存在
if(indicesExists(client, indexName)) {
OpenIndexRequestBuilder openIndexBuilder = new OpenIndexRequestBuilder(client.admin().indices(), OpenIndexAction.INSTANCE);
openIndexBuilder.setIndices(indexName).execute().actionGet();
}else{
//不存在则新建索引库
client.admin().indices().prepareCreate(indexName).execute().actionGet();
} TypesExistsRequest ter = new TypesExistsRequest(new String[]{indexName.toLowerCase()}, indexType);
boolean typeExists = client.admin().indices().typesExists(ter).actionGet().isExists();
//假设 存在 返回!不能覆盖mapping
if(typeExists) {
return true;
}
//定义索引字段属性
XContentBuilder mapping = jsonBuilder().startObject().startObject(indexType).startObject("properties");
for (ColumnInfo col : cols) {
String colName = col.getName().toLowerCase().trim();
String colType = col.getType().toLowerCase().trim(); if("string".equals(colType)) {
mapping.startObject(colName).field("type", colType).field("store", ""+col.isStore()).field("indexAnalyzer", col.getIndexAnalyzer()).field("searchAnalyzer", col.getSearchAnalyzer()).field("include_in_all", col.isStore()).field("boost", col.getBoost()).endObject();
}else if("long".equals(colType)) {
mapping.startObject(colName).field("type", colType).field("index", "not_analyzed").field("include_in_all", false).endObject();
}else if("date".equals(colType)) {
mapping.startObject(colName).field("type", colType).field("format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd").field("index", "not_analyzed").field("include_in_all", false).endObject();
}else {
mapping.startObject(colName).field("type", "string").field("index", "not_analyzed").endObject();
} }
mapping.endObject().endObject().endObject();
PutMappingRequest mappingRequest = Requests.putMappingRequest(indexName).type(indexType).source(mapping);
PutMappingResponse response = client.admin().indices().putMapping(mappingRequest).actionGet();
return response.isAcknowledged();
}

用ELK 实时处理搜索日志的更多相关文章

  1. ELK+kafka构建日志收集系统

    ELK+kafka构建日志收集系统   原文  http://lx.wxqrcode.com/index.php/post/101.html   背景: 最近线上上了ELK,但是只用了一台Redis在 ...

  2. ELK搭建实时日志分析平台之一ElasticSearch搭建

    文:铁乐与猫 系统:CentOS Linux release 7.3.1611 (Core) 注:我这里为测试和实验方便,ELK整套都装在同一台服务器环境中了,生产环境的话,可以分开搭建在不同的服务器 ...

  3. [elk]kibana搜索绘图

    kibana绘图 好些日志入库了需要分析. 1,首先分析top10 url的table和柱状分布 2,其次想着分析下404所占比例,以及404所对应的url table. 3,最后分析一下请求总数. ...

  4. K8S上的ELK和应用日志上报实战

    来源:DevOps ID:Idevops168 本次实战的基础结构如下图所示: 一共有两个Pod:ELK和web应用: ELK的Pod会暴露两个服务,一个暴露logstash的5044端口,给file ...

  5. ELK搭建实时日志分析平台

    ELK搭建实时日志分析平台 导言 ELK由ElasticSearch.Logstash和Kiabana三个开源工具组成,ELK平台可以同时实现日志收集.日志搜索和日志分析的功能.对于生产环境中海量日志 ...

  6. ELK +Nlog 分布式日志系统的搭建 For Windows

    前言 我们为啥需要全文搜索 首先,我们来列举一下关系型数据库中的几种模糊查询 MySql : 一般情况下LIKE 模糊查询  SELECT * FROM `LhzxUsers` WHERE UserN ...

  7. ELK对nginx日志进行流量监控

    ELK对nginx日志进行流量监控 一.前言 线上有一套ELK单机版,版本为5.2.1.现在想把nginx访问日志接入到elk里,进行各个域名使用流量带宽的统计分析.要把nginx日志传输到elk上, ...

  8. 使用Docker快速部署ELK分析Nginx日志实践

    原文:使用Docker快速部署ELK分析Nginx日志实践 一.背景 笔者所在项目组的项目由多个子项目所组成,每一个子项目都存在一定的日志,有时候想排查一些问题,需要到各个地方去查看,极为不方便,此前 ...

  9. 基于Centos 7.4 搭建ELK整合SpringBoot日志收集

    基于Centos 7.4搭建es7.12.0+logstash-7.12.0+kibana-7.12.0(ELK)整合SpringBoot日志收集 注:Skywalking和logstash可共用一个 ...

随机推荐

  1. Iterator设计模式--jdk1.7

    参照:http://www.cnblogs.com/tstd/p/5049338.html java.util.Iterator<E>是一个接口,它的定义如下: public interf ...

  2. HDU——4162Shape Number(字符串的最小表示)

    Shape Number Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  3. 正则表达式的\b与\B总结

    \b 单词边界,是指单词与符号之间的边界,是一个位置,不是空格或字符.(这里单词可以是中文字符,英文字符,数字:  符号可以是中文符号,英文符号,空格,制表符,换行).不能与量词?+*{1}{2,5} ...

  4. ubuntu下卸载python2和升级python3.5

    卸载python只需一条语句就可以实现 sudu apt-get remove python ubuntu下安装python3 sudo apt-get install python3 但这样只安装了 ...

  5. [USACO12DEC]第一!First! (Trie树,拓扑排序)

    题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...

  6. form标签

    一 什么是form标签 <form> 标签用于为用户输入创建 HTML 表单. 表单用于向服务器传输数据. 二 属性 1 method method 属性规定如何发送表单数据(表单数据发送 ...

  7. vue 按需加载

    vue 构建单页面应用,但是问题是随着系统的体积变大,js文件也体积太大了,这时候就需要按需要进行加载了 vue-router提供了懒加载的方式 const Foo = resolve => r ...

  8. TSP 旅行商问题(状态压缩dp)

    题意:有n个城市,有p条单向路径,连通n个城市,旅行商从0城市开始旅行,那么旅行完所有城市再次回到城市0至少需要旅行多长的路程. 思路:n较小的情况下可以使用状态压缩dp,设集合S代表还未经过的城市的 ...

  9. c#.net分类上升达人~~~呵呵。。。

    原文发布时间为:2008-11-11 -- 来源于本人的百度文章 [由搬家工具导入] 觉得自己蛮无聊的~~~~~~~~~(>_<)~~~~

  10. Android之framework修改底部导航栏NavigationBar动态显示和隐藏

     原文链接 http://blog.csdn.net/way_ping_li/article/details/45727335 git diff diff --git a/frameworks/bas ...