1.HBase数据热点问题
在某一个时刻,电池数据表的以某些规则开头的数据,比如M12******,这些电池一直在上报数据,由于HBase的存储是按照字典顺序排序的,所有某一时刻,相似规则的数据落在了同一个region上,造成了数据热点。
我们采取的是rowkey散列+预分区的方式:http://student-lp.iteye.com/blog/2309075
在建表的时候,按照字典顺序,随机生成一批startkey和endkey的集合,这些集合按照字典顺序排列,写入数据的时候,将要写入的【key_时间戳】前面加上哈希前缀,形成【三位哈希值_key_时间戳】方式,将写入数据的压力分散开。
2.HBase插入数据过慢问题
历史数据的消费过程,就是把数据写入HBase的过程,但是写入HBase过慢,容易造成消费不过来,产生数据堆积,由于数据堆积,会影响Kafka拉取数据消费发送心跳的超时。
1, HBase写操作尽量采用批量写入操作;
2, 禁用预写日志:put.setDurability(Durability.SKIP_WAL);//禁用hbase的预写日志功能(但是禁用预写日志的方式不够安全)
3, 禁止autoflush:table.setAutoFlushTo(false); 并配置write buff:
<property>
<name>hbase.client.write.buffer</name>
<value>5000000</value>
</property>
4,消费过程采用线程池写入:最开始用的可回收线程池,但是观察GC发现,FGC太多,而且数据量大了,CUP占用过高,最后还是采用固定的数目的线程池,多开几个客户端进行消费;
3.HBase分区过多问题
采用了固定线程池持续运行一段时间之后,观察GC发现:
导出对内存情况观察:
发现有写对象在持续增长,后来观察写入HBase的监控,发现Hbase每秒写入数据操作在0.001次这样子,通过对象分析,发现线程池在执行任务时候,会有个LinkedBlockingQueue的队列,由于HBase写入阻塞,导致队列持续递增,FGC持续进行,判断问题处在了HBase上面。
观察HBase目前配置:memstore:256M,hbase.hregion.max.filesize:10G (一个region最多管理10G的HFile),当写入的数据总量超过一定数量(1T)时,写入速度变慢。写入方式rowkey前加hash。
能源站对表预建了20个Region,随着数据量膨胀分裂到了160个
由于写入方式是完全随机写入到各个region中,因为region数量过多,大量时间浪费在等待region释放资源,获取region连接,释放连接。。
车联网的某些表虽然也有100多个region。但是由于写入的数据不是完全随机的,所以每次都是client只连接一个region去写,所以压测时没出现此问题。
解决方案:
禁用表的自动分期策略,如果日后有需要,手动分区。
alter'batteryData',{METADATA=>{'SPLIT_POLICY'=>'org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy'}},{NAME=> 't'}