में BZ2 JSON ट्विटर फ़ाइलों के साथ प्रभावी रूप से बड़ी (30GB +) TAR फ़ाइल को प्रभावी ढंग से कैसे पढ़ा जाए, मैं archive.org archive से ट्विटर डेटा प्राप्त करने और इसे डेटाबेस में लोड करने का प्रयास कर रहा हूं। मैं पहले एक विशिष्ट महीने के लिए सभी ट्वीट्स लोड करने का प्रयास कर रहा हूं, फिर ट्वीट्स के लिए चयन कर सकता हूं और केवल उन लोगों को मंचित कर सकता हूं जिनमें मुझे रूचि है (जैसे लोकेल, या हैशटैग)।पोस्टग्रेएसक्यूएल
मैं जो कुछ भी ढूंढ रहा हूं उसे करने के लिए नीचे वर्णित स्क्रिप्ट को चलाने में सक्षम हूं, लेकिन मुझे एक समस्या है कि यह अविश्वसनीय रूप से धीमी है। यह लगभग आधे घंटे तक चलता है और केवल एक टीएआर फ़ाइल में आंतरिक .bz2 फ़ाइलों के ~ 6/50,000 को पढ़ता है।
एक उदाहरण टीएआर फ़ाइल से कुछ आंकड़े:
- कुल आकार: ~ 30-40GB
- भीतरी .bz2 फ़ाइलों की संख्या (फ़ोल्डर में व्यवस्थित): 50,000
- आकार में से एक .bz2 फ़ाइल : ~ 600kb
- एक निकाली गई JSON फ़ाइल का आकार: ~ 5 एमबी, ~ 3600 ट्वीट्स।
गति के लिए इस प्रक्रिया को अनुकूलित करते समय मुझे क्या देखना चाहिए?
- क्या मुझे पाइथन में उन्हें बफर करने के बजाय फ़ाइलों को डिस्क में निकालना चाहिए?
- क्या मुझे प्रक्रिया के एक हिस्से को बहुसंख्यक देखना चाहिए? इस प्रक्रिया का कौन सा हिस्सा इष्टतम होगा?
- वैकल्पिक रूप से, क्या मैं वर्तमान में ऐसी स्क्रिप्ट के लिए अपेक्षाकृत सामान्य प्राप्त कर रहा हूं?
स्क्रिप्ट वर्तमान में मेरे सीपीयू का ~ 3% और ~ 6% मेरी रैम मेमोरी का उपयोग कर रही है।
किसी भी मदद की बहुत सराहना की जाती है।
import tarfile
import dataset # Using dataset as I'm still iteratively developing the table structure(s)
import json
import datetime
def scrape_tar_contents(filename):
"""Iterates over an input TAR filename, retrieving each .bz2 container:
extracts & retrieves JSON contents; stores JSON contents in a postgreSQL database"""
tar = tarfile.open(filename, 'r')
inner_files = [filename for filename in tar.getnames() if filename.endswith('.bz2')]
num_bz2_files = len(inner_files)
bz2_count = 1
print('Starting work on file... ' + filename[-20:])
for bz2_filename in inner_files: # Loop over all files in the TAR archive
print('Starting work on inner file... ' + bz2_filename[-20:] + ': ' + str(bz2_count) + '/' + str(num_bz2_files))
t_extract = tar.extractfile(bz2_filename)
data = t_extract.read()
txt = bz2.decompress(data)
tweet_errors = 0
current_line = 1
num_lines = len(txt.split('\n'))
for line in txt.split('\n'): # Loop over the lines in the resulting text file.
if current_line % 100 == 0:
print('Working on line ' + str(current_line) + '/' + str(num_lines))
try:
tweet = json.loads(line)
except ValueError, e:
error_log = {'Date_time': datetime.datetime.now(),
'File_TAR': filename,
'File_BZ2': bz2_filename,
'Line_number': current_line,
'Line': line,
'Error': str(e)}
tweet_errors += 1
db['error_log'].upsert(error_log, ['File_TAR', 'File_BZ2', 'Line_number'])
print('Error occured, now at ' + str(tweet_errors))
try:
tweet_id = tweet['id']
tweet_text = tweet['text']
tweet_locale = tweet['lang']
created_at = tweet['created_at']
tweet_json = tweet
data = {'tweet_id': tweet_id,
'tweet_text': tweet_text,
'tweet_locale': tweet_locale,
'created_at_str': created_at,
'date_loaded': datetime.datetime.now(),
'tweet_json': tweet_json}
db['tweets'].upsert(data, ['tweet_id'])
except KeyError, e:
error_log = {'Date_time': datetime.datetime.now(),
'File_TAR': filename,
'File_BZ2': bz2_filename,
'Line_number': current_line,
'Line': line,
'Error': str(e)}
tweet_errors += 1
db['error_log'].upsert(error_log, ['File_TAR', 'File_BZ2', 'Line_number'])
print('Error occured, now at ' + str(tweet_errors))
continue
if __name__ == "__main__":
with open("postgresConnecString.txt", 'r') as f:
db_connectionstring = f.readline()
db = dataset.connect(db_connectionstring)
filename = r'H:/Twitter datastream/Sourcefiles/archiveteam-twitter-stream-2013-01.tar'
scrape_tar_contents(filename)
मैन्युअल रूप से मैन्युअल रूप से निकालने के बाद कोड बहुत तेजी से चला गया: धन्यवाद। मैंने http://stackoverflow.com/questions/27847695/how-to-multithread-reading-dples-from-a-list-and-entering-into-डेटा "मल्टीथ्रेडिंग पर सहायता मांगने के लिए जोड़ा। क्या आप पॉइंटर्स ऑन यह, शायद? – MattV
लिनक्स टैर कमांड एक फ़ाइल को निकालने या मेनिफेस्ट में पूरी अनजान सामग्री को लोड किए बिना मैनिफेस्ट को सूचीबद्ध क्यों कर सकता है जबकि पाइथन का टैरिफाइल ऐसा लगता है? मेरे परीक्षण में, पाइथन 2 जीबी मेमोरी को सिंगल पाने के लिए क्या मिला फाइल आउट, टैर कमांड केवल 200 केबी का इस्तेमाल किया।ऐसा लगता है कि पाइथन संस्करण तुलना में यह बहुत अक्षमता से कर रहा है। – PKKid
@ पीकेकिड: आप [इस प्रभाव] देख रहे हैं (http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm)। अगर वह इसका उत्तर नहीं देता है, तो कृपया एक नया प्रश्न पोस्ट करें। – unutbu