再分享一下关于Hive元数据的一些经验教训。
组件: Hive数据数据分区过多的问题
版本: CentOS 5/ CDH3u4 hive 0.7
问题:Hive数据分区过多导致用户作业提交太慢!
问题原因以及解决方案:Hive元数据保存在MySQL的数据库中,相信很多同学也都是这样做的,当然这样做一点问题都没有。但是当表中分区信息过多的时候,会导致用户提交作业时,MySQL的查询效率会成为瓶颈,甚至会影响到Hive语句的正常执行。从另一个角度看,这实际上是一个设计上的问题,也是一个权衡的问题——数据存储的粒度与执行效率之间。
对于HDFS来说,不建议有太多的小文件存储,如果有巨量的小文件,不仅仅会占据NameNode的内存空间,而且也会在DataNode上占用更多的内存空间,这时其一;其次,对于一个MapReduce作业来说,假如我们需要操作的数据是一天的数据,我们肯定希望此作业只会涉及到这一天的数据,而不是这一天所在的那一周的全部数据以期获得理想的执行效率。因此就要仔细考虑分区字段的设计问题,考虑到避免存储太多的小文件,我们希望存储粒度大一些;考虑到MR作业的IO效率,我们又希望降低数据的存储粒度。此时就应该对自己的业务模型有一个深入的理解,才能做出合适的决策。
从我们的经验看,当拥有400w个数据分区的时候,MySQL元数据存储在内存为24GB,CPU为16核心的服务器上已经成为瓶颈,以致我们将元数据库转移到一个具有64GB和24核心CPU的服务器上之后,才能从一定程度上解决作业提交过慢的问题。当然,MySQL的瓶颈主要是在IO层面上。
在升级硬件配置之后,对于MySQL的优化,主要涉及以下三个参数,核心的目标就是——减少磁盘IO过程,多利用内存:
innodb_buffer_pool_size=16384MB # innodb缓存数据占用内存大小上限
max_heap_table_size=522715200 # 和下一个一起起作用
tmp_table_size=335544320 # 数据量超过这个大小的时候,tmp table的数据就要向磁盘写入,将默认值35M扩大10倍至350MB。
再次,这是一个数据粒度的设计问题,MySQL服务器的升级和配置优化只是权宜之计,我们已经计划对数据结构做一次较大的调整,以期从根本上解决这个问题。将这个分享出来,希望对后来的同学有些帮助!