【问题标题】:How to read/write/sync data on cloud with Kedro如何使用 Kedro 在云上读取/写入/同步数据
【发布时间】:2021-07-19 21:23:28
【问题描述】:

简而言之:如何在本地和云端保存文件,同样如何设置为从本地读取。

详细描述:有两种场景,1)构建模型 2)通过 API 服务模型。在构建模型时,会进行一系列分析以生成特征和模型。结果将写入本地。最后,所有内容都将上传到 S3。为了提供数据,首先将下载第一步生成的所有必需文件。

我很好奇如何在这里利用 Kedro。也许我可以为每个文件conf/base/catalog.yml 定义两个条目,一个对应于本地版本,第二个对应于 S3。但当我处理 20 个文件时,这可能不是最有效的方法。

或者,我可以使用自己的脚本将文件上传到 S3 并排除 Kedro 的同步!换句话说,Kedro 对云上存在副本这一事实视而不见。也许这种方法不是对 Kedro 最友好的方法。

【问题讨论】:

    标签: kedro


    【解决方案1】:

    不太一样,但我的回答 here 可能有用。

    我建议在您的情况下,最简单的方法确实是定义两个目录条目并将 Kedro 保存到这两个条目(并从本地加载以提高速度),这为您提供了最大的灵活性,尽管我承认不是最漂亮的。

    就避免所有需要返回两个值的节点函数而言,我建议将装饰器应用于您使用特定标签标记的某些节点,例如 tags=["s3_replica"] 从以下脚本中获取灵感(从同事那里窃取我的):

    class S3DataReplicationHook:
        """
        Hook to replicate the output of any node tagged with `s3_replica` to S3.
    
        E.g. if a node is defined as:
            node(
                func=myfunction,
                inputs=['ds1', 'ds2'],
                outputs=['ds3', 'ds4'],
                tags=['tag1', 's3_replica']
            )
    
        Then the hook will expect to see `ds3.s3` and `ds4.s3` in the catalog.
        """
    
        @hook_impl
        def before_node_run(
            self,
            node: Node,
            catalog: DataCatalog,
            inputs: Dict[str, Any],
            is_async: bool,
            run_id: str,
        ) -> None:
            if "s3_replica" in node.tags:
                node.func = _duplicate_outputs(node.func)
                node.outputs = _add_local_s3_outputs(node.outputs)
    
    
    def _duplicate_outputs(func: Callable) -> Callable:
        def wrapped(*args, **kwargs):
            outputs = func(*args, **kwargs)
            return (outputs,) + (outputs,)
    
        return wrapped
    
    
    def _add_local_s3_outputs(outputs: List[str]) -> List[str]:
        return outputs + [f'{o}.s3' for o in outputs] 
    

    上面是一个钩子,所以你可以把它放在你项目中的hooks.py文件(或任何你想要的地方)中,然后将它导入你的settings.py文件并放入:

    from .hooks import ProjectHooks, S3DataReplicationHook
    
    hooks = (ProjectHooks(), S3DataReplicatonHook())
    

    在你的settings.py。

    您可以稍微巧妙地使用输出命名约定,使其仅复制某些输出(例如,也许您同意所有以 .local 结尾的目录条目也必须具有相应的 .s3 条目并且您进行了变异你的node 的outputs 相应地在那个钩子中,而不是对每个输出都这样做。

    如果您想更聪明一点,您可以使用 after_catalog_created 挂钩将相应的 S3 条目注入目录,而不是再次按照您的命名约定在目录中手动编写数据集的 S3 版本选择。虽然我认为从长远来看,编写 S3 条目更具可读性。

    【讨论】:

      【解决方案2】:

      我能想到的方法有两种。一种更简单的方法是对云和本地都使用--env conf。 https://kedro.readthedocs.io/en/latest/04_kedro_project_setup/02_configuration.html#additional-configuration-environments

      conf
      ├── base
      │   └── 
      ├── cloud
      │   └── catalog.yml
      └── my_local_env
          └── catalog.yml
      

      您可以调用kedro run --env=cloud 或kedro run --env=my_local,具体取决于您要使用的环境。

      另一种更高级的方法是使用 TemplatedConfigLoader https://kedro.readthedocs.io/en/stable/kedro.config.TemplatedConfigLoader.html

      conf
      ├── base
      │   └── catalog.yml
      ├── cloud
      │   └── globals.yml (contains `base_path:s3-prefix-path`)
      └── my_local
          └── globals.yml (contains `base_path:my_local_path`)
      

      在catalog.yml,可以这样引用base_path

      my_dataset:
          filepath: s3:${base_path}/my_dataset
      

      您可以调用kedro run --env=cloud 或kedro run --env=my_local,具体取决于您要使用的环境。

      【讨论】:

      • 谢谢 - 太好了 - 但我仍然缺少的是如何在本地和 S3 上保存输出 - 所以如果我使用 --env=my_local 运行模型,我应该如何在 S3 上上传结果?
      猜你喜欢
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      相关资源
      最近更新 更多