一、简介

ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式支持需要ZooKeeper的支持。

这里有一个详细的ElasticSearch和Solr的对比:http://solr-vs-elasticsearch.com/

二、基本用法

Elasticsearch集群可以包含多个索引(indices),每一个索引可以包含多个类型(types),每一个类型包含多个文档(documents),然后每个文档包含多个字段(Fields),这种面向文档型的储存,也算是NoSQL的一种吧。

ES比传统关系型数据库,对一些概念上的理解:

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields

从创建一个Client到添加、删除、查询等基本用法:

1、创建Client

public ElasticSearchService(String ipAddress, int port) {client = new TransportClient().addTransportAddress(new InetSocketTransportAddress(ipAddress,port));}

这里是一个TransportClient。

ES下两种客户端对比:

TransportClient:轻量级的Client,使用Netty线程池,Socket连接到ES集群。本身不加入到集群,只作为请求的处理。

Node Client:客户端节点本身也是ES节点,加入到集群,和其他ElasticSearch节点一样。频繁的开启和关闭这类Node Clients会在集群中产生“噪音”。

2、创建/删除Index和Type信息

    // 创建索引public void createIndex() {client.admin().indices().create(new CreateIndexRequest(IndexName)).actionGet();}// 清除所有索引public void deleteIndex() {IndicesExistsResponse indicesExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(new String[] { IndexName })).actionGet();if (indicesExistsResponse.isExists()) {client.admin().indices().delete(new DeleteIndexRequest(IndexName)).actionGet();}}// 删除Index下的某个Typepublic void deleteType(){client.prepareDelete().setIndex(IndexName).setType(TypeName).execute().actionGet();}// 定义索引的映射类型public void defineIndexTypeMapping() {try {XContentBuilder mapBuilder = XContentFactory.jsonBuilder();mapBuilder.startObject().startObject(TypeName).startObject("properties").startObject(IDFieldName).field("type", "long").field("store", "yes").endObject().startObject(SeqNumFieldName).field("type", "long").field("store", "yes").endObject().startObject(IMSIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject().startObject(IMEIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject().startObject(DeviceIDFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject().startObject(OwnAreaFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject().startObject(TeleOperFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject().startObject(TimeFieldName).field("type", "date").field("store", "yes").endObject().endObject().endObject().endObject();PutMappingRequest putMappingRequest = Requests.putMappingRequest(IndexName).type(TypeName).source(mapBuilder);client.admin().indices().putMapping(putMappingRequest).actionGet();} catch (IOException e) {log.error(e.toString());}}

这里自定义了某个Type的索引映射(Mapping),默认ES会自动处理数据类型的映射:针对整型映射为long,浮点数为double,字符串映射为string,时间为date,true或false为boolean。

注意:针对字符串,ES默认会做“analyzed”处理,即先做分词、去掉stop words等处理再index。如果你需要把一个字符串做为整体被索引到,需要把这个字段这样设置:field("index", "not_analyzed")。

详情参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-intro.html

3、索引数据

    // 批量索引数据public void indexHotSpotDataList(List<Hotspotdata> dataList) {if (dataList != null) {int size = dataList.size();if (size > 0) {BulkRequestBuilder bulkRequest = client.prepareBulk();for (int i = 0; i < size; ++i) {Hotspotdata data = dataList.get(i);String jsonSource = getIndexDataFromHotspotData(data);if (jsonSource != null) {bulkRequest.add(client.prepareIndex(IndexName, TypeName,data.getId().toString()).setRefresh(true).setSource(jsonSource));}}BulkResponse bulkResponse = bulkRequest.execute().actionGet();if (bulkResponse.hasFailures()) {Iterator<BulkItemResponse> iter = bulkResponse.iterator();while (iter.hasNext()) {BulkItemResponse itemResponse = iter.next();if (itemResponse.isFailed()) {log.error(itemResponse.getFailureMessage());}}}}}}// 索引数据public boolean indexHotspotData(Hotspotdata data) {String jsonSource = getIndexDataFromHotspotData(data);if (jsonSource != null) {IndexRequestBuilder requestBuilder = client.prepareIndex(IndexName,TypeName).setRefresh(true);requestBuilder.setSource(jsonSource).execute().actionGet();return true;}return false;}// 得到索引字符串public String getIndexDataFromHotspotData(Hotspotdata data) {String jsonString = null;if (data != null) {try {XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();jsonBuilder.startObject().field(IDFieldName, data.getId()).field(SeqNumFieldName, data.getSeqNum()).field(IMSIFieldName, data.getImsi()).field(IMEIFieldName, data.getImei()).field(DeviceIDFieldName, data.getDeviceID()).field(OwnAreaFieldName, data.getOwnArea()).field(TeleOperFieldName, data.getTeleOper()).field(TimeFieldName, data.getCollectTime()).endObject();jsonString = jsonBuilder.string();} catch (IOException e) {log.equals(e);}}return jsonString;}

ES支持批量和单个数据索引。

4、查询获取数据

    // 获取少量数据100个private List<Integer> getSearchData(QueryBuilder queryBuilder) {List<Integer> ids = new ArrayList<>();SearchResponse searchResponse = client.prepareSearch(IndexName).setTypes(TypeName).setQuery(queryBuilder).setSize(100).execute().actionGet();SearchHits searchHits = searchResponse.getHits();for (SearchHit searchHit : searchHits) {Integer id = (Integer) searchHit.getSource().get("id");ids.add(id);}return ids;}// 获取大量数据private List<Integer> getSearchDataByScrolls(QueryBuilder queryBuilder) {List<Integer> ids = new ArrayList<>();// 一次获取100000数据SearchResponse scrollResp = client.prepareSearch(IndexName).setSearchType(SearchType.SCAN).setScroll(new TimeValue(60000)).setQuery(queryBuilder).setSize(100000).execute().actionGet();while (true) {for (SearchHit searchHit : scrollResp.getHits().getHits()) {Integer id = (Integer) searchHit.getSource().get(IDFieldName);ids.add(id);}scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();if (scrollResp.getHits().getHits().length == 0) {break;}}return ids;}

这里的QueryBuilder是一个查询条件,ES支持分页查询获取数据,也可以一次性获取大量数据,需要使用Scroll Search。

5、聚合(Aggregation Facet)查询

    // 得到某段时间内设备列表上每个设备的数据分布情况<设备ID,数量>public Map<String, String> getDeviceDistributedInfo(String startTime,String endTime, List<String> deviceList) {Map<String, String> resultsMap = new HashMap<>();QueryBuilder deviceQueryBuilder = getDeviceQueryBuilder(deviceList);QueryBuilder rangeBuilder = getDateRangeQueryBuilder(startTime, endTime);QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(deviceQueryBuilder).must(rangeBuilder);TermsBuilder termsBuilder = AggregationBuilders.terms("DeviceIDAgg").size(Integer.MAX_VALUE).field(DeviceIDFieldName);SearchResponse searchResponse = client.prepareSearch(IndexName).setQuery(queryBuilder).addAggregation(termsBuilder).execute().actionGet();Terms terms = searchResponse.getAggregations().get("DeviceIDAgg");if (terms != null) {for (Terms.Bucket entry : terms.getBuckets()) {resultsMap.put(entry.getKey(),String.valueOf(entry.getDocCount()));}}return resultsMap;}

Aggregation查询可以查询类似统计分析这样的功能:如某个月的数据分布情况,某类数据的最大、最小、总和、平均值等。

详情参考:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-aggs.html

三、集群配置

配置文件elasticsearch.yml

集群名和节点名:

#cluster.name: elasticsearch

#node.name: "Franz Kafka"

是否参与master选举和是否存储数据

#node.master: true

#node.data: true

分片数和副本数

#index.number_of_shards: 5
#index.number_of_replicas: 1

master选举最少的节点数,这个一定要设置为整个集群节点个数的一半加1,即N/2+1

#discovery.zen.minimum_master_nodes: 1

discovery ping的超时时间,拥塞网络,网络状态不佳的情况下设置高一点

#discovery.zen.ping.timeout: 3s

注意,分布式系统整个集群节点个数N要为奇数个!!

如何避免ElasticSearch发生脑裂(brain split):http://blog.trifork.com/2013/10/24/how-to-avoid-the-split-brain-problem-in-elasticsearch/

即使集群节点个数为奇数,minimum_master_nodes为整个集群节点个数一半加1,也难以避免脑裂的发生,详情看讨论:https://github.com/elastic/elasticsearch/issues/2488

四、Elasticsearch插件

1、elasticsearch-head是一个elasticsearch的集群管理工具:./elasticsearch-1.7.1/bin/plugin -install mobz/elasticsearch-head

2、elasticsearch-sql:使用SQL语法查询elasticsearch:./bin/plugin -u https://github.com/NLPchina/elasticsearch-sql/releases/download/1.3.5/elasticsearch-sql-1.3.5.zip --install sql

github地址:https://github.com/NLPchina/elasticsearch-sql

3、elasticsearch-bigdesk是elasticsearch的一个集群监控工具,可以通过它来查看ES集群的各种状态。

安装:./bin/plugin -install lukas-vlcek/bigdesk

访问:http://192.103.101.203:9200/_plugin/bigdesk/,

4、elasticsearch-servicewrapper插件是ElasticSearch的服务化插件,

在https://github.com/elasticsearch/elasticsearch-servicewrapper下载该插件后,解压缩,将service目录拷贝到elasticsearch目录的bin目录下。

而后,可以通过执行以下语句安装、启动、停止ElasticSearch:

sh elasticsearch install

sh elasticsearch start

sh elasticsearch stop

参考:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

http://stackoverflow.com/questions/10213009/solr-vs-elasticsearch

作者:阿凡卢
出处:http://www.cnblogs.com/luxiaoxun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/p/4869509.html

ElasticSearch的基本用法与集群搭建相关推荐

  1. Elasticsearch(二、高级查询+集群搭建)

    1内容概述 ElasticSearch 高级操作 ElasticSearch 集群管理 2 ElasticSearch高级操作 2.1 bulk批量操作-脚本 脚本: 测试用的5号文档 POST /p ...

  2. Day123.ElasticSearch:CAP定理、集群搭建、架构原理及分片、倒排索引、面试题

    目录 一.CAP定理 二.ES集群 1.搭建集群: 2.head 插件安装 3.集群测试 4.核心概念 二.架构原理及分片 一. ElasticSearch 分片 二. 分片控制 三. 分片原理 1. ...

  3. elasticsearch 在linux环境的集群搭建

    搭建集群节点前,首先了解下节点的三个角色: 主结点:master节点主要用于集群的管理及索引 比如新增结点.分片分配.索引的新增和删除等. 数据结点:data 节点上保存了数据分片,它负责索引和搜索操 ...

  4. elasticsearch集群搭建实例

    下个月又开始搞搜索了,几个月没动这块还好没有落下. 晚上在自己虚拟机上搭建了一个简易搜索集群,分享一下. 操作系统环境: Red Hat 4.8.2-16 elasticsearch : elasti ...

  5. 六,搭建elasticsearch集群搭建

    @Author : By Runsen @Date : 2020/6/12 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘 ...

  6. elasticsearch系列八:ES 集群管理(集群规划、集群搭建、集群管理)

    一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...

  7. ES安装的详细步骤、ES的集群搭建以及ElasticSearch安装时可能出现的问题

    目录 什么是es? 正排索引和倒排索引 安装 ElasticSearch的简单步骤 环境需求 安装ES 下载 设置虚拟机内存 创建用户 安装 ES的目录结构及其作用 配置文件以及作用 修改配置文件el ...

  8. elasticsearch集群搭建及springboot集成使用

    elasticsearch集群搭建及springboot集成使用 1. ES介绍 2. 原理 2.1 核心概念 2.2 索引功能 2.3 ES特性 3. 分词器(analyzer) 4. 集群搭建 4 ...

  9. mac下ElasticSearch 集群搭建,使用Kibana配置和管理集群

    Elasticsearch如果做集群的话Master节点至少三台服务器或者三个Master实例加入相同集群,三个Master节点最多只能故障一台Master节点,如果故障两个Master节点,Elas ...

最新文章

  1. php和python哪个工资高-前端,java,php,python工程师哪个最缺 知乎
  2. 第二话 最最最简单的计算机
  3. 爱我少一点,我请求你
  4. 为什么技术人一定要懂点“可信计算”?
  5. golang中的variable和data types
  6. 主播冲刺GMV,全靠iPhone和茅台?
  7. ES组件elasticsearch-head报错 npm ERR! Please include the following file with any support request
  8. 物联网卡在建筑行业的应用结果
  9. adb.exe可能被其他程序关闭_怎么快速的做自己小程序商城推广?
  10. 浅谈Java栈内存和堆内存
  11. ※设计模式※→☆创建型模式☆============Builder模式(五)
  12. android 渠道 代码重复,Android Studio多渠道打包(示例代码)
  13. 多张表格链接一起——《超级处理器》应用
  14. Unirech腾讯云代充-通过VNC 登录腾讯云国际版Windows云服务器实例教程
  15. vue 修改地址栏参数
  16. 面试笔记@MySQL
  17. 程序员健康指南--努力健康起来吧
  18. web前端性能(一)
  19. 京东2019校招算法岗笔试题
  20. android Jetpack StateFlow使用

热门文章

  1. 可以声明一个抽象类类型变量_TypeScript系列(二)变量声明和数据类型
  2. (哈哈)漫画告诉你什么是屎一样的代码(屎里蕴含着代码的秘密)
  3. 使用Perl进行网页数据抓取[初学者简明版]
  4. MySQL如何用一条SQL将一张表里的数据插入到另一张表
  5. ps-色彩饱和度的设计
  6. 现代质量管理方法的应用思考和实践
  7. 做过CC1020的苦逼前人告诉你(分拿来)
  8. Linux 命令(80)—— chown 命令
  9. Linux 命令(67)—— time 命令
  10. CVTE 2017 秋季校招笔试题回忆(C++后台)