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 s3 配置单元-动态分区:更新表时加载时间长,分区多_Amazon S3_Hive_Amazon Emr - Fatal编程技术网

Amazon s3 配置单元-动态分区:更新表时加载时间长,分区多

Amazon s3 配置单元-动态分区:更新表时加载时间长,分区多,amazon-s3,hive,amazon-emr,Amazon S3,Hive,Amazon Emr,我通过AWS EMR运行Hive,并有一个作业流,可以频繁地将日志数据解析到S3中。我对解析的配置单元表使用动态分区(日期和日志级别) 当我有几GB的数据和大量的分区时,一件需要花费很长时间的事情是当Hive在解析完成后将数据加载到表中时 Loading data to table default.logs partition (dt=null, level=null) ... Loading partition {dt=2013-08-06, level=INFO} L

我通过AWS EMR运行Hive,并有一个作业流,可以频繁地将日志数据解析到S3中。我对解析的配置单元表使用动态分区(日期和日志级别)

当我有几GB的数据和大量的分区时,一件需要花费很长时间的事情是当Hive在解析完成后将数据加载到表中时

Loading data to table default.logs partition (dt=null, level=null)
    ...
    Loading partition {dt=2013-08-06, level=INFO}
    Loading partition {dt=2013-03-12, level=ERROR}
    Loading partition {dt=2013-08-03, level=WARN}
    Loading partition {dt=2013-07-08, level=INFO}
    Loading partition {dt=2013-08-03, level=ERROR}
    ...

    Partition default.logs{dt=2013-03-05, level=INFO} stats: [num_files: 1, num_rows: 0, total_size: 1905, raw_data_size: 0]
    Partition default.logs{dt=2013-03-06, level=ERROR} stats: [num_files: 1, num_rows: 0, total_size: 4338, raw_data_size: 0]
    Partition default.logs{dt=2013-03-06, level=INFO} stats: [num_files: 1, num_rows: 0, total_size: 828250, raw_data_size: 0]
    ...
    Partition default.logs{dt=2013-08-14, level=INFO} stats: [num_files: 5, num_rows: 0, total_size: 626629, raw_data_size: 0]
    Partition default.logs{dt=2013-08-14, level=WARN} stats: [num_files: 4, num_rows: 0, total_size: 4405, raw_data_size: 0]
是否有办法克服此问题并减少此步骤的加载时间?

我已经尝试通过bucket生命周期规则将旧日志归档到Glacier,希望Hive能够跳过加载归档分区的过程。好吧,因为这仍然使文件(路径)在S3中可见,所以配置单元无论如何都会识别归档分区,因此不会获得性能

更新1

数据的加载是通过简单地将数据插入到动态分区的表中来完成的

INSERT INTO TABLE logs PARTITION (dt, level)
SELECT time, thread, logger, identity, message, logtype, logsubtype, node, storageallocationstatus, nodelist, userid, nodeid, path, datablockid, hash, size, value, exception, server, app, version, dt, level
FROM new_logs ;
从一个包含未解析日志的表中

CREATE EXTERNAL TABLE new_logs (
  dt STRING,
  time STRING,
  thread STRING,
  level STRING,
  logger STRING,
  identity STRING,
  message STRING,
  logtype STRING,
  logsubtype STRING,
  node STRING,
  storageallocationstatus STRING,
  nodelist STRING,
  userid STRING,
  nodeid STRING,
  path STRING,
  datablockid STRING,
  hash STRING,
  size STRING,
  value STRING,
  exception STRING,
  version STRING
)
PARTITIONED BY (
  server STRING,
  app STRING
)
ROW FORMAT
  DELIMITED
  FIELDS TERMINATED BY '\t'
STORED AS
  INPUTFORMAT 'org.maz.hadoop.mapred.LogFileInputFormat'
  OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
LOCATION 's3://my-log/logs/${LOCATION}' ;
进入新的(已解析的)表

输入格式(LogFileInputFormat)负责将日志条目解析为所需的日志格式

更新2

当我尝试以下方法时

INSERT INTO TABLE logs PARTITION (dt, level)
SELECT time, thread, logger, identity, message, logtype, logsubtype, node, storageallocationstatus, nodelist, userid, nodeid, path, datablockid, hash, size, value, exception, server, app, version, dt, level
FROM new_logs
WHERE dt > 'some old date';
配置单元仍然加载日志中的所有分区。另一方面,如果我使用静态分区,比如

INSERT INTO TABLE logs PARTITION (dt='some date', level)
SELECT time, thread, logger, identity, message, logtype, logsubtype, node, storageallocationstatus, nodelist, userid, nodeid, path, datablockid, hash, size, value, exception, server, app, version, level
FROM new_logs
WHERE dt = 'some date';
Hive只加载相关的分区,但是我需要为我认为可能出现在新的_日志中的每个日期创建一个查询。通常新的_日志只包含今天和昨天的日志条目,但也可能包含旧的条目


静态分区是目前我选择的解决方案,但我的问题没有其他(更好的)解决方案吗?

在这个缓慢的阶段,Hive将为每个分区构建的文件从临时目录移动到永久目录。您可以在称为移动操作符的“解释扩展”中看到这一点

因此,对于每个分区,只需对元存储进行一次移动和更新。我不使用EMR,但我认为将文件移动到S3的行为对于需要移动的每个文件都有很高的延迟

从您所写的内容中不清楚的是,您每次运行时是否都在满负荷运行。例如,为什么您有2013-03-05分区?您是否正在获取包含此旧日期的新日志数据?如果此数据已在日志表中,则应修改insert语句,如

SELECT fields
FROM new_logs
WHERE dt > 'date of last run';

这样,您只需要移动几个存储桶和几个文件。从新的\u日志中扫描所有这些额外数据仍然是浪费,但您可以通过对新的\u日志进行分区来解决这一问题。

AWS在EMR 3.2.x及更高版本上将配置单元分区恢复时间提高了一个数量级以上


我们有一个配置单元表,它在S3上有20000多个分区。使用以前版本的EMR,恢复通常需要约80分钟,现在使用3.2.x/3.3.x,我们可以在5分钟内完成

在插入过程中总共有多少个分区受到影响?从日志来看,似乎有一些分区的数据量(总大小)非常小——也许可以使用更大的分区(比如说每月一次的分区)?您到底是如何加载数据的?@dimamah通常只有当前日期受插入过程的影响,因为当日志文件上载到S3时,我会立即解析它。是不是因为我使用动态分区,所以Hive不可能知道在插入过程中哪些分区会受到影响,从而加载每个可用分区?请参阅更新部分。配置单元将只更新受影响的分区,这真的很奇怪,只有在使用动态分区时才会花费很长时间。到底是什么花了很长时间?地图绘制者要运行多长时间?减速器运行多长时间?如果有阶段,请说明每个阶段。是否有长时间运行的特定映射器/还原器?请粘贴它的日志。很棒的东西,我会试试的。插入到日志中的日志几乎总是与当前日期相同的日期(如果解析在午夜后几个小时完成,则可能是昨天),因为新的_日志中的日志条目只包含在最近一个小时左右上载到服务器的日志条目。真正古老的日期是允许查询所有已解析的日志。尝试按日期限制并不能解决我的问题。我发现唯一有效的解决方案是使用静态分区。但这并不是完全可取的,因为我必须在每个日期创建一个查询。如果只有一个问题,我会更高兴。有什么建议吗?
SELECT fields
FROM new_logs
WHERE dt > 'date of last run';