Solr从3.6.2升级至7.3后多EmbeddedSolrServer索引锁失效,求锁类型选型
解决Solr 3.6.2升级到7.3后索引锁失效的问题
嘿,针对你升级Solr后遇到的索引锁失效问题,我结合版本差异和你的部署场景给你几个排查和解决方向:
1. 明确Solr版本间锁机制的核心变化
Solr 3.6.2默认使用的是SimpleFSLockFactory(基于文件的锁,跨进程/同一JVM内的不同实例都能生效),但Solr 7.x对锁机制做了优化,默认锁工厂根据部署模式有所不同:
- 对于EmbeddedSolrServer,如果是单个CoreContainer实例,默认可能用
SingleInstanceLockFactory(仅在同一CoreContainer内的线程间生效) - 但你的场景是同一JVM下两个应用各有独立的CoreContainer实例,共享同一个SolrHome,这种情况下默认锁工厂就无法跨CoreContainer实例生效,导致锁失效。
2. 显式配置全局有效的锁工厂
你需要为两个应用的CoreContainer都配置支持跨CoreContainer实例的锁工厂,推荐使用NativeFSLockFactory(基于操作系统原生文件锁,比SimpleFSLockFactory更可靠)或者依然用SimpleFSLockFactory。
配置方式:
在初始化CoreContainer的时候,显式设置锁工厂:
// 初始化CoreContainer前设置锁工厂 CoreContainer coreContainer = new CoreContainer(solrHomePath); // 配置NativeFSLockFactory,指定锁存储目录(可以用SolrHome下的locks目录) LockFactory lockFactory = new NativeFSLockFactory(new File(solrHomePath, "locks")); coreContainer.setDefaultLockFactory(lockFactory); // 加载配置并初始化 coreContainer.load(); // 创建EmbeddedSolrServer实例 EmbeddedSolrServer solrServer = new EmbeddedSolrServer(coreContainer, coreName);
注意:两个应用的CoreContainer都要做相同的锁工厂配置,确保它们使用同一种锁机制和同一个锁存储目录。
3. 检查只读应用的锁模式
你的只读应用不需要获取写锁,但Solr在读取索引时也会获取读锁(防止写操作破坏索引)。需要确保只读应用的EmbeddedSolrServer配置正确:
- 不要在只读应用中设置
solr.lock.type=none,这会完全禁用锁,导致读写冲突。 - 只读应用的锁工厂配置要和写应用保持一致,这样读锁和写锁才能互相识别。
4. 验证CoreContainer的单例正确性
虽然你说每个应用都用单例模式获取EmbeddedSolrServer,但还是要确认:
- 每个应用确实只初始化了一个CoreContainer实例(多个CoreContainer实例即使配置了相同锁工厂,也可能出现异常)
- 两个应用的CoreContainer都指向同一个SolrHome路径,路径配置没有拼写错误(比如相对路径导致实际指向不同目录)
5. 查看Solr日志排查锁相关错误
在Solr的日志中搜索lock相关关键词,比如:
Failed to acquire lockLock releasedLockFactory
这些日志能帮你定位锁获取失败的具体原因,比如锁目录权限不足、锁工厂类型不匹配等。
内容的提问来源于stack exchange,提问作者Jing
相关产品推荐
相关产品推荐

