转载请标明原处: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();
}

最新文章

  1. Javascript设计模式学习二(单例)
  2. NotificationCenter接收不到通知的原因
  3. [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题
  4. Mysql-报错:1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost
  5. 【bzoj3624】Apio2008—免费道路
  6. 20145206《Java程序设计》实验二Java面向对象程序设计实验报告
  7. Hibernate框架的使用。。。
  8. github的初次体验及管理代码的心得
  9. 10款基于jquery的web前端特效及源码下载
  10. JAVA使用EPoll来进行NIO处理的方法(转)
  11. 异步协程 的 trip库
  12. 销售订单-修改量-高级定价关联sql
  13. go语言nsq源码解读八 http.go、http_server.go
  14. 打造自己的Android常用知识体系
  15. enumerate() 函数
  16. hdu 1010 走到终点时刚好花掉所有时间 (DFS + 奇偶性剪枝 )
  17. cordova性能优化方法
  18. ef 数据库创建失败
  19. Linux 下 MQ 的安装
  20. Delphi XE3写DLL,用Delphi7调用,报错!

热门文章

  1. python-高级编程-07-端口
  2. PostgreSQL order by 排序问题
  3. change login screen wallpaper on ubuntu14.04
  4. hihoCoder挑战赛29
  5. HDU-1853 Cyclic Tour
  6. ubuntu14.04 安装 tensorflow9.0
  7. BZOJ 4584 [Apio2016]赛艇 ——动态规划
  8. [bzoj1095][ZJOI2007]Hide 捉迷藏 点分树,动态点分治
  9. OSU!(bzoj 4318)
  10. spring执行事务提交后进行一些逻辑操作