寻找hive数据倾斜路

前言

  一直以来我都是从书上、博客上、别人口中听说数据倾斜,自己也从而指导一些解决数据倾斜的方式或者一些容易出现数据倾斜的场景。但是从来没有认真的去发现过,寻求过,研究过。

 

正文

  我打开了hive官网 点开了 document文档 然后呢,一个一个的去找倾斜的地方,找了一会儿发现了一个地方,看到了一个词skew,没错这个就是倾斜的意思,Skewed Join Optimization于是我就跟着进去了,那么我先不管三七二十一解读一下吧!

  The problem

  首先是两个大表的join通过mr作业的集合来基于key对他们进行表排序后再join他们。Mapper给全部的行指定一个特定的key然后到下游相同的reducer。

  e.g:假设我们有一个A表又一列“id“字段,有值1,2,3,4;然后B表也有这么一列,有值1,2,3。

    select A.id from A join B on A.id = B.id 

  Mapper去读取表基于key去分组然后发给相应下游的reducer。例如:行数据 key是1的会发送R1,2的发到Reducer R2 如此这样。这些reducer会跨越从A表和B表生成值,然后写出去。R4从A获取,但是不会生成任何结果。因为B没有4.

  现在我们假设A表的1倾斜特别高。R2和R3会完成的很快但是R1要持续一段时间,这样就成了瓶颈。如果用户有关于倾斜的信息,瓶颈可以通过以下方式来避免:

  执行两个不受影响的查询:

    select A.id from A join B on  A.id = B.id where A.id <> 1;

    select A.id from A join B on  A.id = B.id where A.id = 1 and B.id = 1;

  这样第一个查询语句就不会产生任何倾斜了,因此所有的reducer就会在大约相同的时间完成。如果我们假设B有很少的B.id = 1的数据,然后他会被写到内存中。因此join可以提高很高的性能通过把B的值存储在内存哈希表中。这种方式,join可以完成通过mapper自己数据就不需要到reducer计算了。两个查询的部分结果就可以合并获取到最终的结果了。很精妙啊,之前从来没来官网看这个地方。今天的目的也是为了帮助工作中一些仓库同学有时候作业慢如何解决而产生的一个念头,确实还是有收获的。

    优势:

      其实优势已经很明显了,如果key倾斜小数量弥补了数据的大部分,那么就不会成为瓶颈了。

    劣势:

      AB表不得不读取处理两次

      因为部分结果,从而不得不读取写入两次

      用户必须有意识的去发现数据中的倾斜并且需要手动去处理以上过程

  我们可以提高这种情况通过尝试减少数据倾斜的过程。首先读取B并且存储key=1在内存哈希表。现在mapper读取A然后如下操作:

    如果他有key 1,那么用哈希B去计算结果

    对于其他的key,发送到reducer。

  这种方式,我们最后只读B两次。A中的倾斜值只是读取和处理在mapper中,不会发送到reducer。剩下的A的key仅在一个单独的mr。

  这种场景是,假设B的倾斜的数据只是很少可以被存储在内存中,倾斜的数据是大部分在A中。

 

  hive增强

  实现:在Hive0.10.0,表创建可以作为倾斜方式或者我们可以修改为倾斜表。此外,倾斜表可以列表块特征通过指定存储方式为DIRECTORIES选项。更详细的DDL查看:Create TableSkewed Tables, and Alter Table Skewed or Stored as Directories.

      看吧,应不是这一个地方,后面都是倾斜的document。那就接着打开看,我们在创建表的时候,可以通过指定某几个字段值来说明,我们标志这几个是倾斜的值。

    CREATE TABLE list_bucket_single (key STRING, value STRING)

       SKEWED BY (key) ON (1,5,6) [STORED AS DIRECTORIES];
 
  我们也可以指定多个字段来作为倾斜:
  
      CREATE TABLE list_bucket_multiple (col1 STRING, col2 int, col3 STRING)
      SKEWED BY (col1, col2) ON (('s1',1), ('s3',3), ('s13',13), ('s78',78)) [STORED AS DIRECTORIES];

  我们也可以修改table为倾斜表

      ALTER TABLE table_name SKEWED BY (col_name1, col_name2, ...)
      ON ([(col_name1_value, col_name2_value, ...) [, (col_name1_value, col_name2_value), ...]
      [STORED AS DIRECTORIES];

      禁止倾斜

    ALTER TABLE table_name NOT SKEWED; 

    

结尾

  好吧,就这样吧。这算自己主动学习了一下,有时候具体业务还需要具体来分析表的数据。

 

 

      be sure to practive     

posted @ 2020-06-24 11:48  xiaoyon  阅读(347)  评论(0编辑  收藏  举报