高并发下SOLR单文档增量索引部分失败,如何实现请求排队?
问题根源
你遇到的更新失效、数据丢失问题本质不是请求被忽略,而是你用的Solr DataImportHandler(DIH)的full-import接口默认不支持并发执行:同一时间core只能运行一个导入任务,后续到达的full-import请求会被直接拒绝,不会进入排队,这是DIH的固有设计。
解决方案
方案一:替换单条同步的实现方式(优先级最高)
用full-import做单条数据同步属于不合理使用,直接替换为Solr原生update接口可彻底解决并发问题:
- 业务侧先查询数据库拿到对应ID的文档数据,直接以JSON/XML格式POST到
http://localhost:8983/solr/mycore/update接口,该接口天然支持并发写入,不会出现任务互斥问题,你的单条写入耗时还能进一步压缩。 - 如果必须保留DIH同步逻辑,将
full-import改为delta-import,配置好delta查询规则,也能规避full-import的并发限制。
方案二:基于现有逻辑实现请求排队
如果暂时不能修改同步逻辑,可在业务侧加队列层解决冲突:
- 所有DIH同步请求先写入内存队列(如Java的BlockingQueue、Go的Channel)或消息队列(如RabbitMQ),启动1~2个固定消费线程串行发送请求到Solr,保证同一时间只有一个DIH任务在运行,后续请求自动排队等待。
- 消费时可合并相邻的多个单条同步请求,批量传入多个ID到where条件,一次请求同步多条数据,大幅降低请求频次,提升整体吞吐量。
方案三:修改Solr DIH配置(不推荐)
可在solrconfig.xml的DIH配置项中添加<bool name="parallel">true</bool>开启并行导入,但该配置容易引发写入版本冲突、索引数据损坏等问题,尤其你当前每次请求都带commit参数,会进一步放大一致性风险,不建议使用。
额外优化建议
你当前请求带的commit=true参数会触发每次写入都做硬提交,200万文档量级下频繁硬提交会带来极高的IO开销,建议优化:
- 移除请求中的
commit=true参数,在solrconfig.xml中配置自动提交策略:比如autoCommit设为每1秒/满1000条文档做一次硬提交,autoSoftCommit设为100毫秒,兼顾数据可见性和写入性能。 - 如果要求更新立即可见,可将硬提交改为软提交,请求参数替换为
softCommit=true,性能远高于硬提交。
内容的提问来源于stack exchange,提问作者KoosMos
相关产品推荐
相关产品推荐

