测试代码
package mytest; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.client.solrj.impl.BinaryRequestWriter; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.core.CoreContainer; public class SolrTest { public static void test1() throws Exception { HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/dtrace"); solrServer.setRequestWriter(new BinaryRequestWriter()); int size = 100; long begin = System.currentTimeMillis(); for (int i = 0; i < size; ++i) { SolrInputDocument doc1 = new SolrInputDocument(); doc1.addField("id", i); doc1.addField("rowkey", "100 p"); doc1.addField("cf", "[{30:50}]"); doc1.addField("timestamp", System.currentTimeMillis()); solrServer.add(doc1); } long end = System.currentTimeMillis(); System.out.println(" add cost:" + (end - begin) + "ms"); begin = System.currentTimeMillis(); solrServer.commit(); end = System.currentTimeMillis(); // System.out.println(" commit " + size + " cost:" + (end - begin) + " ms"); } static ExecutorService service = Executors.newFixedThreadPool(20); static CoreContainer container = new CoreContainer("/duitang/data/solr"); static { container.load(); } static EmbeddedSolrServer solrServer = new EmbeddedSolrServer(container, "dtrace"); public static void _test2(int round) throws Exception { int count = 10000; int size = count * round; final CountDownLatch latch = new CountDownLatch(count); // final HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/dtrace"); // solrServer.setRequestWriter(new BinaryRequestWriter()); long begin = System.currentTimeMillis(); for (int i = size - count; i < size; ++i) { final int id = i; service.submit(new Runnable() { public void run() { SolrInputDocument doc1 = new SolrInputDocument(); doc1.addField("id", id); doc1.addField("rowkey", "12345678901234567890 12345678901234567890 12345678901234567890 12345678901234567890 12345678901234567890"); doc1.addField( "cf", "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); doc1.addField("timestamp", System.currentTimeMillis()); try { solrServer.add(doc1); latch.countDown(); } catch (Exception e) { e.printStackTrace(); } } }); } latch.await(); long end = System.currentTimeMillis(); System.out.println(" add[" + size + "] " + count + " cost:" + (end - begin) + "ms"); // begin = System.currentTimeMillis(); // solrServer.commit(false, false, true); // solrServer.commit(); // end = System.currentTimeMillis(); // System.out.println(" commit " + size + " cost:" + (end - begin) + "ms"); // service.shutdown(); } public static void test2() throws Exception { ExecutorService service = Executors.newFixedThreadPool(1); int count = 10000; final CountDownLatch latch = new CountDownLatch(count); long begin = System.currentTimeMillis(); for (int i = 7342; i <= count; ++i) { final int index = i; service.submit(new Runnable() { public void run() { try { _test2(index); latch.countDown(); } catch (Exception e) { e.printStackTrace(); } } }); } latch.await(); long end = System.currentTimeMillis(); System.out.println(" add finish " + count + " cost:" + (end - begin) + "ms"); } public static void test3() throws Exception { // CoreContainer container = new CoreContainer("/duitang/data/solr"); // container.load(); // EmbeddedSolrServer solrServer = new EmbeddedSolrServer(container, "dtrace"); SolrInputDocument doc1 = new SolrInputDocument(); doc1.addField("id", 1); doc1.addField("rowkey", "100 p"); doc1.addField("cf", "[{30:50}]"); doc1.addField("timestamp", System.currentTimeMillis()); solrServer.add(doc1); // solrServer.commit(); System.out.println("ok"); } public static void close() { solrServer.shutdown(); } public static void main(String[] args) throws Exception { test2(); // close(); // RAMDirectory rdir = new RAMDirectory(); // String fileList[] = rdir.listAll(); // for (int i = 0; i < fileList.length; i++) { // // } // FileSystem fs = FileSystem.get(null); // fs.startLocalOutput(fsOutputFile, tmpLocalFile) // FSDirectory.open(path) //IndexWriter indexWriter = new IndexWriter(); } }
每次build数据,1k字符串。
一.测试add性能
1.单个add
平均cost:4ms
2. 顺序执行,add 100个doc:
add cost:564ms
add cost:404ms
add cost:349ms
add cost:393ms
add cost:368ms
3. 20个并发,add 100个doc(增加到30,40个并发,性能没有增加):
add cost:74ms
add cost:78ms
add cost:61ms
add cost:60ms
3.20个并发, 不同doc的耗时
add 1000 cost:367ms
add 5000 cost:812ms
add 10000 cost:1624ms
add 20000 cost:3190ms
add 100000 cost:16874ms
二. 测试commit性能
1.等到多少条doc,提交一次的耗时
commit 100 cost:600 ms
commit 1000 cost:1053ms
commit 5000 cost:2130ms
commit 10000 cost:2542ms
commit 20000 cost:3057ms
commit 30000 cost:3036ms
commit 40000 cost:3408ms
commit 100000 cost:4808ms
三. 并发commit测试:
当开启5个线程并发commit时候,load上升到10+,会抛出异常:
org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException: Error opening new searcher. exceeded limit of maxWarmingSearchers=2, try again later.
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:491)
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:197)
at org.apache.solr.client.solrj.request.AbstractUpdateRequest.process(AbstractUpdateRequest.java:117)
at org.apache.solr.client.solrj.SolrServer.commit(SolrServer.java:168)
at org.apache.solr.client.solrj.SolrServer.commit(SolrServer.java:146)
at mytest.SolrTest.test2(SolrTest.java:74)
at mytest.SolrTest$2.run(SolrTest.java:88)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
三. 网络连接
测试发现solr不会开启长连接。
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46166 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46197 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46243 TIME_WAIT -
tcp6 0 183 127.0.0.1:8080 127.0.0.1:46302 ESTABLISHED 20112/java
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46173 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46228 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46230 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46278 TIME_WAIT -
tcp6 0 187 127.0.0.1:8080 127.0.0.1:46298 ESTABLISHED 20112/java
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46158 TIME_WAIT -
tcp6 0 0 127.0.0.1:46299 127.0.0.1:8080 ESTABLISHED 3321/java
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46137 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46160 TIME_WAIT -
tcp6 0 0 127.0.0.1:8080 127.0.0.1:46134 TIME_WAIT -
tcp6 0 187 127.0.0.1:8080 127.0.0.1:46288 ESTABLISHED 20112/java
yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ netstat -antp | grep 8080 | wc -l
331
yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ netstat -antp | grep 8080 | wc -l
411
yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ netstat -antp | grep 8080 | wc -l
660
yunpeng@yunpeng-duitang:/duitang/data/solr$ netstat -antp | grep 8080 | wc -l
10018
四. 索引数据量
插入30万条数据,单条数据1k,占用磁盘空间:9.5M,30万条1K数据实际应占用300MB,可见luence的索引是经过压缩的。大概是30:1。 (结论不正确,估计是因为测试是大量重复数据有关)
五.测试solr各种commit不同配置下的性能。
1.配置1
<updateHandler class="solr.DirectUpdateHandler2"> <autoCommit> <maxDocs>10000</maxDocs> <maxTime>1000</maxTime> <openSearcher>false</openSearcher> </autoCommit> <updateLog> <str name="dir">${solr.shard.data.dir:}</str> </updateLog> </updateHandler>
结果:
1.无法查询到结果。
2.yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ du -sh data/*
2.9M data/index
39M data/tlog
3. add 5000 cost:2405ms
2. 配置2:
<updateHandler class="solr.DirectUpdateHandler2"> <autoCommit> <maxDocs>10000</maxDocs> <maxTime>1000</maxTime> <openSearcher>true</openSearcher> </autoCommit> <updateLog> <str name="dir">${solr.shard.data.dir:}</str> </updateLog> </updateHandler>
结果:
1.可以查询到结果。
2.yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ du -sh data/*
1.7M data/index
27M data/tlog
3. add5000 cost:2726ms
3. 配置3:
<updateHandler class="solr.DirectUpdateHandler2"> <autoCommit> <maxTime>2000</maxTime> <openSearcher>false</openSearcher> </autoCommit> <autoSoftCommit> <maxTime>10000</maxTime> </autoSoftCommit> <updateLog> <str name="dir">${solr.shard.data.dir:}</str> </updateLog> </updateHandler>
结果:
1.可以查询到结果。
2.yunpeng@yunpeng-duitang:/duitang/data/solr/dtrace$ du -sh data/*
2.0M data/index
31M data/tlog
3. add 5000 cost:1264ms
五.结论
1. 通过http api solr单机build索引最大QPS 5k。
相关推荐
- **创建索引**:客户端(可以是浏览器或 Java 程序)用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr 服务器根据 XML 文档添加、删除或更新索引。 - **搜索索引**:客户端用 GET 方法向 ...
Solr的运行依赖于Apache Lucene,这是一个高度可配置和高性能的全文检索库。Lucene的jar包包括了索引和搜索的基本功能,如分词器、查询解析器和排序算法等。在Solr的lib目录下,你会找到像lucene-core.jar、lucene-...
Apache Solr 是一款开源的、高性能的企业级搜索平台,基于 Lucene 库构建而成。它提供了高度可伸缩性的全文检索功能,并支持多种语言。Solr 被广泛应用于企业级搜索解决方案中,能够处理大量的数据,并提供快速、...
在本文发布时,Solr 1.4是最新版本,其目录结构包括多个子目录,如build、client、dist、example、src等,每个目录都有其特定的作用,如存放编译文件、API客户端程序、构建后的文件、示例数据、源码等。 ##### Solr...
- `build.xml` 文件:Ant构建脚本,用于编译、测试和打包Solr。 - `LICENSE` 和 `NOTICE` 文件:包含了Apache软件基金会的许可协议信息。 如果你打算使用或开发Solr,你需要熟悉Java编程,理解Solr的架构和工作流程...
10. **性能优化**:了解Solr的缓存机制(如QueryResultCache、DocumentCache等)和并发控制策略,有助于提高Java应用与Solr交互的性能。 通过理解和应用上述知识点,Java开发者能够在项目中顺利地集成Solr,构建...
1. **连接Solr服务器**: 创建`SolrClient`实例,如`SolrClient client = new HttpSolrClient.Builder("http://localhost:8983/solr/my_core").build();` 2. **索引文档**: 使用`add`方法添加文档,`client.add(doc)...
相较于 Lucene,Solr 提供了更为丰富的查询语言支持,并且具备高度可配置性和可扩展性,针对索引和搜索性能进行了专门优化。 - **查询语言丰富**:Solr 支持多种查询方式,如简单查询、高级查询、近似匹配等。 - **...
CloudSolrClient solr = new CloudSolrClient.Builder("http://localhost:8983/solr").build(); // 添加文档 SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", "doc1"); doc.addField(...
接着,需要将 example\solr 目录下的文件复制到 web 项目的根目录下,这是索引库,collection1 是默认索引库名称。 3. 配置 Solr 完成上述步骤后,一个基本的 Solr 一级搭建好了。下面开始配置具体信息。需要编辑 ...
通过研究这些文件和目录,开发者可以学习如何配置Solr服务器,创建和管理索引,实现复杂的查询逻辑,以及优化搜索性能。同时,Solr 7.7.3可能包含了一些新特性、改进和bug修复,具体细节可以通过阅读CHANGES.txt来...
Solr是Apache Lucene项目的一个子项目,是一个高性能、基于Java的企业级搜索服务器。它提供了全文检索、Hit高亮、拼写检查、动态集群、分布式搜索等特性,广泛应用于各类数据检索场景。在本篇文章中,我们将深入探讨...
同时,Solr 的监控和日志记录也是运维过程中不可忽视的部分,确保系统运行稳定且性能良好。 总的来说,Solr 是一个强大且灵活的搜索引擎,它结合了 Lucene 的强大检索能力并提供了服务器化的解决方案,适用于各种...
- **性能优化**:Solr 4.10在查询速度和索引构建方面进行了优化,提高了处理高并发请求的能力。 - **分布式搜索**:支持多节点的SolrCloud模式,可以实现自动的索引分片和复制,以确保高可用性和故障恢复。 - **...
1. 创建索引:客户端(可以是浏览器可以是 Java 程序)用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr 服务器根据 xml 文档添加、删除、更新索引。 2. 搜索索引:客户端(可以是浏览器...
DataImportHandler-Scheduler 插件则增强了这个功能,它允许用户设定定时任务,自动监测数据源的变化,并仅导入新的或更新的数据,从而减少了不必要的全量索引重建,提高了系统的性能和响应速度。 在源码包 "solr-...
Solr是一款开源的、高性能的企业级全文搜索引擎,它可以独立运行并通过HTTP协议提供服务。用户可以通过发送XML文件来创建索引,或者通过HTTP GET请求来进行检索,并且检索结果会以XML格式返回。 #### 二、Solr的...
PHP扩展Solr是PHP与Apache Solr搜索引擎之间的桥梁,它允许PHP应用程序无缝地与Solr服务器进行交互,执行搜索、索引操作等。在Linux环境下安装这个扩展,需要遵循一系列步骤,确保所有依赖项都已满足,并正确编译和...
1. **Apache Solr**:了解Solr的核心概念,如索引、查询、分布式搜索等,以及如何使用Tika解析器处理非文本内容。 2. **Tika解析器**:学习如何配置和使用Tika,以解析不同文件格式并提取文本信息,将其索引到Solr...