双机部署Infinispan时索引元数据加载失败求助
先来看你遇到的核心异常:
Caused by: java.io.FileNotFoundException: Error loading metadata for index file: segments_2j|M|Course
at org.infinispan.lucene.impl.DirectoryImplementor.openInput(DirectoryImplementor.java:134)
at org.infinispan.lucene.impl.DirectoryLuceneV4.openInput(DirectoryLuceneV4.java:101)
at org.apache.lucene.store.Directory.openChecksumInput(Directory.java:113)
at org.apache.lucene.index.SegmentInfos.read(SegmentInfos.java:341)
...(省略后续栈信息)
这个异常本质是集群中的某个节点找不到索引的segments元数据文件,大概率是集群同步问题或者持久化配置不一致导致的,我帮你梳理几个核心排查点和解决办法:
1. 修复JGroups集群通信的硬编码问题
你的JGroups配置文件my-jgroup.xml里的bind_addr直接写死成了192.168.1.48,如果两台机器都用这个配置,第二台机器无法绑定到自己的真实IP,集群根本无法形成,索引数据自然只能存在于第一台机器,第二台启动时就会找不到对应的segments文件。
解决办法:
- 把
bind_addr改成动态变量,允许每台机器绑定自身IP,或者为不同机器配置对应IP:
启动每台机器时,通过JVM参数指定各自的IP:<TCP bind_addr="${jgroups.tcp.address:0.0.0.0}" bind_port="${jgroups.tcp.port:7800}" enable_diagnostics="false" ... />-Djgroups.tcp.address=192.168.1.XX(替换XX为机器实际IP) - 同时把
MPING节点的bind_addr也做同样修改,确保集群节点能互相发现对方。
2. 统一JDBC缓存存储的数据库地址
你的Infinispan配置中,LuceneIndexesMetadata和LuceneIndexesData的JDBC Store都配置了jdbc:mysql://localhost:3306/hsearch——如果两台机器各自连接本地的MySQL,索引数据会分散在两个独立的数据库里,跨节点访问时自然找不到对方机器DB里的索引文件。
解决办法:
- 将JDBC连接URL改成你要统一持久化的那台机器的数据库IP(比如和你
persistence.xml里的192.168.1.99一致),确保两台机器都连接同一个数据库:<jdbc:connection-pool connection-url="jdbc:mysql://192.168.1.99:3306/hsearch" driver="com.mysql.jdbc.Driver" username="my-username" password="my-password"></jdbc:connection-pool> - 启动前确认目标数据库中已经创建了
ISPN_STRING_TABLE表,并且两台机器都有读写该表的权限。
3. 修复Hibernate Search索引管理器的重复配置
你的persistence.xml里重复设置了indexmanager属性:
<property name="hibernate.search.default.indexmanager" value="org.infinispan.query.indexmanager.InfinispanIndexManager"/> <property name="hibernate.search.default.indexmanager" value="near-real-time"/>
后一个配置会直接覆盖前一个,导致没有使用Infinispan的分布式索引管理器,这会彻底打乱集群的索引同步逻辑,引发文件找不到的问题。
解决办法:
- 删除重复的
near-real-time配置,只保留Infinispan的索引管理器配置:<property name="hibernate.search.default.indexmanager" value="org.infinispan.query.indexmanager.InfinispanIndexManager"/>
4. 验证集群状态转移与缓存加载逻辑
检查你的缓存配置中的两个关键属性:
await-initial-transfer="true":确保节点启动时会等待集群状态同步完成,但前提是集群能正常形成;preload="true":缓存启动时会从持久化存储加载已有数据,确保节点能获取到之前生成的索引元数据。
验证步骤:
- 先启动第一台机器,操作生成一些索引数据,确认数据库的
ISPN_STRING_TABLE中已经出现对应的记录; - 启动第二台机器,查看日志中是否有状态转移成功的记录,确认数据从数据库或集群节点加载完成。
5. 排除Lucene版本冲突
你使用的Infinispan 7.2.0.Final和Lucene 4.10.4是官方兼容的版本组合,但要检查项目依赖中是否混入了其他版本的Lucene jar包——版本冲突会导致索引文件解析异常,也可能表现为找不到文件的错误。
内容的提问来源于stack exchange,提问作者Nadeem Pasha

