【问题标题】:Retrieve million records in batches from Apache Hive - Java 8 + Spring Boot + Hive 1.2.1 version从Apache Hive批量检索百万条记录-Java 8 + Spring Boot + Hive 1.2.1版本
【发布时间】:2021-01-04 10:24:22
【问题描述】:

我需要从 Hive 中检索 1000 万行。

String sql = 从表名中选择 *

List<Map<String, Object>> resultSet = jdbctemplate.queryForList(String sql)

上述方法运行良好,可以一次检索 100 万行(单次命中),使用 2GB 堆内存。从 30 MB(100 万行)大小的表中选择记录只需 3-4 分钟。

但是对于超过 100 万条记录,存在内存问题,并且需要更多时间。

我需要用 OFFSET 值查询 Hive,但是对于 1.2.1 版本,似乎没有 OFFSET 子句。

还有其他方法可以从 Hive 中批量选择记录吗?像这样选择前 10K 条记录和接下来的 10K 条记录?

【问题讨论】:

  • 你不关心性能?一次 100 万行? ??????????
  • @dm_tr 是的,性能很重要,但在此之前,我需要在最坏的情况下检索所有记录而不会出现问题。
  • 简单的程序员关心他们的代码(他们只需要它运行)。优秀的程序员关心数据结构、性能和平滑度。加油队长

标签: java spring-boot hive


【解决方案1】:

如果您有一些可以按顺序使用的候选主键(可以是列列表),那么您可以使用 row_number():

select --column list here
from (
    select t.*, row_number() OVER (ORDER by PK) as rn --use PK in order by
    from table_name t
    ) s
where rn between 1000001 and 2000000

只需检查您的候选 PK 是否唯一且不为空,因为如果 PK 不唯一或可以为空,则 row_number 可能具有不确定的行为,并且每次运行可能会产生不同的结果。

而且如果你没有PK,这个功能是无法实现的,因为Hive可能会因为并行执行而返回不同顺序的行,这会导致跨批次的行重复,可能会丢失一些行。

【讨论】:

  • @dm_tr 看来你不知道这个问题。谢谢。
  • @dm_tr 必要时处理 1M 行有什么问题?性能是另一个非功能性要求。问题不在于这里的性能。 Apache Hive 适用于大数据。 1M 行不算大
  • 解决方案似乎不错。由于我们无法确定每个表的 PK,这将很难实现。如果 Hive 升级了,我们可以使用 Offset 作为select * from table limit 0,100
【解决方案2】:

如果每行都有某种独特的递增 id,则此解决方案应该可以工作。

获取唯一id的最小值和最大值。然后分批从最小值中选择10000个,你会达到最大值。

同样的逻辑可以应用于时间戳字段,您可以从一天的开始到一天结束,以 15 分钟或 1 小时或任何适合您的批处理要求的批次进行。如果数据不是非常偏斜,这将起作用。

如果你想使用 jdbc 模板,你可以使用 RowCallbackHandler 或 ResultSetExtractor 作为参数。

要设置结果集一次获取的行数,覆盖 applyStatementSettings() 并调用 Statement.setFetchSize()

您可以在此处阅读有关它的更多信息。

https://docs.spring.io/spring-framework/docs/3.1.x/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

【讨论】:

  • 感谢您的建议。我已经尝试过使用 setFetchSize。我认为可能有一些功能(我可能不知道)可以使用它。
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2011-11-29
  • 2012-05-30
  • 1970-01-01
  • 2017-12-01
  • 2020-09-23
  • 1970-01-01
相关资源
最近更新 更多