Python 分布式dask中计算NetCDF数据集滚动和的内存问题

Python 分布式dask中计算NetCDF数据集滚动和的内存问题,python,dask,python-xarray,dask-distributed,Python,Dask,Python Xarray,Dask Distributed,我正在开发一个HPC系统(),想对一个大型NetCDF数据集(NCAR大型集合)做一些事情。尽管阅读了Pangeo和dask/dask分发的文档,我还是有记忆错误的问题 我想采取的步骤是: 使用xarray加载一个大型(全球,~1800年的每日数据)多文件数据集。将_mfdataset()打开到dask中 在所有网格点的整个时间维度上进行30天的滚动求和,最好使用分布式dask,因为它的数据量为TB 计算这些30天总和的返回间隔(即,使用指定的百分比值运行numpy.nanpercentile(

我正在开发一个HPC系统(),想对一个大型NetCDF数据集(NCAR大型集合)做一些事情。尽管阅读了Pangeo和dask/dask分发的文档,我还是有记忆错误的问题

我想采取的步骤是:

  • 使用
    xarray加载一个大型(全球,~1800年的每日数据)多文件数据集。将_mfdataset()
    打开到dask中
  • 在所有网格点的整个时间维度上进行30天的滚动求和,最好使用分布式dask,因为它的数据量为TB
  • 计算这些30天总和的返回间隔(即,使用指定的百分比值运行
    numpy.nanpercentile()
    或dask
    DataFrame.quantile()
    函数)
  • 将结果保存为二维(横向x纵向)NetCDF文件
  • 对我来说,能够一次加载任何网格点的完整时间序列非常重要,因为滚动和和返回间隔计算取决于完整时间段。

    下面是我一直试图使用的代码片段(直到上面的第2步)。我在jupyter笔记本中运行它,我已经指定
    $TMPDIR
    作为我的个人临时目录(在这个系统上,
    /glade/scratch/$USER/temp/
    ):

    即使我加载一个文件(不是完整的数据集),上面的最后一行代码看起来也会通过dask仪表板完成,但最终作业会被系统终止。HPC管理员多次发电子邮件说我在登录节点上使用了太多内存,但我已经仔细指定了我的
    $TMPDIR
    本地_目录
    ,我不知道如何解决这个问题

    关于这一点,我有几个问题:

  • 对于这些计算,有没有比我正在采取的步骤更好的方法?(似乎构建一个懒惰的滚动窗口对象,然后调用sum/persist是一个好方法。我也尝试过使用
    scatter()
    和futures,但内存问题仍然存在。)
  • 当我查看我的scratch目录(
    du-hs/glade/scratch/$USER/temp
    )的磁盘使用情况时,在
    sum()
    persist()
    期间,工作人员似乎没有占用任何内存。在这种情况下,内存到底在哪里使用?我有一种感觉,如果我能学会这一点,我就能解决我的问题。
    • 更多信息:
      client.scheduler_info()
      确认已正确设置了我的临时目录,并在其中创建了worker-****文件,但文件夹大小保持固定在32 KB。也许我的想法是关于在
      PBSCluster()
      函数中设置
      local\u目录做什么

  • 这里有几个问题。我将试着为您指出一些好的途径,以供将来阅读:

    • 您的节点可能没有本地存储。tmp目录是RAM或网络文件系统。给任何一方写信都会引起问题。相反您希望Dask工作人员暂停执行,或者在内存不足时自杀。这将使您的IT人员更加快乐。有关这方面的更多信息,请参见:

    • 要找出占用内存的内容,可以查看仪表板。这在progressbars(纯色而非透明色)和每个工人的信息页面中都很明显。这个页面上有一个youtube视频

    • 您可能还需要查看
      mfds\u data\u 30day\u rolling\u object.sum()
      对象的总字节数,以确保在内存中持久化是合理的。Xarray文档可能在这方面有所帮助


      • 这里有几个问题。我将试着为您指出一些好的途径,以供将来阅读:

        • 您的节点可能没有本地存储。tmp目录是RAM或网络文件系统。给任何一方写信都会引起问题。相反您希望Dask工作人员暂停执行,或者在内存不足时自杀。这将使您的IT人员更加快乐。有关这方面的更多信息,请参见:

        • 要找出占用内存的内容,可以查看仪表板。这在progressbars(纯色而非透明色)和每个工人的信息页面中都很明显。这个页面上有一个youtube视频

        • 您可能还需要查看
          mfds\u data\u 30day\u rolling\u object.sum()
          对象的总字节数,以确保在内存中持久化是合理的。Xarray文档可能在这方面有所帮助


        您能否添加
        mfds\U数据的
        repr
        ?您不需要调用
        client.persist
        。您是否能够观看分布式仪表板?您是否能够判断工作人员在某个时候是否特别内存紧张?能否添加
        mfds_数据的
        repr
        ?您不需要调用
        client.persist
        。您是否能够观看分布式仪表板?你能判断员工是否在某个时候特别有记忆压力吗?
        import xarray
        import dask_jobqueue
        import dask.distributed
        import glob
        
        ## specify location of precipitation files, use glob to get list of them
        PRECT_root = '/glade/collections/cdg/data/cesmLE/CESM-CAM5-BGC-LE/atm/proc/tseries/daily/PRECT/'
        filename_list = sorted(glob.glob(PRECT_root + 'b.e11.B1850C5CN.f09_g16.005.cam.h1.PRECT.*.nc'))
        
        ## import multi-file data set
        mfds = xarray.open_mfdataset(filename_list, chunks={'lat':12, 'lon':12})
        mfds_data = mfds['PRECT']
        
        ## start cluster object
        cluster = dask_jobqueue.PBSCluster(cores=36, memory='100 GB', project='UCLA0022', queue='regular', walltime='06:00:00', local_directory='/glade/scratch/$USER/temp/')
        
        ## create 30 workers (I've tried up to 70)
        cluster.start_workers(30)
        
        ## attach client
        client = dask.distributed.Client(cluster)
        
        ## create a rolling 30-day sum
        mfds_data_30day_rolling_object = mfds_data.rolling(time=30, center=True)
        mfds_data_30day_rolling_sum = client.persist(mfds_data_30day_rolling_object.sum())