ElasticSearch的基本用法与集群搭建
一、简介
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
ElasticSearch的基本用法与集群搭建相关推荐
- Elasticsearch(二、高级查询+集群搭建)
1内容概述 ElasticSearch 高级操作 ElasticSearch 集群管理 2 ElasticSearch高级操作 2.1 bulk批量操作-脚本 脚本: 测试用的5号文档 POST /p ...
- Day123.ElasticSearch:CAP定理、集群搭建、架构原理及分片、倒排索引、面试题
目录 一.CAP定理 二.ES集群 1.搭建集群: 2.head 插件安装 3.集群测试 4.核心概念 二.架构原理及分片 一. ElasticSearch 分片 二. 分片控制 三. 分片原理 1. ...
- elasticsearch 在linux环境的集群搭建
搭建集群节点前,首先了解下节点的三个角色: 主结点:master节点主要用于集群的管理及索引 比如新增结点.分片分配.索引的新增和删除等. 数据结点:data 节点上保存了数据分片,它负责索引和搜索操 ...
- elasticsearch集群搭建实例
下个月又开始搞搜索了,几个月没动这块还好没有落下. 晚上在自己虚拟机上搭建了一个简易搜索集群,分享一下. 操作系统环境: Red Hat 4.8.2-16 elasticsearch : elasti ...
- 六,搭建elasticsearch集群搭建
@Author : By Runsen @Date : 2020/6/12 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘 ...
- elasticsearch系列八:ES 集群管理(集群规划、集群搭建、集群管理)
一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...
- ES安装的详细步骤、ES的集群搭建以及ElasticSearch安装时可能出现的问题
目录 什么是es? 正排索引和倒排索引 安装 ElasticSearch的简单步骤 环境需求 安装ES 下载 设置虚拟机内存 创建用户 安装 ES的目录结构及其作用 配置文件以及作用 修改配置文件el ...
- elasticsearch集群搭建及springboot集成使用
elasticsearch集群搭建及springboot集成使用 1. ES介绍 2. 原理 2.1 核心概念 2.2 索引功能 2.3 ES特性 3. 分词器(analyzer) 4. 集群搭建 4 ...
- mac下ElasticSearch 集群搭建,使用Kibana配置和管理集群
Elasticsearch如果做集群的话Master节点至少三台服务器或者三个Master实例加入相同集群,三个Master节点最多只能故障一台Master节点,如果故障两个Master节点,Elas ...
最新文章
- php和python哪个工资高-前端,java,php,python工程师哪个最缺 知乎
- 第二话 最最最简单的计算机
- 爱我少一点,我请求你
- 为什么技术人一定要懂点“可信计算”?
- golang中的variable和data types
- 主播冲刺GMV,全靠iPhone和茅台?
- ES组件elasticsearch-head报错 npm ERR! Please include the following file with any support request
- 物联网卡在建筑行业的应用结果
- adb.exe可能被其他程序关闭_怎么快速的做自己小程序商城推广?
- 浅谈Java栈内存和堆内存
- ※设计模式※→☆创建型模式☆============Builder模式(五)
- android 渠道 代码重复,Android Studio多渠道打包(示例代码)
- 多张表格链接一起——《超级处理器》应用
- Unirech腾讯云代充-通过VNC 登录腾讯云国际版Windows云服务器实例教程
- vue 修改地址栏参数
- 面试笔记@MySQL
- 程序员健康指南--努力健康起来吧
- web前端性能(一)
- 京东2019校招算法岗笔试题
- android Jetpack StateFlow使用