问题描述:
在某一个时刻,电池数据表的以某些规则开头的数据,比如M12******,这些电池一直在上报数据,由于HBase的存储是按照字典顺序排序的,所有某一时刻,相似规则的数据落在了同一个region上,造成了数据热点。
解决方法:
在建表的时候,按照字典顺序,随机生成一批startkey和endkey的集合,这些集合按照字典顺序排列,写入数据的时候,将要写入的【key_时间戳】前面加上哈希前缀,形成【三位哈希值_key_时间戳】方式,将写入数据的压力分散开。
问题描述:
历史数据的消费过程,就是把数据写入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占用过高,最后还是采用固定的数目的线程池,多开几个客户端进行消费;
问题描述:
采用了固定线程池持续运行一段时间之后,观察GC发现:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZD9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVP9ElT3VEVNpGaHJmdRhlW1VTaitmTzkVdjJjYzpkMMZ3bENGMShUYvwFd4VGdvwlMvw1ayFWbyVGdhd3PyITN0QzMyEjM2ATMxcTMwIzLcRXZu5ibkN3Yuc2bsJmLn1Wavw1LcpDc0RHaiojIsJye.jpg)
导出对内存情况观察:
发现有写对象在持续增长,后来观察写入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'}