同社のクラウドアプリケーションプラットフォームアプリケーションの背後にあるテストES環境を実行するために、独自の初めに建てられたES検索を使用して、最近のプロジェクト、
かなりの紆余曲折中ESドッキングプロセスは、多くの問題、記録の下で統合に遭遇しました:
1、ES 9200と9300ポート説明
HTTPプロトコルのような9200、主に外部との通信のために、ESのRESTfulインターフェイスポート番号を露出
ESクラスタ間で9300を介して通信することです
ジャーの間のTCP 9300契約は、TCPプロトコル通信を介して行われるように
ESのドッキングポート9200を使用してください、9300ポートを使用することは推奨されていません
図2に示すように、マスタデータとクライアントが差分ノード
クラスタが設定することをお勧め3つのマスターノードとして以上のノードを、これらのノードは、マスターノード、クラスタ全体のメンテナンス状態になっのみ責任を負います。
次に、データ量は、データを記憶するための唯一の原因であるデータノードの数、サービスの後者提供インデキシング及びクエリインデックスを設定するので、ユーザの要求より頻繁な場合には、これらのノードの圧力が比較的大きくなる
ようにクラスタを設定することを提案しますバッチ取り込みノードはまた、ユーザーの要求を処理し、負荷分散やその他の機能を達成するために要求を転送するための唯一の責任であるクライアント・ノードとして知られています。
マスター・ノード:通常のサーバは(一般的にはCPUのメモリ消費)することができ、データノード:ディスク、メモリ、の主要な消費者クライアント|インジェスト・ノード:通常のサーバは(あなたが集計操作をグループ化したい場合、それはメモリノードももう少し割り当てられていることが推奨される)ことができます
3、使用中のjarパッケージのバージョンドッキングES ESのバージョンが一致している必要があります
ESをドッキングすると、一貫性のjarパッケージのバージョンドッキングESとESのバージョンを確認するために必ず、例えば、私はESバージョン6.1.4を使用して、対応するjarファイルのパッケージには、6.1.4にする必要があり、次のように、POMの情報は以下のとおりです。
<依存>
<groupIdを> org.elasticsearch </ groupIdを>
<たartifactId> elasticsearch </たartifactId>
<バージョン> 6.1.4 </バージョン>
</依存関係>
<依存>
<groupIdを> org.elasticsearch.client </ groupIdを>
<たartifactId>輸送</たartifactId>
<バージョン> 6.1.4 </バージョン>
</依存関係>
<依存>
<groupIdを> org.elasticsearch.client </ groupIdを>
<たartifactId> elasticsearch休止・高レベルのクライアント</たartifactId>
<バージョン> 6.1.4 </バージョン>
</依存関係>
プロジェクトはまた、ネッティーフレームを使用している場合は、必ず一貫して使用されるパッケージのバージョンネッティーのネッティーフレームとドッキングES関連のjarパッケージを作ります
例外が発生する可能性があります時にそうでない場合、クライアントは閉じられ、たとえば、私は異常な異常があらわれ、「スレッドを起動していなかった」など、ハングアップするアプリケーション全体を引き起こします。
関連するバージョン6.1.4のjarパッケージネッティーバージョンのESは、プロジェクトで参照し、以下のように、同じjarファイルのパッケージを使用し、4.1.13.Finalです。
<依存>
<groupIdを> io.netty </ groupIdを>
<たartifactId>ネッティー-すべての</たartifactId>
<バージョン> 4.1.13.Final </バージョン>
</依存関係>
4,使用tcp及http方式对接es,请使用http方式对接es,tcp方式多用于es节点间通讯,不推荐做对外对接(而且在使用中感觉http方式会明显快于tcp方式)
4.1 tcp方式对接可以使用类 org.elasticsearch.transport.client.PreBuiltTransportClient,端口9300,可以对接master节点和client节点
初始化方式为:
//说明:clusterName为集群名称,在ES6.x版本后可以不使用;client.transport.sniff表示是否嗅探(设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中,这样做的好处是一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器)
Settings settings = Settings.builder().put("cluster.name",clusterName).put("client.transport.sniff", true).build();
//esurl是es的对接信息,我这边不同节点间使用, 分隔,例如 1.1.1.2:9300
// getHttpHosts 用于使用ip和端口初始化一个个TransportAddress对象,最终返回一个TransportAddress 数组,
List<String> hostNames = Arrays.asList(esurl.split(","));
client = new PreBuiltTransportClient(settings).addTransportAddresses(getHttpHosts(hostNames));
4.2 http方式对接可以使用类 org.elasticsearch.client.RestHighLevelClient,端口9200,只可以对接client节点
初始化方式如下:
// esurl是es的对接信息,我这边不同节点间使用, 分隔,例如 1.1.1.2:9300
// getHttpHosts 用于使用ip和端口初始化一个个HttpHost对象,最终返回一个HttpHost数组,
RestClientBuilder clientBuilder = RestClient.builder(getHttpHosts(esurl));
RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
但是很多情况下http方式对接es需要输入鉴权信息(用户名及密码),此时的对接方式如下:
(此处摘录自这里:https://msd.misuland.com/pd/3255817963235711680)
// esname为用户名, espassword为密码
String auth = Base64.encodeBase64String((esname + ":" + espassword).getBytes());
RestClientBuilder clientBuilder = RestClient.builder(getHttpHosts(esurl));
clientBuilder.setDefaultHeaders(new BasicHeader[] { new BasicHeader("Authorization", "Basic " + auth) });
RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
5,es查询
需要先构建SearchSourceBuilder,然后通过client查询结果SearchResponse,然后在通过SearchResponse获取查询返回值,直接上代码如下:
// 构建查询请求对象
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// 设置查询条件
queryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("id", id));
sourceBuilder.query(queryBuilder);
// 设置排序依据,及排序方式
sourceBuilder.sort("timestamp", SortOrder.DESC);
// 设置起始页及每页大小
sourceBuilder.from(page);
sourceBuilder.size(size);
// 设置查询索引信息及类型
SearchRequest request = new SearchRequest(INDEX_NAME);
request.types(INDEX_TYPE);
request.source(sourceBuilder);
.....
// 查询,我这边使用的是http方式,如果使用tcp方式请使用如下语句response = client.search(request).get(); (将其转换为一个同步操作)
response = client.search(request);
if (response == null || response.getHits().getTotalHits() == 0) {
LOGGER.error("ES查询返回空");
}
// 将数据转换为结果对象,直接将结果json字符串序列化为目标对象
SearchHit[] hits = response.getHits().getHits();
for (SearchHit sh : hits) {
Info info = new Info();
try {
info= JSON.parseObject(sh.getSourceAsString(), Info.class);
} catch (Exception e) {
LOGGER.error("ES结果序列化失败:{}", sh.getSourceAsString(), e);
continue;
}
list.add(info);
}
6,ES检索语法
在上面构建ES查询请求时,我们使用一些检索语法,用于构建查询条件, 例如
queryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("id", id)); 这句里面的must和matchPhrasePrefixQuery即为一些检索语法,
这些语法很容易找到大量介绍,这里记录一些我感觉很不错的文章地址:
ES 高级检索语法:https://www.cnblogs.com/shoufeng/p/11103913.html
es 的常用查询语法 : https://blog.csdn.net/qingmoruoxi/article/details/77221602
Es学习系列之一: 常见的查询场景总结 : http://tech.dianwoda.com/2017/09/22/esxue-xi-xi-lie-zhi-chang-jian-de-cha-xun-chang-jing-zong-jie/
7, ES提示某个字段不可用于排序
此时需要修改该字段配置,使其可以排序,主要是设置fielddata属性为true,例如
url: ip:9200/index/_mapping/type 使用POST方法, index为索引,type为索引中数据的类型
内容: {"properties":{"time":{"type":"text","fielddata":true}}}
可以查看该连接, es fielddata理解 : https://www.cnblogs.com/chenmz1995/p/10198967.html
8,ES查询报错page+size > 10000
ES默认的结果集窗口大小为10000,很多时候是不够用的,这时候需要放大这个数值,
url: ip:9200/index/_settings 使用PUT方法
linux执行后面的命令: curl -XPUT http://ip:9200/index/_settings -d '{ "index" : { "max_result_window" : 100000000}}'
9,es中单个中文字查询成功,但是中文词组查询不成功;英文单词查询成功,但是包含特殊字符时查询失败,
这个是ES的默认分词器及我们使用的检索语法造成的,
查询单个中文能查询出来,这里采用的是ES标准分词器,将内容分成了一个一个的字,查询单个中文能查询出来,
想要查询到也有办法的,采用matchparse查询(查询分词),例如我如下使用的这样:
es中文查询不成功(注意看下面的回答): https://elasticsearch.cn/question/2337
记录下遇到的ES相关问题,在安装及部署时内容相对简单, 不在多余叙述,
安装参考链接: https://blog.csdn.net/weixin_38040473/article/details/81082968