solr分片shard对应的range值变为null异常问题处理
转贴请声明原文: http://blog.csdn.net/duck_genuine/article/details/52984082
选 用的solr是solr4.7版本!
solr分片突然发现多个collections上某些shard对应的range值变为null,而且还多一个parent:null
由于solr文档的分发到不同shard是通过主键hash后,分到不同的范围值取对应的shard,所以上面这个问题会
导致索引不了,且搜索到某个分片取对应文档也有问题,最关键在solrcloud图上并没有显示有任务的异常问题,只有在logging上不断抛出下面的异常!
org.apache.solr.common.SolrException: No active slice servicing hash code b8951b39 in DocCollection(audio_tags)={
"shards":{
"shard2":{
"range":"0-7fffffff",
"state":"active",
"replicas":{
"core_node4":{
"state":"active",
"base_url":"http://192.168.1.14:11111/solr",
"core":"audio_tags_shard2_replica2",
"node_name":"192.168.1.14:11111_solr"},
"core_node5":{
"state":"active",
"base_url":"http://192.168.1.13:11112/solr",
"core":"audio_tags_shard2_replica1",
"node_name":"192.168.1.13:11112_solr",
"leader":"true"}}},
"shard1":{
"range":null,
"state":"active",
"parent":null,
"replicas":{
"core_node6":{
"state":"active",
"base_url":"http://192.168.1.11:11111/solr",
"core":"audio_tags_shard1_replica4",
"node_name":"192.168.1.11:11111_solr",
"leader":"true"},
"core_node7":{
"state":"active",
"base_url":"http://192.168.1.3:11111/solr",
"core":"audio_tags_shard1_replica4",
"node_name":"192.168.1.3:11111_solr"}}}},
"maxShardsPerNode":"1",
"router":{"name":"compositeId"},
"replicationFactor":"3"}
at org.apache.solr.common.cloud.HashBasedRouter.hashToSlice(HashBasedRouter.java:60)
at org.apache.solr.common.cloud.HashBasedRouter.getTargetSlice(HashBasedRouter.java:34)
at org.apache.solr.update.processor.DistributedUpdateProcessor.setupRequest(DistributedUpdateProcessor.java:218)
at org.apache.solr.update.processor.DistributedUpdateProcessor.processAdd(DistributedUpdateProcessor.java:550)
at org.apache.solr.update.processor.LogUpdateProcessor.processAdd(LogUpdateProcessorFactory.java:100)
at org.apache.solr.handler.loader.JavabinLoader$1.update(JavabinLoader.java:96)
at org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec$1.readOuterMostDocIterator(JavaBinUpdateRequestCodec.java:166)
at org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec$1.readIterator(JavaBinUpdateRequestCodec.java:136)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:225)
at org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec$1.readNamedList(JavaBinUpdateRequestCodec.java:121)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:190)
at org.apache.solr.common.util.JavaBinCodec.unmarshal(JavaBinCodec.java:116)
at org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec.unmarshal(JavaBinUpdateRequestCodec.java:173)
at org.apache.solr.handler.loader.JavabinLoader.parseAndLoadDocs(JavabinLoader.java:106)
at org.apache.solr.handler.loader.JavabinLoader.load(JavabinLoader.java:58)
at org.apache.solr.handler.UpdateRequestHandler$1.load(UpdateRequestHandler.java:92)
at org.apache.solr.handler.ContentStreamHandlerBase.handleRequestBody(ContentStreamHandlerBase.java:74)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:1916)
at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:768)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:415)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:205)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1419)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:368)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
at org.eclipse.jetty.server.BlockingHttpConnection.handleRequest(BlockingHttpConnection.java:53)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:953)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1014)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:861)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.BlockingHttpConnection.handle(BlockingHttpConnection.java:72)
at org.eclipse.jetty.server.bio.SocketConnector$ConnectorEndPoint.run(SocketConnector.java:264)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:745)
这应该是个bug,不过要重现应该不容易,所以只能找解决方案。马上想到的是修改 /clusterstate.json
为了安全起见,不直接去zk上修改该结点内容。而是写了个小程序去修改
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.CompositeIdRouter;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.DocRouter.Range;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
public class UpdateClusterstat {
/**取分片对应hash范围值
* @param totalShardNum 总共有多少分片
* @param shardNum 第几个分片 ,1开始
* @return
*/
public static String getRange(int totalShardNum, int shardNum) {
DocRouter hp = DocRouter.DEFAULT;
List ranges;
ranges = hp.partitionRange(totalShardNum, hp.fullRange());
int index = shardNum - 1;
Range r = ranges.get(index);
return r.toString();
}
public static void main(String[] args) {
System.out.println("###");
try {
// testSliceStateUpdate("audio_comment", "shard2",
// "d5550000-2aa9ffff");
// testSliceStateUpdate("audio_tags", "shard1",
// "80000000-ffffffff");
// testSliceStateUpdate("audio", "shard2", "0-7fffffff");
// testSliceStateUpdate("DeviceIDFA", "shard1", "80000000-7fffffff");
// testSliceStateUpdate("analzyerword", "shard1", "80000000-7fffffff");
String range = getRange(2,2);
testSliceStateUpdate("DeviceIDFA", "shard1", range);
System.out.println(range);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testSliceStateUpdate(String collection, String shard,
String range) throws Exception {
String zkHost = "zookeeper:2181/new_on_lizhi_search";
int zkClientTimeout = 2000;
int zkConnectTimeout = 2000;
CloudSolrServer solrServer = CloudSolrServerFactory.getInstance(zkHost,
zkClientTimeout, zkConnectTimeout, collection);
ClusterState cluster = solrServer.getZkStateReader().getClusterState();
Map slicesMap = cluster.getSlicesMap(collection);
Slice slice = slicesMap.get(shard);
Map prop = slice.getProperties();
prop.put("range", range);
prop.remove("parent");
Slice newSlice = new Slice(slice.getName(), slice.getReplicasMap(),
prop);
slicesMap.put(newSlice.getName(), newSlice);
Map props = new HashMap(1);
props.put(DocCollection.DOC_ROUTER,
ZkNodeProps.makeMap("name", CompositeIdRouter.NAME));
DocCollection coll = new DocCollection(collection, slicesMap, props,
DocRouter.DEFAULT);
ClusterState newState = cluster.copyWith(Collections.singletonMap(
coll.getName(), coll));
solrServer
.getZkStateReader()
.getZkClient()
.setData(ZkStateReader.CLUSTER_STATE,
ZkStateReader.toJSON(newState), true);
}
}