如何使用SOLRJ的ConcurrentUpdateSolrClient批量更新Solr文档?
ConcurrentUpdateSolrClient 批量写入(含Javabin传输)实操示例
你的猜测基本正确,ConcurrentUpdateSolrClient的新增、更新逻辑和HttpSolrClient高度兼容,文档id重复时会自动覆盖更新,且客户端默认使用Javabin格式做数据传输,吞吐量远高于普通HttpSolrClient,非常适合大批量数据写入场景。
前置依赖(Maven示例)
需保证solrj版本和你的Solr服务端版本一致,以下为通用依赖配置:
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <!-- 替换为你的Solr服务对应版本,如8.11.2、9.3.0等 --> <version>8.11.2</version> </dependency>
完整批量写入代码示例
import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; import org.apache.solr.common.SolrInputDocument; public class SolrBatchOperateDemo { public static void main(String[] args) { // 初始化客户端,默认已开启Javabin序列化传输 ConcurrentUpdateSolrClient client = new ConcurrentUpdateSolrClient.Builder("http://my-solr-server:8983/solr/core1") // 内部队列阈值,达到该数值客户端自动触发批量提交 .withQueueSize(1000) // 后台提交线程数,建议设置为服务器CPU核心数的1~2倍 .withThreadCount(4) // 可选配置:每批自动提交,大批量写入不建议开启,会降低性能 // .withAlwaysCommitBatch(true) .build(); try { // 模拟批量生成10000条文档,更新操作仅需将id替换为已存在的id即可 for (int i = 0; i < 10000; i++) { SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", "doc_" + i); doc.addField("title", "测试文档标题" + i); doc.addField("content", "这是第" + i + "条批量写入的文档内容"); // 直接添加单条文档即可,客户端内部自动攒批发送 client.add(doc); } // 所有文档写入完成后统一提交 client.commit(); } catch (Exception e) { e.printStackTrace(); try { // 写入异常时回滚所有未提交的变更 client.rollback(); } catch (Exception ex) { ex.printStackTrace(); } } finally { try { // 关闭客户端释放连接资源 client.close(); } catch (Exception e) { e.printStackTrace(); } } } }
核心注意事项
- 无需手动攒文档集合调用批量add方法,客户端内部队列会按照配置的
queueSize自动批量发送,直接循环调用单条add不会有性能损耗 - Javabin传输默认已开启,无需额外配置,相比XML格式传输效率提升3~5倍,序列化、反序列化开销更低
- 大批量写入场景建议关闭自动提交,所有文档添加完成后统一调用
commit,可以减少Solr服务端的IO开销和索引合并频率,提升整体写入速度 - 若需验证Javabin传输是否生效,可在Solr服务端的请求日志中查看请求的
wt参数是否为javabin
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

