2014-09-10 276 views
3

我有一个有趣的问题。作为一名初学者,当涉及到数据处理的规模时,我会喜欢这里的老兵的一些技巧。阅读/解析大量JSON.gz文件的优化技巧

我身边有6000 Json.gz文件总数约为5GB压缩和非压缩20GB。 我打开每个文件并使用gzip模块逐行读取它们;然后使用json.loads()加载每一行并解析复杂的JSON结构。然后,我会在每次迭代到下一个文件之前将每个文件中的行同时插入到Pytable中。

这一切正在我周围3小时。大容量插入到Pytable并没有真正帮助速度。由于它们有一个真正可怕的结构,大部分时间都没有从解析的JSON行获取值。有些是直接像'attrname':attrvalue,但有些是复杂和耗时的结构,如:

'attrarray':[{'name':abc, 'value':12},{'value':12},{'name':xyz, 'value':12}...]

...我需要拿起attr阵列中的所有这些对象已有些相应namevalue,并忽略那些没有的。所以我需要遍历列表并检查每个JSON对象。 (我会很高兴,如果你能指出任何更快聪明的方法,如果存在的话)

,所以我想它的实际的解析部分没有加速的很大余地。我认为他们的可能是加速范围是实际读取的文件部分。

所以我跑了几个测试(我没有与我的数字现在),甚至删除我的程序的解析部分之后;简单地通过文件行本身花了相当长的时间。

那么请问:是否有这个问题,你觉得我可能是次优做的任何部分?

for filename in filenamelist: 
    f = gzip.open(filename): 
    toInsert=[] 
    for line in f: 
     parsedline = json.loads(line) 
     attr1 = parsedline['attr1'] 
     attr2 = parsedline['attr2'] 
     . 
     . 
     . 
     attr10 = parsedline['attr10'] 
     arr = parsedline['attrarray'] 
     for el in arr: 
      try: 
       if el['name'] == 'abc': 
        attrABC = el['value'] 
       elif el['name'] == 'xyz': 
        attrXYZ = el['value'] 
       . 
       . 
       . 
      except KeyError: 
       pass 
     toInsert.append([attr1,attr2,...,attr10,attrABC,attrXYZ...]) 

    table.append(toInsert) 
+0

请包含profiler的输出 – shx2 2014-09-10 20:30:24

+1

问题可能是gzip模块。这里有一些替代方法:http://aripollak.com/pythongzipbenchmarks/ – matiasg 2014-09-10 20:46:27

+0

当你说阅读需要相当长的时间时,包括IO和解压缩两项成本。确保你找出哪些需要多少时间。之后,解析和处理这些行是第三件事。他们三个人都可以并行处理,以更好地使用现代计算机。最后,如果你有多行可以解析为JSON,那么整个文件就不是JSON。或者,它可能是文件只包含一行?这可能会影响解析,至少看起来很奇怪。 – 2014-09-10 20:47:57

回答

3

一个明显的一块“唾手可得”

如果你将要一遍又一遍访问相同的压缩文件(这不是从你的描述特别清楚这是否是一种单时间操作),那么你应该解压缩一次,而不是每次读取它们时将其解压缩。

解压缩是CPU密集型操作,与zcat/gunzip等C实用程序相比,Python's gzip module is not that fast

可能是最快的方法是gunzip所有这些文件,保存在某个地方的结果,然后从你的脚本中的未压缩的文件读取。

其他问题

这剩下的是不是一个真正的答案,但它是一个评论太长。为了使这个速度更快,您需要考虑一些其他问题:

  1. 什么是你想要做所有这些数据?
  2. 你真的需要一次加载全部吗?
    • 如果您可以将数据分割成更小的块,那么如果不是所需的总时间,则可以减少程序的延迟。例如,你可能知道你只需要特定文件中的几行特定行就可以进行任何你想要做的分析......太好了!只加载这些特定的行。
    • 如果你要需要以任意和不可预知的方式访问数据,那么你应该加载到另一个系统(RDBMS?),它存储在一个更适合你正在做的分析的格式用它。

如果最后一颗子弹点是真实的,一种选择是每个JSON“文件”加载到一个PostgreSQL 9.3数据库(JSON support is awesomefast),然后从那里你做进一步的分析。希望您可以在加载JSON文档时从中提取有意义的键。