Solr CloudSolrClient: вызвано: java.lang.ClassCastException: java.lang.String не может быть приведено к java.util.Map - PullRequest
0 голосов
/ 19 июня 2019

Я использую CloudSolrClient с весенней загрузкой Solr 1.5.18.RELEASE, а версия Solr - Solr 4.10.3.

SolrClient solrClient = новый . CloudSolrClient.Builder () withZkHost (zkHosts) .withZkChroot (solrProperties.getSolrZookeeperLocation ()) построить ();.

Когда я использую Solr, который поставляется с CDH 5.16.1 по умолчанию, т.е. Solr 4.10.3 при сохранении документа я получаю следующую ошибку:

org.springframework.data.solr.UncategorizedSolrException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map; nested exception is org.apache.solr.client.solrj.SolrServerException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map
at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:168)
at org.springframework.data.solr.core.SolrTemplate.saveBeans(SolrTemplate.java:223)
at com.solix.emailarchiving.email.solr.search.SolrTemplateWrapper.saveBeans(SolrTemplateWrapper.java:33)
at com.solix.emailarchiving.email.solr.search.EmailSearchRepositoryImpl.saveEmails(EmailSearchRepositoryImpl.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy153.saveEmails(Unknown Source)
at com.solix.emailarchiving.email.EmailSolrServiceImpl.saveEmails(EmailSolrServiceImpl.java:24)
at com.solix.emailarchiving.email.EmailSolrServiceImpl$$FastClassBySpringCGLIB$$40f18538.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
at com.solix.emailarchiving.annotation.ServiceTransactionAspect.beforeMethod(ServiceTransactionAspect.java:46)
at sun.reflect.GeneratedMethodAccessor138.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:643)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:632)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.solix.emailarchiving.email.EmailSolrServiceImpl$$EnhancerBySpringCGLIB$$a84565b1.saveEmails(<generated>)
at com.solix.emailarchiving.hbasetosolrsync.EmailsSync.sendEmailsToSolr(EmailsSync.java:157)
at com.solix.emailarchiving.hbasetosolrsync.EmailsSync.syncMailsFromHbaseToSolr(EmailsSync.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:750)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.solix.emailarchiving.hbasetosolrsync.EmailsSync$$EnhancerBySpringCGLIB$$2714482.syncMailsFromHbaseToSolr(<generated>)
at com.solix.emailarchiving.hbasetosolrsync.HBaseToSolrEmailSyncConsumer.processEmailIdModels(HBaseToSolrEmailSyncConsumer.java:129)
at com.solix.emailarchiving.hbasetosolrsync.HBaseToSolrEmailSyncConsumer.hbaseToSolrSyncListen(HBaseToSolrEmailSyncConsumer.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:181)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:114)
at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48)
at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:248)
at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:80)
at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:51)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:1001)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:981)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:932)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:801)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:689)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.solr.client.solrj.SolrServerException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map
at org.apache.solr.client.solrj.impl.CloudSolrClient.requestWithRetryOnStaleState(CloudSolrClient.java:1246)
at org.apache.solr.client.solrj.impl.CloudSolrClient.request(CloudSolrClient.java:1073)
at org.apache.solr.client.solrj.SolrRequest.process(SolrRequest.java:160)
at org.apache.solr.client.solrj.SolrClient.add(SolrClient.java:106)
at org.springframework.data.solr.core.SolrTemplate.lambda$saveBeans$3(SolrTemplate.java:223)
at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:164)
... 66 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map
at org.apache.solr.common.cloud.DocRouter.getRouteField(DocRouter.java:53)
at org.apache.solr.common.cloud.CompositeIdRouter.sliceHash(CompositeIdRouter.java:46)
at org.apache.solr.common.cloud.HashBasedRouter.getTargetSlice(HashBasedRouter.java:38)
at org.apache.solr.client.solrj.request.UpdateRequest.getRoutes(UpdateRequest.java:262)
at org.apache.solr.client.solrj.impl.CloudSolrClient.directUpdate(CloudSolrClient.java:771)
at org.apache.solr.client.solrj.impl.CloudSolrClient.sendRequest(CloudSolrClient.java:1263)
at org.apache.solr.client.solrj.impl.CloudSolrClient.requestWithRetryOnStaleState(CloudSolrClient.java:1134)
... 71 more

После того, как я начал копать немного глубже и гуглил, я узнал, что проблема связана с полем router в zookeepers clusterstate.json

Информация о моей коллекции в clusterstate.json:

"88_Exchange12_2":{
    "shards":{"shard1":{
        "range":"80000000-7fffffff",
        "state":"active",
        "replicas":{"core_node1":{
            "state":"active",
            "core":"88_Exchange12_2_shard1_replica1",
            "node_name":"SEZ-DESK-047-Linux:8983_solr",
            "base_url":"http://SEZ-DESK-047-Linux:8983/solr",
            "leader":"true"}}}},
    "maxShardsPerNode":"1",
    "router":"compositeId",
    "replicationFactor":"1",
    "autoAddReplicas":"false",
    "routerSpec":{"name":"compositeId"}},

Ожидается, что значение в поле маршрутизатора будет похоже на "router": {"name": "композитный идентификатор"}. как бы то ни было, он хранится неправильно и, следовательно, приводит к приведенному выше ClassCastException.

Однако, когда я использую Apache Solr той же версии 4.10.3 (не CDH Solr 4.10.3), «router» устанавливается с правильным значением.

  "92_S2R1_35":{
    "replicationFactor":"1",
    "shards":{
      "shard1":{
        "range":"80000000-ffffffff",
        "state":"active",
        "replicas":{"core_node2":{
            "core":"92_S2R1_35_shard1_replica1",
            "base_url":"http://172.52.110.44:8983/solr",
            "node_name":"172.52.110.44:8983_solr",
            "state":"down",
            "leader":"true"}}},
      "shard2":{
        "range":"0-7fffffff",
        "state":"active",
        "replicas":{}}},
    "router":{"name":"compositeId"},
    "maxShardsPerNode":"1",
    "autoAddReplicas":"false",
    "autoCreated":"true"}

Q1. Как это решить. Можем ли мы установить маршрутизатор программно из кода Java при создании Collection? Ниже описано, как создать коллекцию:

SolrZkClient solrZkClient=null;
    try {

        String solrZkUrl= solrProperties.getSolrZookeerHost()+solrProperties.getSolrZookeeperLocation();
        solrZkClient = new SolrZkClient(solrZkUrl, 10000);

        Resource resource = new ClassPathResource(solrConfig);
        java.nio.file.Path path = Paths.get(resource.getURI());

        solrZkClient.upConfig(path, solrConfigName);
        LOG.info("Solr Config created with name : \"" + solrConfigName+ "\"");
    }catch (IOException e) {
        LOG.error("Something went Wrong while creating SolrConfig for tenantId: "+ tenantId , e);               
    }finally {
        if (solrZkClient != null) {
            solrZkClient.close();
        }
    }

    int numShards=(solrProperties.getNumShards()<=0)?1:solrProperties.getNumShards();
    int numReplicas=(solrProperties.getNumReplicas()<=0)?1:solrProperties.getNumReplicas();

    SolrClient solrClient=null;
    try {
        Create collection = CollectionAdminRequest.createCollection(collectiomName, solrConfigName, numShards, numReplicas);

        //          collection.setMaxShardsPerNode(-1);
        solrClient = solrConectionUtils.solrClient(tenantId);
        CollectionAdminResponse response = collection.process(solrClient);
        if (!response.isSuccess()) {
            LOG.error(response.getErrorMessages().toString());
            throw new ApplicationException(ExceptionCodeType.SOLR_COLLECTION_CREATION_FAILED);
        } else {
            LOG.info("Collection created with name : \"" + collection.getCollectionName()+ "\"");
        }
    } catch (SolrException | SolrServerException e) {
        LOG.error("Something went wrong while creating collection");                


    }finally {
        if (solrClient != null) {
            solrClient.close();
        }
    }

Q2. В Clusterstate.json CDH мы видим еще одно поле с именем routerSpec, которое имеет правильное значение, но я думаю, что оно не используется. Есть ли способ использовать это поле в качестве маршрутизатора и выполнить работу?

1 Ответ

1 голос
/ 23 июня 2019

Атрибут router действительно был изменен со строки на карту в Solr 4.5.0, но в клиент solrj был добавлен обратно-совместимый код чтения, чтобы избежать этой ситуации.Я не знаю, почему вы видите эту ошибку в 4.10.3, метод getRouterField в 4.10.3 имеет значение https://github.com/apache/lucene-solr/blob/d52936c3c3f92aa3d04eaeeab3472a6e259be7b6/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java#L52, которое проверяет, является ли объект маршрутизатора строкой, и возвращает ноль.Если ничего другого, возможно, вы можете вручную изменить объект состояния кластера в zookeeper, чтобы изменить маршрутизатор на карту json.

...