1

大きなファイル (列と同じ形式の行を含む) を処理する必要があります。処理中にプログラムがクラッシュする場合を考慮する必要があるため、この処理プログラムを再試行可能にする必要があります。つまり、クラッシュしてプログラムを再起動した後、失敗した行からファイルを処理し続けることができます。

従うことができるパターンや使用できるライブラリはありますか? ありがとうございました!


アップデート:

クラッシュのケースについては、OOM や内部の問題だけではありません。また、他の部品とのタイムアウトまたはマシンのクラッシュが原因である可能性もあります。したがって、try/catch ではこれを処理できません。


別の更新:

ファイルのチャンクについては、私の場合は実行可能ですが、思ったほど単純ではありません。前述したように、ファイルは複数の列でフォーマットされており、列の 1 つに基づいてファイルを数百のファイルに分割し、ファイルを 1 つずつ処理できます。しかし、これを行う代わりに、再試行をサポートする大きなファイル/データの処理に関する一般的なソリューションについて詳しく知りたいと思います。

4

3 に答える 3

1

私ならどうしますか(プロではありませんが)

  1. ファイル内のすべての行で呼び出されるLineProcessorを作成します

    クラス Processor は LineProcessor を実装します> {

            private List<String> lines = Lists.newLinkedList();
            private int startFrom = 0;
            private int lineNumber = 0;
    
            public Processor(int startFrom) {
                this.startFrom = startFrom;
            }
    
            @Override
            public List<String> getResult() {
                return lines;
            }
    
            @Override
            public boolean processLine(String arg0) throws IOException {
                lineNumber++;
                if (lineNumber < startFrom) {
                    // do nothing
                } else {
                    if (new Random().nextInt() % 50000 == 0) {
                        throw new IOException("Randomly thrown Exception " + lineNumber);
                    }
                     //Do the hardwork here
                    lines.add(arg0);
                    startFrom++;
                }
                return true;
            }
        }
    
  2. LineProcessorを利用するファイルを読み取るためのCallableを作成する

    class Reader implements Callable<List<String>> {
    
        private int startFrom;
    
        public Reader(int startFrom) {
            this.startFrom = startFrom;
        }
    
        @Override
        public List<String> call() throws Exception {
            return Files.readLines(new File("/etc/dictionaries-common/words"),
                Charsets.UTF_8, new Processor(startFrom));
        }
    }
    
  3. Callableを Retryer でラップし、 Executorを使用して呼び出します

    public static void main(String[] args) throws InterruptedException, ExecutionException {
    BasicConfigurator.configure();
    
    ExecutorService executor = Executors.newSingleThreadExecutor();
    
    Future<List<String>> lines = executor.submit(RetryerBuilder
            .<List<String>> newBuilder()
            .retryIfExceptionOfType(IOException.class)
            .withStopStrategy(StopStrategies.stopAfterAttempt(100)).build()
            .wrap(new Reader(100)));
    
    logger.debug(lines.get().size());
    executor.shutdown();
    logger.debug("Happily Ever After");
    

    }

于 2013-03-21T10:56:24.990 に答える
0

コードでチェックポイント/コミット スタイルのロジックを維持できます。したがって、プログラムが再度実行されると、同じチェックポイントから開始されます。

RandomAccessFile を使用してファイルを読み取り、 getFilePointer() を保持するチェックポイントとして使用できます。プログラムを再度実行するときは、seek(offset) を呼び出して、このチェックポイントから開始します。

于 2013-03-21T07:52:11.673 に答える
0

Catch win's save from OOM error を試してください。ファイルをチャンクで処理し、チャンクが成功するたびにその場所をファイルシステム/データベース/プログラムがクラッシュしても永続的な場所に保存する必要があります。その後、ソフトウェアを再起動したときに、保存した場所から前のポイントを読み取ることができます。また、ファイル全体が処理されるときに、この情報をクリーンアップする必要があります。

于 2013-03-21T07:53:41.510 に答える