Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services 如何在AWS Athena中自动执行MSCK修复表_Amazon Web Services_Amazon S3_Hive_Amazon Athena_Amazon Quicksight - Fatal编程技术网

Amazon web services 如何在AWS Athena中自动执行MSCK修复表

Amazon web services 如何在AWS Athena中自动执行MSCK修复表,amazon-web-services,amazon-s3,hive,amazon-athena,amazon-quicksight,Amazon Web Services,Amazon S3,Hive,Amazon Athena,Amazon Quicksight,我有一个火花批作业,每小时执行一次。每次运行都会使用目录命名模式data/YEAR=?/MONTH=?/DATE=?/datafile在S3中生成并存储新数据 将数据上传到S3后,我想使用Athena对其进行调查。另外,我想通过连接到雅典娜作为数据源,在QuickSight中将它们可视化 问题是,在每次运行Spark批处理后,雅典娜不会发现存储在S3中的新生成数据,除非我手动运行查询MSCK修复表 有没有办法让雅典娜自动更新数据,这样我就可以创建一个全自动的数据可视化管道?有很多方法可以安排这项

我有一个火花批作业,每小时执行一次。每次运行都会使用目录命名模式
data/YEAR=?/MONTH=?/DATE=?/datafile
S3
中生成并存储新数据

将数据上传到
S3
后,我想使用
Athena
对其进行调查。另外,我想通过连接到雅典娜作为数据源,在
QuickSight
中将它们可视化

问题是,在每次运行Spark批处理后,雅典娜不会发现存储在
S3
中的新生成数据,除非我手动运行查询
MSCK修复表


有没有办法让雅典娜自动更新数据,这样我就可以创建一个全自动的数据可视化管道?

有很多方法可以安排这项任务。你如何安排你的工作流程?您是使用诸如、cron之类的系统,还是使用

从这些命令中,您应该能够触发以下CLI命令

$aws athena开始查询执行--查询字符串“MSCK修复表某些数据库.某些表”--结果配置“OutputLocation=s3://SOMEPLACE”

另一个选择是。您可以使用一个函数调用MSCK REPAIR TABLE some_database.some_TABLE,以响应到S3的新上载

示例Lambda函数可以这样编写:

import boto3

def lambda_handler(event, context):
    bucket_name = 'some_bucket'

    client = boto3.client('athena')

    config = {
        'OutputLocation': 's3://' + bucket_name + '/',
        'EncryptionConfiguration': {'EncryptionOption': 'SSE_S3'}

    }

    # Query Execution Parameters
    sql = 'MSCK REPAIR TABLE some_database.some_table'
    context = {'Database': 'some_database'}

    client.start_query_execution(QueryString = sql, 
                                 QueryExecutionContext = context,
                                 ResultConfiguration = config)
然后,当在bucket中的
data/
前缀下添加新数据时,您将配置一个触发器来执行Lambda函数


最终,在使用作业调度器运行Spark作业后显式地重建分区具有自文档化的优势。另一方面,AWS Lambda对这样的工作很方便

您应该运行
添加分区

aws athena start-query-execution --query-string "ALTER TABLE ADD PARTITION..."
它从
S3
位置向新创建的分区添加一个 Athena利用配置单元对数据进行分区。
要创建带有分区的表,必须在
createtable
语句中定义它。使用
分区依据
定义分区数据所依据的键。

有多种方法可以解决此问题并更新表:

  • 调用MSCK维修表。这将扫描所有数据。它的成本很高,因为每个文件都是完全读取的(至少AWS完全收取了费用)。而且速度非常慢。简言之:不要这样做

  • 通过调用
    altertable ADD PARTITION abc…
    自己创建分区。这在某种意义上是好的,因为不需要扫描数据,成本也很低。而且查询速度很快,所以这里没有问题。如果您的文件结构非常混乱,没有任何公共模式(在您的示例中,这似乎不是一种情况,因为它是一种组织良好的S3密钥模式),那么它也是一个不错的选择这种方法也有缺点:A)很难维护B)所有分区都将存储在GLUE目录中。当您有很多分区时,这可能会成为一个问题,因为它们需要读取并传递给Athenas和EMRs Hadoop基础设施

  • 使用分区投影。您可能需要评估两种不同的样式。以下是在查询时为Hadoop创建分区的变体。这意味着没有胶水目录条目通过网络发送,因此可以更快地处理大量分区。缺点是您可能会“命中”一些可能不存在的分区。这些当然会被忽略,但在内部,所有可能与您的查询匹配的分区都会被生成——不管它们是否在S3上(所以总是在您的查询中添加分区过滤器!)。如果操作正确,则此选项是一种免责方法,因为不需要更新

  • 仅列出所有选项:您还可以使用
    胶水爬虫
    。但这似乎不是一个有利的方法,因为它不像宣传的那样灵活

  • 直接使用
    GLUE Data Catalog API
    可以更好地控制GLUE,如果有大量自动化脚本,这可能是#2方法的替代方法 完成设置表格的准备工作

  • 简言之:

    • 如果您的应用程序是以SQL为中心的,您喜欢没有脚本的最精简的方法,请使用分区投影
    • 如果有许多分区,请使用分区投影
    • 如果您有几个分区或分区没有通用模式,请使用方法#2
    • <> LI>如果你的脚本重,脚本做了大部分的工作,并且更容易处理,考虑方法5</LI>。
    • 如果您感到困惑并且不知道从哪里开始-请先尝试分区投影!它应该适合95%的用例

    我认为另一种可能性是在胶水脚本中使用boto。您应该能够使用来执行相关的
    MSCK REPAIR TABLE
    命令。我使用了一个定时AWS爬虫程序对数据库进行爬网以更新表。你对这个解决方案有什么看法?那是可行的。使用Lambda函数的好处在于Lambda可以动态响应事件,例如在Athena的情况下向S3添加文件。Lambda函数的缺点是,从持续集成和版本控制的角度来看,它们的管理可能会有些混乱。在这种情况下,Lambda的另一个缺点是它的执行必须在5分钟内完成,这可能是修复表的缩写(但对于添加分区来说已经足够了)关于这个问题的任何想法都不确定,如果你使用消防水带将数据放入雅典娜水桶中,这是可能的。即使使用“动态”分区,您仍然需要指定分区:-(@RalphBolton使用Firehose登录时,您也可以使用分区投影。请参见我的答案。@samuel_liew问题并不宽泛,它只是为问题的上下文提供了一些额外的信息。这可能无关紧要
    CREATE EXTERNAL TABLE `mydb`.`mytable`
    (
       ...
    )
      PARTITIONED BY (
        `YEAR` int,
        `MONTH` int,
        `DATE` int)
      ...
      LOCATION
        's3://DATA/'
      TBLPROPERTIES(
          "projection.enabled" = "true",
          "projection.account.type" = "integer",
          "projection.account.range" = "1,50",
          "projection.YEAR.type" = "integer",
          "projection.YEAR.range" = "2020,2025",
          "projection.MONTH.type" = "integer",
          "projection.MONTH.range" = "1,12",
          "projection.DATE.type" = "integer",
          "projection.DATE.range" = "1,31",
          "storage.location.template" = "s3://DATA/YEAR=${YEAR}/MONTH=${MONTH}/DATE=${DATE}/"
      );