Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql EC2集群中Infinispan支持的Hibernate搜索中出现重复记录错误_Mysql_Amazon Ec2_Hibernate Search_Infinispan_Jgroups - Fatal编程技术网

Mysql EC2集群中Infinispan支持的Hibernate搜索中出现重复记录错误

Mysql EC2集群中Infinispan支持的Hibernate搜索中出现重复记录错误,mysql,amazon-ec2,hibernate-search,infinispan,jgroups,Mysql,Amazon Ec2,Hibernate Search,Infinispan,Jgroups,我们有一个在EC2集群中工作的应用程序(目前有2个节点用于测试)。为了搜索域模型,我们使用Hibernate搜索,由于应用程序运行在集群上,所以我们使用Infinispan作为Lucene目录。为了避免重启,我们在MySQL上使用JDBC缓存存储,两个节点访问相同的MySQL表。为了说明如何添加和删除节点,我们使用Hibernate搜索工作者配置的“jgroups”后端 我们的问题是,当我们尝试重建整个实体索引时,会收到重复记录异常。我们会收到类似stacktraces的错误,如下所示: ERR

我们有一个在EC2集群中工作的应用程序(目前有2个节点用于测试)。为了搜索域模型,我们使用Hibernate搜索,由于应用程序运行在集群上,所以我们使用Infinispan作为Lucene目录。为了避免重启,我们在MySQL上使用JDBC缓存存储,两个节点访问相同的MySQL表。为了说明如何添加和删除节点,我们使用Hibernate搜索工作者配置的“jgroups”后端

我们的问题是,当我们尝试重建整个实体索引时,会收到重复记录异常。我们会收到类似stacktraces的错误,如下所示:

ERROR [AsyncStoreProcessor-LuceneIndexesData-0] [2016-06-21 17:01:59] org.infinispan.persistence.jdbc.stringbased.JdbcStringBasedStore - ISPN008024: Error while storing string key to database; key: '_d.fdt|0|1048576|com.model.SomeModel'
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '_d.fdt|0|1048576|com.model.SomeModel' for key 'PRIMARY'
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
 at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
 at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
 at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1399)
 at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:857)
 at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
 at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
 at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
 at com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy.executeUpdate(PreparedStatementJavassistProxy.java)
 at org.infinispan.persistence.jdbc.stringbased.JdbcStringBasedStore.write(JdbcStringBasedStore.java:174)
 at org.infinispan.persistence.async.AsyncCacheWriter.applyModificationsSync(AsyncCacheWriter.java:158)
 at org.infinispan.persistence.async.AsyncCacheWriter$AsyncStoreProcessor.retryWork(AsyncCacheWriter.java:330)
 at org.infinispan.persistence.async.AsyncCacheWriter$AsyncStoreProcessor.run(AsyncCacheWriter.java:312)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)
当我们检查数据库时,有一个具有此ID的条目。当我们使用单个节点进行尝试时,没有错误。因此,我们猜测两个节点都试图将缓存项写入DB什么可能导致此问题?AFAIK jgroups后端应该阻止它。

我们使用hibernate 4.3.9.Final、hibernate search 5.2.1.Final、infinispan 7.2.5.Final和jgroups 3.6.8.Final。Infinispan配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:7.2"
            xmlns:jdbc="urn:infinispan:config:store:jdbc:7.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
            urn:infinispan:config:7.2 http://www.infinispan.org/schemas/infinispan-config-7.2.xsd
            urn:infinispan:config:store:jdbc:7.2 http://www.infinispan.org/schemas/infinispan-cachestore-jdbc-config-7.2.xsd">

    <jgroups>
        <stack-file name="tcp" path="default-configs/default-jgroups-tcp.xml"/>
        <stack-file name="ec2" path="search/infinispan-jgroups-ec2.xml"/>
    </jgroups>

    <cache-container name="HibernateSearch" default-cache="default" statistics="false" shutdown-hook="DONT_REGISTER">

        <transport stack="${infinispan.transport:tcp}"/>

        <!-- Duplicate domains are allowed so that multiple deployments with default configuration
            of Hibernate Search applications work - if possible it would be better to use JNDI to share
            the CacheManager across applications -->
        <jmx duplicate-domains="true"/>

        <!-- *************************************** -->
        <!--  Cache to store Lucene's file metadata  -->
        <!-- *************************************** -->
        <replicated-cache name="LuceneIndexesMetadata" mode="SYNC" remote-timeout="25000">
            <transaction mode="NONE"/>
            <state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
            <indexing index="NONE"/>
            <locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
            <eviction max-entries="-1" strategy="NONE"/>
            <expiration max-idle="-1"/>
            <persistence passivation="false">
                <jdbc:string-keyed-jdbc-store preload="true" fetch-state="true" read-only="false" purge="false">
                    <jdbc:data-source jndi-url="java:comp/env/jdbc/..."/>
                    <jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ISPN_STRING_TABLE">
                        <jdbc:id-column name="ID" type="VARCHAR(255)"/>
                        <jdbc:data-column name="METADATA" type="BLOB"/>
                        <jdbc:timestamp-column name="TIMESTAMP" type="BIGINT"/>
                    </jdbc:string-keyed-table>
                    <property name="key2StringMapper">org.infinispan.lucene.LuceneKey2StringMapper</property>
                    <write-behind/>
                </jdbc:string-keyed-jdbc-store>
            </persistence>
        </replicated-cache>

        <!-- **************************** -->
        <!--  Cache to store Lucene data  -->
        <!-- **************************** -->
        <distributed-cache name="LuceneIndexesData" mode="SYNC" remote-timeout="25000">
            <transaction mode="NONE"/>
            <state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
            <indexing index="NONE"/>
            <locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
            <eviction max-entries="-1" strategy="NONE"/>
            <expiration max-idle="-1"/>
            <persistence passivation="false">
                <jdbc:string-keyed-jdbc-store preload="true" fetch-state="true" read-only="false" purge="false">
                    <jdbc:data-source jndi-url="java:comp/env/jdbc/..."/>
                    <jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ISPN_STRING_TABLE">
                        <jdbc:id-column name="ID" type="VARCHAR(255)"/>
                        <jdbc:data-column name="DATA" type="MEDIUMBLOB"/>
                        <jdbc:timestamp-column name="TIMESTAMP" type="BIGINT"/>
                    </jdbc:string-keyed-table>
                    <property name="key2StringMapper">org.infinispan.lucene.LuceneKey2StringMapper</property>
                    <write-behind/>
                </jdbc:string-keyed-jdbc-store>
            </persistence>
        </distributed-cache>

        <!-- ***************************** -->
        <!--  Cache to store Lucene locks  -->
        <!-- ***************************** -->
        <replicated-cache name="LuceneIndexesLocking" mode="SYNC" remote-timeout="25000">
            <transaction mode="NONE"/>
            <state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
            <indexing index="NONE"/>
            <locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
            <eviction max-entries="-1" strategy="NONE"/>
            <expiration max-idle="-1"/>
        </replicated-cache>
    </cache-container>

</infinispan>

org.infinispan.lucene.LuceneKey2StringMapper
org.infinispan.lucene.LuceneKey2StringMapper
各自的Hibernate配置如下(通过Spring完成):


您在JGroups后端的用途上是正确的,并且您的Hibernate配置看起来是正确的

问题在于Infinispan中CacheStore组件的配置,这些组件有一个“shared”属性,其默认值为false


您对JGroups后端的理解是正确的,您的Hibernate配置看起来是正确的

问题在于Infinispan中CacheStore组件的配置,这些组件有一个“shared”属性,其默认值为false


同时使用Infinispan目录(允许所有节点访问索引)和JGroups后端(第二次复制)似乎有点奇怪。这是Hibernate Search建议的。这是为了确保只有一个节点尝试写入索引。否则,当节点尝试写入同一索引时,它们会尝试获取锁并互相等待。此外,不使用JGroups后端也不会更改任何内容,当请求完整索引重建时,仍然存在重复记录异常。@Flavius:索引的存储复制与后端不同;狂暴K81是正确的。在Infinispan中作为“Infinispan查询”运行时,后端方面是自动的,但在运行Hibernate应用程序时,必须将其配置为正交组件。这有点棘手,因此我报告了一个需要改进的问题:使用两个Infinispan目录(允许所有节点访问索引)似乎有点奇怪和JGroups后端,后者进行第二次复制。这是Hibernate Search的建议。这是为了确保只有一个节点尝试写入索引。否则,当节点尝试写入同一索引时,它们会尝试获取锁并互相等待。此外,不使用JGroups后端也不会更改任何内容,当请求完整索引重建时,仍然存在重复记录异常。@Flavius:索引的存储复制与后端不同;狂暴K81是正确的。当以“Infinispan查询”的形式在Infinispan中运行时,后端方面是自动的,但当运行Hibernate应用程序时,必须将其配置为正交组件。这有点棘手,因此我报告了一个需要改进的问题:添加shared=“true”修复了该问题。非常感谢您提供的解决方案。添加shared=“true”修复了此问题。非常感谢您的解决方案。
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceUnitName" value="..."/>
    <property name="packagesToScan" value="com...."/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false"/>
            <property name="showSql" value="false"/>
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="database" value="MYSQL"/>
        </bean>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.default_batch_fetch_size" value="50"/>
            <entry key="hibernate.multiTenancy" value="SCHEMA"/>
            <entry key="hibernate.multi_tenant_connection_provider" value-ref="connectionProvider"/>
            <entry key="hibernate.tenant_identifier_resolver" value-ref="tenantIdentifierResolver"/>
            <entry key="hibernate.cache.use_second_level_cache" value="true"/>
            <entry key="hibernate.cache.region.factory_class" value="com.hazelcast.hibernate.HazelcastCacheRegionFactory"/>
            <entry key="hibernate.cache.hazelcast.use_native_client" value="true"/>
            <entry key="hibernate.cache.hazelcast.native_client_address" value="127.0.0.1"/>
            <entry key="hibernate.cache.hazelcast.native_client_group" value="dev"/>
            <entry key="hibernate.cache.hazelcast.native_client_password" value="dev-pass"/>
            <entry key="hibernate.connection.characterEncoding" value="UTF-8"/>
            <entry key="hibernate.connection.useUnicode" value="true"/>
            <entry key="hibernate.search.default.directory_provider" value="infinispan"/>
            <entry key="hibernate.search.default.locking_cachename" value="LuceneIndexesLocking"/>
            <entry key="hibernate.search.default.data_cachename" value="LuceneIndexesData"/>
            <entry key="hibernate.search.default.metadata_cachename" value="LuceneIndexesMetadata"/>
            <entry key="hibernate.search.default.chunk_size" value="1048576"/>
            <entry key="hibernate.search.infinispan.configuration_resourcename" value="search/hibernatesearch-infinispan.xml"/>
            <entry key="hibernate.search.default.worker.backend" value="jgroups"/>
            <entry key="hibernate.search.services.jgroups.configurationFile" value="search/infinispan-jgroups-ec2.xml"/>
        </map>
    </property>
</bean>
<jdbc:string-keyed-jdbc-store
    preload="true"
    fetch-state="true"
    read-only="false"
    purge="false"
    shared="true" <!-- FIX