solr大批量数据导出

需求

有100个core,每个core4000w数据量。把所有数据导出来。

方案1.

直接对每个core通过HttpSolrClient先取出总条数,然后通过每次分页读n行,直到读完,这个方案肯定不行,因为越到后面,读取速度越慢,不用想都要很长时间。

方案2.

深度分页

通过游标,可以使分页速度很快。

SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("*:*");
solrQuery.setFields("*");
solrQuery.addSort("uid", ORDER.asc); 
String cursorMark = CursorMarkParams.CURSOR_MARK_START;

solrQuery.setRows(config.getBlockSize());
boolean done = false;
while (!done) {
  solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark); 
  QueryResponse rsp = client.query(solrQuery);
  String nextCursorMark = rsp.getNextCursorMark();
  SolrDocumentList results = rsp.getResults();
  for (SolrDocument d : results) {
    
  }
  if (nextCursorMark == null || cursorMark.equals(nextCursorMark)) {
            done = true;
  }
  cursorMark = nextCursorMark;
}

但是发现每次查询都很慢,qtime基本都在1s以内,但是拿到QueryResponse要1分钟。不知道为什么。网上说qtime只是返回所以数据id的时间,但是返回数据还要时间

方案3

通过EmbeddedSolrServer提取

这个是比较底层的操作,也是先得到总条数,然后通过每次分页读n行,直到读完。

进过测试一小时700多万条数据输出,但是也越往后越慢,一个core执行完需要15小时

方案4

直接lucene读取

lucene也有两种,一种是直接读取全部数据放内存,说是速度很快,但是内存占用太大。所以还是用luncene的分页算法。

Directory dir = FSDirectory.open(Paths.get(corepath, key, "data/index"));
IndexReader indexReader = DirectoryReader.open(dir);
Query query = new MatchAllDocsQuery();

IndexSearcher searcher = new IndexSearcher(indexReader);

int pageStart = 0;
ScoreDoc lastBottom = null;
int count = 0;
while (pageStart < 100000000) {//10000000足够大就行
  TopDocs tds = searcher.searchAfter(lastBottom, query, 50000);
  if (tds.scoreDocs.length == 0) {
	break;
  }

pageStart += tds.scoreDocs.length;
lastBottom = tds.scoreDocs[tds.scoreDocs.length - 1];
List<String> list = new ArrayList<String>();
for (ScoreDoc sc : tds.scoreDocs) {

  Document doc = searcher.doc(sc.doc);

  String uid = doc.get("uid"));
  //....
  
  count += 50000;
  System.out.println("--------------------------------" + count);

}
indexReader.close();
dir.close();
System.out.println(key + "end.................");

这个方法一个core几十分钟就搞定了

你可能感兴趣的:(solr)