一、ElasticSearch和Hbase
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。 Elasticsearch的性能是solr的50倍。
HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、
实时读写的分布式数据库
– 利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理
HBase中的海量数据,利用Zookeeper作为其分布式协同服务
– 主要用来存储非结构化和半结构化的松散数据(列存 NoSQL 数据库)
二、需求分析&服务器环境设置
主要是做一个文章的搜索。有文章标题、作者、摘要、内容四个主要信息。效果图如下:这里样式我就没怎么设置了,想要好看一点的可以自己加css。
服务器:
在3台centos7中部署,主机名为node1-node3.安装好ElasticSearch并配置好集群,
1. 解压
2. 修改config/elasticsearch.yml (注意要顶格写,冒号后面要加一个空格)
a) Cluster.name: tf (同一集群要一样)
b) Node.name: node-1 (同一集群要不一样)
c) Network.Host: 192.168.44.137 这里不能写127.0.0.1
3. 解压安装kibana
4. 再congfig目录下的kibana.yml中修改elasticsearch.url
5. 安装插件
Step 1: Install Marvel into Elasticsearch:
bin/plugin install license
bin/plugin install marvel-agent
Step 2: Install Marvel into Kibana
bin/kibana plugin --install elasticsearch/marvel/latest
Step 3: Start Elasticsearch and Kibana
bin/elasticsearch
bin/kibana
启动好elasticsearch集群后,
然后启动zookeeper、hdfs、hbase。zkService.sh start 、start-all.sh、start-hbase.sh。
接下来就是剩下编码步骤了。
三、编码开发
1、首先在IntelliJ IDEA中新建一个maven工程,加入如下依赖。
2、Dao层
private Integer id;
private String title;
private String describe;
private String content;
private String author;
实现其getter/setter方法。
3、数据准备
在桌面新建一个doc1.txt文档,用于把我们需要查询的数据写入到里面,这里我只准备了5条数据。中间用tab键隔开。
4、在hbase中建立表。表名师doc,列族是cf。
public static void main(String[] args) throws Exception {
HbaseUtils hbase = new HbaseUtils();
//创建一张表
hbase.createTable("doc","cf");
}
/**
* 创建一张表
* @param tableName
* @param column
* @throws Exception
*/
public void createTable(String tableName, String column) throws Exception {
if(admin.tableExists(TableName.valueOf(tableName))){
System.out.println(tableName+"表已经存在!");
}else{
HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));
tableDesc.addFamily(new HColumnDescriptor(column.getBytes()));
admin.createTable(tableDesc);
System.out.println(tableName+"表创建成功!");
}
}
5、导入索引。这一步的时候确保你的hdfs和hbase以及elasticsearch是处于开启状态。
@Test
public void createIndex() throws Exception {
List
File file = new File("C:\\Users\\asus\\Desktop\\doc1.txt");
List
for(String line : list){
Doc Doc = new Doc();
String[] split = line.split("\t");
System.out.print(split[0]);
int parseInt = Integer.parseInt(split[0].trim());
Doc.setId(parseInt);
Doc.setTitle(split[1]);
Doc.setAuthor(split[2]);
Doc.setDescribe(split[3]);
Doc.setContent(split[3]);
arrayList.add(Doc);
}
HbaseUtils hbaseUtils = new HbaseUtils();
for (Doc Doc : arrayList) {
try {
//把数据插入hbase
hbaseUtils.put(hbaseUtils.TABLE_NAME, Doc.getId()+"", hbaseUtils.COLUMNFAMILY_1, hbaseUtils.COLUMNFAMILY_1_TITLE, Doc.getTitle());
hbaseUtils.put(hbaseUtils.TABLE_NAME, Doc.getId()+"", hbaseUtils.COLUMNFAMILY_1, hbaseUtils.COLUMNFAMILY_1_AUTHOR, Doc.getAuthor());
hbaseUtils.put(hbaseUtils.TABLE_NAME, Doc.getId()+"", hbaseUtils.COLUMNFAMILY_1, hbaseUtils.COLUMNFAMILY_1_DESCRIBE, Doc.getDescribe());
hbaseUtils.put(hbaseUtils.TABLE_NAME, Doc.getId()+"", hbaseUtils.COLUMNFAMILY_1, hbaseUtils.COLUMNFAMILY_1_CONTENT, Doc.getContent());
//把数据插入es
Esutil.addIndex("tfjt","doc", Doc);
} catch (Exception e) {
e.printStackTrace();
}
}
}
数据导入成功之后可以在服务器上通过命令查看一下:
curl -XGET http://node1:9200/tfjt/_search
7、搜索。
在这里新建了一个工具类Esutil.java,主要用于处理搜索的。注意,我们默认的elasticsearch是9200端口的,这里数据传输用的是9300,不要写成9200了,然后就是集群名字为tf,也就是前面配置的集群名。还有就是主机名node1-node3,这里不能写ip地址,如果是本地测试的话,你需要在你的window下面配置hosts文件。
public class Esutil {
public static Client client = null;
/**
* 获取客户端
* @return
*/
public static Client getClient() {
if(client!=null){
return client;
}
Settings settings = Settings.settingsBuilder().put("cluster.name", "tf").build();
try {
client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node1"), 9300))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node2"), 9300))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node3"), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
public static String addIndex(String index,String type,Doc Doc){
HashMap
hashMap.put("id", Doc.getId());
hashMap.put("title", Doc.getTitle());
hashMap.put("describe", Doc.getDescribe());
hashMap.put("author", Doc.getAuthor());
IndexResponse response = getClient().prepareIndex(index, type).setSource(hashMap).execute().actionGet();
return response.getId();
}
public static Map
SearchRequestBuilder builder = getClient().prepareSearch(index);
builder.setTypes(type);
builder.setFrom(start);
builder.setSize(row);
//设置高亮字段名称
builder.addHighlightedField("title");
builder.addHighlightedField("describe");
//设置高亮前缀
builder.setHighlighterPreTags("");
//设置高亮后缀
builder.setHighlighterPostTags("");
builder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
if(StringUtils.isNotBlank(key)){
// builder.setQuery(QueryBuilders.termQuery("title",key));
builder.setQuery(QueryBuilders.multiMatchQuery(key, "title","describe"));
}
builder.setExplain(true);
SearchResponse searchResponse = builder.get();
SearchHits hits = searchResponse.getHits();
long total = hits.getTotalHits();
Map
SearchHit[] hits2 = hits.getHits();
map.put("count", total);
List
8、使用spring控制层处理
在里面的spring配置这里就不说了,代码文末提供。
@RequestMapping("/search.do")
public String serachArticle(Model model,
@RequestParam(value="keyWords",required = false) String keyWords,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "3") Integer pageSize){
try {
keyWords = new String(keyWords.getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Map
int count = 0;
try {
map = Esutil.search(keyWords,"tfjt","doc",(pageNum-1)*pageSize, pageSize);
count = Integer.parseInt(((Long) map.get("count")).toString());
} catch (Exception e) {
logger.error("查询索引错误!{}",e);
e.printStackTrace();
}
PageUtil
List
page.setList(articleList);
model.addAttribute("total",count);
model.addAttribute("pageNum",pageNum);
model.addAttribute("page",page);
model.addAttribute("kw",keyWords);
return "index.jsp";
}
9、页面
10、项目发布
在IntelliJ IDEA 中配置好常用的项目,这里发布名Application context名字为es,当然你也可以自定义设置。