29

ここに私の問題があります: 私は潜在的に巨大になる可能性のあるファイルを HDFS に持っています (= すべてをメモリに収めるのに十分ではありません)。

私がやりたいことは、このファイルをメモリにキャッシュする必要を避け、通常のファイルで行うように1行ずつ処理することです:

for line in open("myfile", "r"):
    # do some processing

外部ライブラリを使用せずにこれを正しく行う簡単な方法があるかどうかを調べています。おそらくlibpyhdfsまたはpython-hdfsで動作させることができますが、システムに新しい依存関係やテストされていないライブラリを導入することはできれば避けたいと思います。生産で使用されます。

Pythonモジュールを使用して標準の「hadoop」コマンドラインツールを使用してこれを行うことを考えていましたsubprocessが、処理を実行するコマンドラインツールがないため、必要なことを実行できないようです。ストリーミング方式ですべての行に対して Python 関数を実行します。

subprocess モジュールを使用して Python 関数をパイプの右オペランドとして適用する方法はありますか? または、ファイルのようにジェネレーターとして開くと、各行を簡単に処理できますか?

cat = subprocess.Popen(["hadoop", "fs", "-cat", "/path/to/myfile"], stdout=subprocess.PIPE)

外部ライブラリを使用せずに上記のことを達成する別の方法がある場合、私もかなりオープンです。

助けてくれてありがとう!

4

4 に答える 4

44

xreadlinesが必要な場合、ファイル全体をメモリにロードせずにファイルから行を読み取ります。

編集

Popenオブジェクトから stdout パイプを取得する必要があるだけです。

cat = subprocess.Popen(["hadoop", "fs", "-cat", "/path/to/myfile"], stdout=subprocess.PIPE)
for line in cat.stdout:
    print line
于 2012-09-18T22:04:22.797 に答える
32

どんな犠牲を払っても外部依存関係を追加したくない場合は、キースの答えが最適です。 一方、 Pydoopを使用すると、作業がはるかに簡単になります。

import pydoop.hdfs as hdfs
with hdfs.open('/user/myuser/filename') as f:
    for line in f:
        do_something(line)

あなたの懸念に関して、Pydoop は活発に開発されており、主に計算生物学アプリケーションのためにCRS4で何年も本番環境で使用されてきました。

シモーネ

于 2013-01-15T10:15:33.553 に答える
1

過去 2 年間、Hadoop ストリーミングに関する多くの動きがありました。Cloudera によると、これはかなり高速です: http://blog.cloudera.com/blog/2013/01/a-guide-to-python-frameworks-for-hadoop/ 私はこれでうまくいきました。

于 2014-10-03T16:00:39.137 に答える