消息消费轨迹存储效率优化

背景

消息队列是业务中常用的中间件,除了消息收发等核心流程以外,对历史消息轨迹的跟踪查询也非常重要。如果没有历史消息查询,那么一旦出了问题将很难进行定位。

公司使用的消息队列中间件为qmq,和其它消息队列中间件类似,qmq的主要组件包括meta server(提供集群管理和集群发现的作用),server(提供实时消息服务),producer(消息生产者),consumer(消息消费者)。在消息的收发过程中,消息都存储在Server端,为了提供高吞吐的消息收发服务,server是以顺序日志的形式存储消息的,这种格式并不利于消息的检索。为了提供历史消息的查询服务,qmq专门有一个backup模块进行历史消息的备份和查询,为了减少历史消息备份的数据大小,backup仅仅从server slave中同步消息的索引而非完整的消息内容;然后backup将索引保存到hbase中。这样,backup便可从HBase中查询出对应的消息索引并据此读到具体的消息内容。具体如下图:

1.png

1.png

现状

现在公司的backup将消息索引写入HBase采用的是调用HBase Client的PUT API的方式,每次批量写入若干条消息(默认是1000条消息索引),然而这种方式写入效率比较低下。当需要写入HBase的消息索引数据量特别大时,写入一次批量的消息索引需要2-3秒(公司HBase的服务器配置较低),消息备份的延迟可能有几个小时甚至是几天。导致无法及时地从HBase中查询到对应的历史消息,无法满足现有业务的需求。有鉴于此,我们需要尝试提升backup将消息索引写入HBase的速度。

寻找数据写入HBase效率低下的原因

为了了解数据是如何写入HBase的,我们首先大致了解一下HBase的架构:

在HBase集群中,真正负责读写数据的是一个个的Region Server,而每个Region Server又管理着多个region。

一个region中存储的是同一张HBase表的数据,每个region包含一个或多个Store,每个Store对应HBase表的一个列簇(Column Family)。

Store由MemStore 和 StoreFile 组成,MemStore是写缓存,在内存中存储着还未被持久化到硬盘的数据,当MemStore满之后,会被flush到StoreFile中,StoreFile对应一个实际的HFile 格式的文件。

HLog即Write Ahead Log(WAL),记录着每个Region Server的数据操作日志,用来做故障恢复。

在了解了HBase的基本架构之后,我们可以继续了解一下向HBase中写入数据的普通方式,即我们目前使用的方式。一般向HBase中写入数据最直接的方式是调用HBase的API用put方法插入数据,其流程大致如下:

2.png

2.png

Client调用API写入数据到HBase实际上都是RPC请求,HMaster会将Client写入数据的请求分发到对应的Region Server。

写入的数据传输到Region Server后,会先写入到HLog即Write Ahead Log(WAL)中,然后再将数据写入到对应region的MemStore中,当MemStore满之后,才会被flush到StoreFile中,flush会耗费较多的I/O资源。

HBase还可能会触发split和compaction操作。当存在较多的小HFile文件时,会触发compaction操作,将多个小文件合并成大文件,以减少HFile的文件数量。当region过大时会触发split操作,将其分裂成两个子region。

在有大数据量写入时这种写入数据的方式效率会比较低下,因为会频繁的进行写WAL、flush操作,耗费较多的磁盘I/O。

如何提升HBase写入效率

调用HBase Client的PUT API的方式写数据效率低下,那我们能不能找到一种更加高效的写数据的方式呢?正如上面所介绍的,HBase的底层存储是使用的HFile文件格式。当有大量数据需要写入HBase时,如果我们能够批量将数据直接写成HFile文件,然后直接导入到HBase是不是就可以提高写入速度呢?经过学习,我们发现HBase提供了一种Bulk Load的API。

Bulk Load 直接将数据输出成 HBase table 内部的存储格式,即HFile文件,然后将生成的 HFile 加载到集群的相应节点。这种方式无需进行写WAL、flush等过程,不会产生大量的写入 I/O,所以需要较少的 CPU 和网络资源。使用Bulk Load批量加载数据,能极大的提高写入效率,并降低对 Region Server 节点的写入压力。

Bulk Load批量导入数据的具体实现

下面我们便通过简单示例介绍一下如何通过Bulk Load 将数据导入HBase中。

准备

首先需要提前部署好HBase以及HDFS服务,在HBase中建好相应的表,例如:

create 'bltable','cf'

实现

在HBase中,Bulk Load主要的过程包括:从其它数据源导出数据,比如简单的文本文件或者是其它数据库;将数据转换成HFile形式;将生成的HFile导入到HBase特定的region中。实现Bulk Load可以借助ImportTsv和CompleteBulkLoad工具或者是通过编程的方式,这里我们主要讲述通过编程实现的方式。通过编程实现Bulk Load将数据导入HBase具体也有两种方式,分别为MapReduce方式和非MapReduce方式。

MapRedu

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值