15

大規模なデータセット(4,100万レコード)を新しいSolrインデックスにインポートしようとしています。私はコアをセットアップしました、それは動作します、私はいくつかのテストドキュメントを挿入しました、それらは動作します。以下のようにdata-config.xmlを設定してから、完全インポートを開始します。約12時間後!インポートは失敗します。

ドキュメントのサイズが非常に大きくなる可能性があります。エラーは、ドキュメント(またはフィールド)が大きいためか、DataImportHandlerに入力されるデータの量が原因である可能性がありますか?

このイライラするインポートタスクを機能させるにはどうすればよいですか!?!

以下にTomcatエラーログを含めました。

私が見逃した情報があれば教えてください!

ログ:

Jun 1, 2011 5:47:55 PM org.apache.solr.handler.dataimport.JdbcDataSource$1 call
INFO: Creating a connection for entity results with URL: jdbc:sqlserver://myserver;databaseName=mydb;responseBuffering=adaptive;selectMethod=cursor
Jun 1, 2011 5:47:56 PM org.apache.solr.handler.dataimport.JdbcDataSource$1 call
INFO: Time taken for getConnection(): 1185
Jun 1, 2011 5:48:02 PM org.apache.solr.core.SolrCore execute
INFO: [results] webapp=/solr path=/dataimport params={command=full-import} status=0 QTime=0
...
Jun 2, 2011 5:16:32 AM org.apache.solr.common.SolrException log
SEVERE: Full Import failed:org.apache.solr.handler.dataimport.DataImportHandlerException: java.lang.OutOfMemoryError: Java heap space
    at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:664)
    at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:267)
    at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:186)
    at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:353)
    at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:411)
    at org.apache.solr.handler.dataimport.DataImporter$1.run(DataImporter.java:392)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.lang.StringCoding$StringDecoder.decode(Unknown Source)
    at java.lang.StringCoding.decode(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at com.microsoft.sqlserver.jdbc.DDC.convertStreamToObject(DDC.java:419)
    at com.microsoft.sqlserver.jdbc.ServerDTVImpl.getValue(dtv.java:1974)
    at com.microsoft.sqlserver.jdbc.DTV.getValue(dtv.java:175)
    at com.microsoft.sqlserver.jdbc.Column.getValue(Column.java:113)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getValue(SQLServerResultSet.java:1982)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getValue(SQLServerResultSet.java:1967)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getObject(SQLServerResultSet.java:2256)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getObject(SQLServerResultSet.java:2265)
    at org.apache.solr.handler.dataimport.JdbcDataSource$ResultSetIterator.getARow(JdbcDataSource.java:286)
    at org.apache.solr.handler.dataimport.JdbcDataSource$ResultSetIterator.access$700(JdbcDataSource.java:228)
    at org.apache.solr.handler.dataimport.JdbcDataSource$ResultSetIterator$1.next(JdbcDataSource.java:266)
    at org.apache.solr.handler.dataimport.JdbcDataSource$ResultSetIterator$1.next(JdbcDataSource.java:260)
    at org.apache.solr.handler.dataimport.EntityProcessorBase.getNext(EntityProcessorBase.java:78)
    at org.apache.solr.handler.dataimport.SqlEntityProcessor.nextRow(SqlEntityProcessor.java:75)
    at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:238)
    at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:591)
    ... 5 more

Jun 2, 2011 5:16:32 AM org.apache.solr.update.DirectUpdateHandler2 rollback
INFO: start rollback
Jun 2, 2011 5:16:44 AM org.apache.solr.update.DirectUpdateHandler2 rollback
INFO: end_rollback

data-config.xml:

<dataConfig> 
  <dataSource type="JdbcDataSource" 
        driver="com.microsoft.sqlserver.jdbc.SQLServerDriver" 
        url="jdbc:sqlserver://myserver;databaseName=mydb;responseBuffering=adaptive;selectMethod=cursor"   
        user="sa" 
        password="password"/> 
  <document> 
    <entity name="results" query="SELECT fielda, fieldb, fieldc FROM mydb.[dbo].mytable WITH (NOLOCK)"> 
      <field column="fielda" name="fielda"/><field column="fieldb" name="fieldb"/><field column="fieldc" name="fieldc"/> 
    </entity> 
  </document> 
</dataConfig> 

solrconfig.xmlスニペット:

<indexDefaults>
    <useCompoundFile>false</useCompoundFile>
    <mergeFactor>25</mergeFactor>
    <ramBufferSizeMB>128</ramBufferSizeMB>
    <maxFieldLength>100000</maxFieldLength>
    <writeLockTimeout>10000</writeLockTimeout>
    <commitLockTimeout>10000</commitLockTimeout>
  </indexDefaults>
  <mainIndex>
    <useCompoundFile>false</useCompoundFile>
    <ramBufferSizeMB>128</ramBufferSizeMB>
    <mergeFactor>25</mergeFactor>
     <infoStream file="INFOSTREAM.txt">true</infoStream>
  </mainIndex>

Java構成設定:init mem 128mb、最大512mb

環境:solr 3.1 tomcat 7.0.12 Windows Server 2008 java:v6 update 25(build 1.6.0_25-b06)(data from:sql 2008 r2)

/admin/stats.jsp - DataImportHandler
    Status : IDLE
    Documents Processed : 2503083
    Requests made to DataSource : 1
    Rows Fetched : 2503083
    Documents Deleted : 0
    Documents Skipped : 0
    Total Documents Processed : 0
    Total Requests made to DataSource : 0
    Total Rows Fetched : 0
    Total Documents Deleted : 0
    Total Documents Skipped : 0
    handlerStart : 1306759913518
    requests : 9
    errors : 0 

編集:これはおそらく例外の原因であると思うので、私は現在、最大の単一レコードのフィールド長を見つけるためにSQLクエリを実行しています。また、ヒープの使用状況を監視するために、jconsoleでインポートを再度実行します。

編集:Solrパフォーマンスファクターのページを読んでください。maxFieldLengthを1000000に変更し、ramBufferSizeMB = 256を変更します。次に、別のインポートを実行します(yay ...)

4

5 に答える 5

8
Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.lang.StringCoding$StringDecoder.decode(Unknown Source)
    at java.lang.StringCoding.decode(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at java.lang.String.<init>(Unknown Source)
    at com.microsoft.sqlserver.jdbc.DDC.convertStreamToObject(DDC.java:419)

MSJDBCドライバーのRAMが不足していることは明らかです。多くのJDBCドライバーは、デフォルトですべての結果を一度にメモリーにフェッチすることができます。したがって、これを調整できるかどうかを確認するか、いずれにせよ一般的に適切に動作するオープンソースのJTDSドライバーの使用を検討してください。

maxfieldlengthが役立つとは思わない-それはLuceneが切り捨てる量に影響するが、最初に転送される量には影響しない。もう1つのオプションは、ページングにTOPやROWNUMBERなどを使用して、一度に選択範囲(たとえば、100万)のみを転送することです。

于 2011-06-09T01:47:41.440 に答える
1

クエリを手動でバッチ処理することで、メモリ不足エラーが発生することなく、jdbcを使用して大きなテーブルをSQLServerに正常にインポートできました。私の場合、256バッチで:

data-config.xml:

<dataConfig> 
  <dataSource  
      type="JdbcDataSource" 
      driver="com.microsoft.sqlserver.jdbc.SQLServerDriver"
      url="jdbc:sqlserver://myserver;databaseName=mydb;responseBuffering=adaptive;selectMethod=cursor"   
      user="sa" 
      password="password" 
      autoCommit="true" 
      batchSize="10000" /> 
  <document> 
    <entity 
        name="batch"
        query="
          with Batch as (
            select 0 BatchId
            union all 
            select BatchId + 1
            from Batch
            where BatchId < 255
          ) 
          select BatchId FROM Batch OPTION (MAXRECURSION 500)
        "
        dataSource="JdbcDataSource"
        rootEntity="false">
      <entity name="results" query="SELECT fielda, fieldb, fieldc FROM mydb.[dbo].mytable WITH (NOLOCK) WHERE CONVERT(varbinary(1),fielda) = ${batch.BatchId}"> 
        <field column="fielda" name="fielda"/><field column="fieldb" name="fieldb"/><field column="fieldc" name="fieldc"/> 
      </entity> 
    </entity> 
  </document> 
</dataConfig>

親エンティティバッチは、バイト値0〜255を返す再帰的なSQLサーバーCTEです。これは、子エンティティの結果をフィルタリングするために使用されます。

注1: where条件(つまり、CONVERT(varbinary(1)、fielda)= $ {batch.BatchId})は、結果を等しいバッチに分割するために、分割フィールドのタイプと内容に応じて調整する必要があります。例:fieldaが数値の場合、fielda%255 =${batch.BatchId}を使用します。私の場合、fieldaはuniqueidentifierであったため、最初のバイトで十分でした。

注2:バッチエンティティのrootEntity = "false"は必須であり、バッチエンティティがルートドキュメントではないことを示します。

于 2013-03-28T01:13:00.500 に答える
1

mysqlの場合、それは機能します

solr wikiによると、

DataImportHandlerは、行を1つずつストリーミングするように設計されています。フェッチサイズ値(デフォルト:500)をStatement#setFetchSizeに渡しますが、一部のドライバーはこれを尊重しません。MySQLの場合、batchSizeプロパティを値-1のdataSource構成に追加します。これにより、Integer.MIN_VALUEがフェッチサイズとしてドライバーに渡され、大きなテーブルのメモリが不足するのを防ぎます。

次のようになります。

<dataSource type="JdbcDataSource" name="ds-2" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:8889/mysqldatabase" batchSize="-1" user="root" password="root"/>
于 2015-12-29T13:30:35.610 に答える
0

このジョブには、Java構成設定では不十分な場合があります:init mem 128mb、max 512mb

OutOfMemoryErrorのこのカーゴカルト修正を試してください。ヒープサイズを増やして、余裕があれば-Xmx1024M以上にし、最初の512M-Xms512Mにします。

于 2011-06-15T18:43:44.063 に答える
0

大きなレコードセットでは、物事が少し厄介になる可能性があることがわかりました。いくつかのオプションがあります。

迅速で最も可能性の高い最良のオプションは、インデックスシステムにより多くのメモリを割り当てることです。メモリ(ほとんどの場合)はかなり安いです。

私が試みるかもしれない他のことは、データをチャンク化することです。

「ドキュメント」のサイズによっては、41Mのドキュメントが検索の妨げになる場合があります。ドキュメントをシャーディングすることをお勧めします。DIHを使用するときは、querystringパラメーターを使用してパーティション化を容易にしようとします。これを行うには、クエリステートメント内で${dataimporter.request.MYPARAMETERNAME}を使用してDHIに渡された適切なパラメーターを参照します。

于 2011-06-15T22:11:53.837 に答える