首页 技术 正文
技术 2022年11月21日
0 收藏 851 点赞 3,637 浏览 1968 个字

elasticsearch可以使用preference参数来指定分片查询的优先级,使用时就是在请求url上加上preference参数,如:http://ip:host/index/_search?preference=_primary 

java的调用接口翻译为:client.prepareSearch(“index”).setPreference(“_primary”)。 

默认情况下es有5种查询优先级: 

_primary: 指查询只在主分片中查询 

_primary_first: 指查询会先在主分片中查询,如果主分片找不到(挂了),就会在副本中查询。 

_local: 指查询操作会优先在本地节点有的分片中查询,没有的话再在其它节点查询。 

_only_node:指在指定id的节点里面进行查询,如果该节点只有要查询索引的部分分片,就只在这部分分片中查找,所以查询结果可能不完整。如_only_node:123在节点id为123的节点中查询。 

Custom (string) value:用户自定义值,指在参数cluster.routing.allocation.awareness.attributes指定的值,如这个值设置为了zone,那么preference=zone的话就在awareness.attributes=zone*这样的节点搜索,如zone1、zone2。关于这个值作用可以参考下面文章。 

虽然es有提供这5种优先级,但感觉还是不能满足我的需求,我是想能指定在某一个或多个节点中查询,比如node1和node2里面的分片能组成一个完整的索引,那我可以只在node1和node2中搜索就行了。看来只能改源码解决,改源码也非常简单。 

首先找到org.elasticsearch.cluster.routing.operation.plain.PlainOperationRouting这个类,es搜索时获取分片信息是通过这个类的。它的preferenceActiveShardIterator()方法就是根据条件来找出响应的分片。看源码可知其主要是根据preference这个参数来决定取出的分片的。如果没有指定该参数,就随机抽取分片进行搜索。如果参数以_shards开头,则表示只查询指定的分片。注意,这个功能官网的文档中没有写到。 

然后下面就是判断我上面说的5种优先级情况。我们现在要加个多节点分片查询的功能,仿照单个节点分片查询(指_only_node)就行了,在

  1. if (preference.startsWith("_only_node:")) {
  2. return indexShard.onlyNodeActiveShardsIt(preference.substring("_only_node:".length()));
  3. }

后面加上

  1. if (preference.startsWith("_only_nodes:"))  {
  2. return indexShard.onlyNodesActiveShardsIt(preference.substring("_only_nodes:".length()));
  3. }

onlyNodesActiveShardsIt这个方法在org.elasticsearch.cluster.routing.IndexShardRoutingTable中是没有的,要自己写。加上

  1. /**
  2. * Prefers execution on the provided nodes if applicable.
  3. */
  4. public ShardIterator onlyNodesActiveShardsIt(String nodeIds) {
  5. String[] ids = nodeIds.split(",");
  6. ArrayList<ShardRouting> ordered = new ArrayList<ShardRouting>(shards.size());
  7. // fill it in a randomized fashion
  8. ; i < shards.size(); i++) {
  9. ShardRouting shardRouting = shards.get(i);
  10. for(String nodeId:ids){
  11. if (nodeId.equals(shardRouting.currentNodeId())) {
  12. ordered.add(shardRouting);
  13. }
  14. }
  15. }
  16. return new PlainShardIterator(shardId, ordered);
  17. }

重新编译源码就行了。查询时加上preference=_only_nodes:node1id,node2id 就可以指定在node1和node2中搜索

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,918
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,444
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,255
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,069
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,701
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,741