sorlCloud是分片的,那么如何决定一个document应该到哪一个分片呢?负责解决这个问题的东西就是DocRouter,翻译过来是doc路由器。在创建一个集合(collection)的时候,我们必须要给集合置顶一个docRouter,solr中默认是使用基于hash策略的docRouter(CompositeIdRouter),当然还有其他的Router,这个博客就要说这些。
我们先看一下DocRouter的源码,里面有很多的抽象方法,
public abstract Slice getTargetSlice(String id, SolrInputDocument sdoc, SolrParams params, DocCollection collection);
根据一个solrInputDocument判断应该属于一个collection的哪一个shard(slice),用于添加document的时候,
public abstract Collection<Slice> getSearchSlicesSingle(String shardKey, SolrParams params, DocCollection collection);
这个方法是在查询的时候应该查那些shard,根据shardKey来判断。
public abstract boolean isTargetSlice(String id, SolrInputDocument sdoc, SolrParams params, String shardId, DocCollection collection);
这个是判断一个shardId是不是一个solrInputDocument的正确的slice。
DocRouter的作用就是体现在这些方法上,对于查询和增加document的时候分别调用不同的方法来决定要操作的那些shard。
我们看一下他的实现类,先看一下基于hash计算的:HashBasedRouter ,我们看一下这个类对上面的方法实现:
1、getTargetSlice:
@Override public Slice getTargetSlice(String id, SolrInputDocument sdoc, SolrParams params, DocCollection collection) { if (id == null) id = getId(sdoc, params);//获得这个doc的id int hash = sliceHash(id, sdoc, params,collection);//根据id计算hash值,嗲用的是Hash.murmurhash3_x86_32(id, 0, id.length(), 0);方法,mermerHash。 return hashToSlice(hash, collection);//根据hash值得到一个slice,看下面的方法 } protected Slice hashToSlice(int hash, DocCollection collection) { for (Slice slice : collection.getActiveSlices()) {//当前的集合所有存活的shard Range range = slice.getRange();//一个shard有一个范围, if (range != null && range.includes(hash)) return slice;//如果hash值在某个范围。 } throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No active slice servicing hash code " + Integer.toHexString(hash) + " in " + collection);//如果没有包含hash值的shard,则报错。从这个地方可以看出,基于hash值的分片的方式应该是不能动态的扩容的 也就是不能在建立好集群之后添加shard,因为各个Shard的范围应该基于创建的shard的个数被固定下来,所以不能动态的添加shard。 }
从上面的方法中可以明白很多问题,比如基于hash值的路由策略的shard在建立的时候就会固定shard的范围,这样也就不能再动态添加shard了。
2、getSearchSliceSingle
@Override public Collection<Slice> getSearchSlicesSingle(String shardKey, SolrParams params, DocCollection collection) { if (shardKey == null) {//如果在查询的时候没有指定shardKey,则查询所有的存活的shard,也就是如果某个shard已经死掉了,默认就是不会查询他。 // search across whole collection // TODO: this may need modification in the future when shard splitting could cause an overlap return collection.getActiveSlices(); } // use the shardKey as an id for plain hashing Slice slice = getTargetSlice(shardKey, null, params, collection);//如果指定了,则调用上面的getTargetSlice方法 return slice == null ? Collections.<Slice>emptyList() : Collections.singletonList(slice); }
3、isTargetSlice方法很简单,这里就不展示了。
HashBasedRouter 仍然是抽象类,因为他没有指定range的实现方式以及和分片的个数的关系,他的实现类时CompositeIdRouter,我们看一下的他的partitionRange方法,在这个方法中一个集合根据分片的个数决定了每个分片的范围(hash值的范围),这个方法我还没有看懂,有兴趣的同学可以帮忙看看。
上面我们看完了基于hash值来分片的策略,他的缺点是不能再运行时添加shard,对于那些没有明显的规则的集合是合适的。
DocRouter的另一个实现:ImplicitDocRouter
这个是必须指定路由域路由策略,我们在创建集合的时候必须制定这个集合的路由的域是什么,然后根据document的这个域的值来判断这个document要添加到哪个shard中。我们看一下他的方法
@Override public Slice getTargetSlice(String id, SolrInputDocument sdoc, SolrParams params, DocCollection collection) { String shard = null; if (sdoc != null) { String f = getRouteField(collection);//得到要使用作为路由的域,这个在创建集合的时候就要指定 if(f !=null) { Object o = sdoc.getFieldValue(f);//得到这个document的这个域的值 if (o != null) shard = o.toString();//根据与的值对应shard的id else throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No value for field "+f +" in " + sdoc); } if(shard == null) {//如果上面没有完成对shard的实现,则使用_ROUTE_这个域 Object o = sdoc.getFieldValue(_ROUTE_);//使用_ROUTE_这个域 if (o == null) o = sdoc.getFieldValue("_shard_");//deprecated . for backcompat remove later,如果没有_ROUTE_这个域,则使用_shard_这个域 if (o != null) { shard = o.toString(); } } } if (shard == null) {//如果上面从sdoc中没有找到,则从参数中 shard = params.get(_ROUTE_); if(shard == null) shard =params.get("_shard_"); //deperecated for back compat } if (shard != null) { Slice slice = collection.getSlice(shard);//直接根据名字找slice if (slice == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No shard called =" + shard + " in " + collection); } return slice; } return null; // no shard specified... use default. }
上面的代码可以看出,是先根据指定的域,如果没有指定,则使用_ROUTE_做路由。
getSearchSlicesSingle
@Override public Collection<Slice> getSearchSlicesSingle(String shardKey, SolrParams params, DocCollection collection) { if (shardKey == null) {//如果在查询的时候没有指定shardkey,则查询所有的存活的shard return collection.getActiveSlices(); } // assume the shardKey is just a slice name Slice slice = collection.getSlice(shardKey);//如果指定了,则返回名字对应的shard if (slice == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "implicit router can't find shard " + shardKey + " in collection " + collection.getName()); } return Collections.singleton(slice); }
这个路由策略的好处是可以在运行时动态的添加shard,对于document有明显的筛选条件的场合应该优先使用这个。
那么应该怎么创建这两种不同路由策略的集合呢?
如果在创建集合的时候没有指定router.name,则默认就是CompositeIdRouter,比如这个语句:admin/collections?action=CREATE&name=collectionName&numShards=4&replicationFactor=2&collection.configName=collectionName&maxShardsPerNode=2可以在创建玩了之后查看一下zk上的clusterstate.json,上面就有"router":{"name":"compositeId"}(solr4.7.2),
如果指定了router.name=implicit,则就是后者,比如这个语句:admin/collections?action=CREATE&name=hello&replicationFactor=2&collection.configName=configName&maxShardsPerNode=10&router.name=implicit&shards=name1,name2,name3,name4&router.field=nameField,就会是后者。
相关推荐
策略路由:一般情况下,数据包的转发是根据目的地址查路由表确定转发路径,如下图,RTA和RTB访问RTF的流量都会被RTC转发给RTD。如果用户要求RTB访问RTF的流量经RTE转发,那么,可以通过在RTC上部署策略路由来实现。...
- 基于策略的路由:根据源IP、目的IP、端口等信息选择不同的转发路径。 - QoS(服务质量)控制:根据业务需求,优先处理某些流量。 - 流量工程:优化网络资源分配,确保关键业务的带宽和延迟。 4. `vrpcfg.cfg`...
在实际应用中,路由策略可以应用于各种场景,例如,在双上行的组网结构中,使用路由策略可以实现对路由信息进行过滤和修改路由的属性,例如,允许来自某个路由器的路由,拒绝来自某个路由器的路由,或者将来自某个...
*管理员需要在 RIP 路由协议中应用路由策略,包括配置路由策略和路由优先级等。 *管理员需要监控网络状态,实时调整路由策略和路由优先级等。 注意事项 ------ 使用 RIP 路由策略配置指导需要注意以下事项: *...
路由策略是华为路由器中的一种机制,旨在实现路由过滤和路由属性设置等功能。通过改变路由属性,路由策略可以改变网络流量的路径,使网络流量更合理化。路由策略在发布、接收和引入路由信息时,根据实际组网需求实施...
Linux 策略路由的分析及其应用 Linux 策略路由是指基于策略的路由选择机制,它允许管理员根据 IP 包的源地址、目的地址或其他信息来选择路由。Linux 作为一个开源的操作系统,具有强大的功能,包括策略路由功能。 ...
3. 过滤和控制引入的路由:在不同路由协议间引入路由时,路由策略可以用来选择性引入并调整引入路由的属性,以符合当前协议的需求。 4. 设置路由属性:路由策略还可以用于修改路由的属性,满足网络流量规划的需求。 ...
- 策略路由:依据用户定义的策略决定报文的转发路径,可以不遵循常规的路由表转发,转发失败后才会查找路由表。策略路由在转发平面操作,适用于安全和负载分担等目的。 路由策略的实现包括两个关键步骤: 1. 定义...
2. 不对称路由:策略路由可能会引起“不对称路由”形式的流量。 策略路由的配置: 1. 启用策略路由: * 配置 route-map * 使用 match 语句定义感兴趣的流量 * 使用 set 命令设置数据包行为 * 进入想应用策略...
HM-042 路由策略与引入ISSUE 5.1是关于路由策略和引入的课程,旨在帮助学习者掌握IP路由策略的原理、配置路由策略和引入、路由策略的监控和维护等知识点。该课程涵盖了路由策略的作用、路由策略的五种过滤器、路由...
在IT行业中,路由策略是网络通信的核心组成部分,它决定了数据包如何在互联网上高效、可靠地传输。本文将深入探讨路由策略的改进及其与传统路由策略的对比,特别是在灵活时隙结构下的应用。 首先,路由策略是网络...
策略路由可以分为接口策略路由和本地策略路由: - 接口策略路由:配置在接口视图下,只对通过该接口转发的报文生效,不适用于路由器本地产生的报文。 - 本地策略路由:配置在系统视图下,只对路由器本地产生的报文...
路由策略简介,基本原理,配置路由策略-配置地址前缀列表、配置AS属性过滤器\配置团体属性过滤器
华为路由器的路由策略和策略路由是网络管理员在配置和管理网络路由时的重要工具,它们用于精细化控制路由信息的处理和网络流量的引导。路由策略主要包括路由的过滤和属性设置,通过对路由信息的筛选和修改,可以实现...
例如,在CISCO路由交换机中,我们可以使用以下命令来配置策略路由: ``` route-map ISP2 permit 10 match ip address 162.153.123.113 255.255.255.252 set ip next-hop 211.211.44.254 ``` 这条命令将配置一个名...
路由策略是华为路由器中的一个重要功能,主要实现了路由过滤和路由属性设置等功能。它通过改变路由属性(包括可达性)来改变网络流量所经过的路径。路由协议在发布、接收和引入路由信息时,根据实际组网需求实施一些...
地址前缀列表是路由策略中的一个重要组件,它根据路由的目的地址进行匹配。在需要根据目的地址控制路由发布和接收的场景下,配置地址前缀列表是必要的。地址前缀列表类似于访问控制列表(ACL),但更加灵活,可以...
描述基础路由策略,路由策略(选路工具) 根据实际情况干预路由器的路由选择: ACL 访问控制列表 修改路由协议的优先级 修改路由协议的COST和METRIC 偏移列表(一般在CISCO设备上配置) 前缀列表 路由映射(route-...
【路由策略与策略路由】是网络管理中的重要概念,它们主要应用于IP路由的管理和控制,以优化网络流量和提高网络性能。路由策略主要在路由发现阶段发挥作用,通过筛选和修改路由信息来影响路由表的内容,而策略路由则...