web-dev-qa-db-ja.com

SOLR-csvファイルから2000万のドキュメントをインポートするための最良のアプローチ

私の現在のタスクは、何百万ものドキュメントをSolrにロードするための最良のアプローチを見つけることです。データファイルは、csv形式のDBからのエクスポートです。

現在、ファイルを小さなファイルに分割し、curlを使用してこの小さなファイルを投稿するときにスクリプトを作成することを考えています。

大量のデータを投稿すると、ほとんどの場合、リクエストがタイムアウトすることに気づきました。

私はデータインポーターを調べています、そしてそれは良いオプションのようです

他のアイデアは高く評価されています

ありがとう

14
Bobby ...

データベースがすでにソリューションの一部になっていない限り、ソリューションをさらに複雑にすることはありません。 SOLR FAQ を引用すると、セッションタイムアウトを発行しているのはサーブレットコンテナです。

私が見ているように、あなたにはいくつかのオプションがあります(私の好みの順序で):

コンテナのタイムアウトを増やす

コンテナのタイムアウトを増やします。 (埋め込みJettyインスタンスを使用している場合は、「maxIdleTime」パラメーター)。

私はあなたがたまにそのような大きなファイルにインデックスを付けるだけだと思いますか?一時的にタイムアウトを増やすのが最も簡単なオプションかもしれません。

ファイルを分割する

これがその仕事をする簡単なUNIXスクリプトです(ファイルを500,000行のチャンクに分割します):

split -d -l 500000 data.csv split_files.
for file in `ls split_files.*`
do  
curl 'http://localhost:8983/solr/update/csv?fieldnames=id,name,category&commit=true' -H 'Content-type:text/plain; charset=utf-8' --data-binary @$file
done

ファイルを解析し、チャンクでロードします

次のGroovyスクリプトは、opencsvとsolrjを使用してCSVファイルを解析し、500,000行ごとにSolrに変更をコミットします。

import au.com.bytecode.opencsv.CSVReader

import org.Apache.solr.client.solrj.SolrServer
import org.Apache.solr.client.solrj.impl.CommonsHttpSolrServer
import org.Apache.solr.common.SolrInputDocument

@Grapes([
    @Grab(group='net.sf.opencsv', module='opencsv', version='2.3'),
    @Grab(group='org.Apache.solr', module='solr-solrj', version='3.5.0'),
    @Grab(group='ch.qos.logback', module='logback-classic', version='1.0.0'),
])

SolrServer server = new CommonsHttpSolrServer("http://localhost:8983/solr/");

new File("data.csv").withReader { reader ->
    CSVReader csv = new CSVReader(reader)
    String[] result
    Integer count = 1
    Integer chunkSize = 500000

    while (result = csv.readNext()) {
        SolrInputDocument doc = new SolrInputDocument();

        doc.addField("id",         result[0])
        doc.addField("name_s",     result[1])
        doc.addField("category_s", result[2])

        server.add(doc)

        if (count.mod(chunkSize) == 0) {
            server.commit()
        }
        count++
    }
    server.commit()
}
22
Mark O'Connor

SOLR 4.0(現在ベータ版)では、ローカルディレクトリからのCSVをUpdateHandlerを使用して直接インポートできます。からの例の変更 SOLR Wiki

curl http://localhost:8983/solr/update?stream.file=exampledocs/books.csv&stream.contentType=text/csv;charset=utf-8

また、これによりファイルがローカルの場所からストリーミングされるため、ファイルをチャンク化してPOST HTTP経由で送信する必要はありません。

12
busybee

上記の回答は、単一のマシンからの取り込み戦略を非常によく説明しています。

ビッグデータインフラストラクチャが整っていて、分散データ取り込みパイプラインを実装したい場合は、さらにいくつかのオプションがあります。

  1. Sqoopを使用してデータをhadoopに移動するか、csvファイルを手動でhadoopに配置します。
  2. 以下のコネクタのいずれかを使用して、データを取り込みます。

Hive- solrコネクタspark- solrコネクタ

PS:

  • クライアントノードとsolr/solrcloudノード間の接続をファイアウォールがブロックしていないことを確認してください。
  • データの取り込みに適切なディレクトリファクトリを選択します。ほぼリアルタイムの検索が必要ない場合は、StandardDirectoryFactoryを使用します。
  • 取り込み中にクライアントログで以下の例外が発生した場合は、solrconfig.xmlファイルのautoCommitおよびautoSoftCommit構成を調整してください。

SolrServerException:このリクエストを処理するために利用できるライブSolrServerがありません

3
Rahul Sharma

間違いなく、最初にこれらを通常のデータベースにロードするだけです。 CSVを処理するためのあらゆる種類のツールがあります(たとえば、 postgres'COPY )ので、簡単なはずです。 Data Import Handler の使用も非常に簡単なので、これはデータをロードするための最も摩擦のない方法のようです。不要なネットワーク/ HTTPオーバーヘッドが発生しないため、この方法も高速になります。

1
beerbajay