HBase使用难点

Row key 设计

团队在使用HBase之前一直使用MySQL关系型数据库,在系统设计之初并没有考虑HBase的特性,而是按照关系型数据库的设计原则设计。经过一段时间的了解后才知道HBase主要使用Row key进行数据查询。Row key的设计至关重要。 目前系统中设计的Row key如下

  • 设备ID + 时间戳:此种方式可以快速定位单台车辆。但是由于设备ID前缀为型号,一旦某批次的设备或车辆发送故障,则会造成HBase的某个Region写入压力过大。
  • subString(MD5(设备ID),x) + 设备ID + 时间戳:此种方式可以将所有车辆打散到每个Region中,避免热点数据和数据倾斜问题,式中的x一般取5左右。但对于某个型号的车辆查询就只能够每台车辆单独进行查询了。
  • 复杂查询问题

    虽然通过Row key的设计可以解决部分数据查询的需求,但是在面对复杂需求时难以通过Row key 直接索引到数据,若索引无法命中,则只能进行大范围或全表扫描才能够定位数据。所以我们在使用HBase时尽量避免复杂的查询需求。但业务方面仍然会有部分较为复杂的查询需求。针对这些需求,我们主要使用两种方式来建立二级索引。

  • 手动在事务产生时将索引写入到HBase表中:使用这种方式建立索引虽然可以不借用第三方插件,但是事务的原子性很难得到保障,业务代码也会因为索引的变化而难以维护。另外索引的管理也较为麻烦,后期的数据迁移很难能够。
  • 通过Phoenix构建索引:通过Phoenix构建索引可以避免事务原子性问题,另外也可以通过重建索引来进行数据迁移。因为使用的SQL语句,开发人员更能够利用之前关系型数据库的设计经验建立数据索引。
  • 目前新能源监控系统中主要使用Phoenix实现二级索引,大大增加了数据的查询使用场景。

    虽然Phoenix能够通过二级索引实现较为复杂的数据查询,但对于更为复杂的查询与分析需求就显得捉襟见肘。所以我们选用了Spark等其他数据分析组件对数据进行离线分析,分析后对结果通过接口提供给用户。

    多语言连接问题

    团队使用Python语言构建系统,但HBase使用Java语言编写,原生提供了Java API,并未对Python语言提供直接的API。我们使用happybase连接HBase,因为它提供了更为Pythonic的接口服务。另外我们也是用QueryServer 作为Python组件和Phoenix连接的纽带。

    HBase冷数据存储

    系统中车辆数据分为热数据和冷数据,热数据需要HBase中实时可查,冷数据虽不需要实时可查,但却需要一直保存在磁盘中。阿里云HBase支持将冷数据直接存储在OSS中,而这些数据的转存只需要简单的设置表相关属性,操作非常简单。将冷数据存储在OSS之中大大减少了数据的存储成本。

    总结

    首先,本文介绍了新能源车辆监控系统的项目背景,随后分析了本项目的项目难点,并介绍了我们团队的各种解决方案。针对项目需求,介绍了我们选择HBase的原因,及在HBase数据库使用过程中的经验和痛点。

    展望

    未来,我们会在系统接入大量车辆后,使用golang重写高性能组件以满足后期的并发性能需求。由于项目初期考虑到开发时间的问题,并未采用服务拆分的方式进行开发,这限制了系统的可扩展性,后期我们会根据实际业务需求,将系统切分成相对独立的模块,增强扩展性可维护性。
    另外,车辆数据积累到一定程度后,我们可以利用这些数据进行大数据分析, 如车辆的故障诊断,车辆状态预测等,这样就可以在车辆出现问题前提前发出预警,为车主和保险公司避免更大的损失,降低运营成本。

    本博客文章除特别声明,全部都是原创!
    原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
    本文链接: 【HBase在新能源汽车监控系统中的应用】(https://www.iteblog.com/archives/2466.html)
    喜欢 (16)
    分享 (0)
    发表我的评论
    取消评论

    表情
    本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!
    (2)个小伙伴在吐槽
    1. Spark消费kafka使用的是streaming还是struct streaming呢

      Celebrate Ubuntu2018-12-16 22:14 回复
    2. 是使用 streaming 的

      w3970907702019-02-20 12:34 回复