实战:如何基于HBase构建图片、 视频数据的统一存储检索方案

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
简介: 作者:天贺

背景介绍


(一)需求情景


老板提出一个紧急需求,下周交付:


·我有非常多的文件需要存储,以图片和短视频为主,以后还会有更多;

·每一个图片或者视频都会有很多的标签信息,我需要通过标签能快速的找到我想要的文件,要求操作流程简单,不需要其它多余操作;

·需要尽量节省资源。


和目标客户交流:

·小王最近接收了一个图片模型训练的项目,需要线上批量拉取某种标签的图片进行模型训练,比如美食、房屋,图片大小为20K~10M;

·小李是短视频推荐系统的研发,需要一个可以存储和通过标签检索短视频的服务,短视频文件大小为200k ~ 200MB,RT不敏感,吞吐量要求TPS 100+,QPS 200+,保存数据2个月以上。


(二)需求分析 用户到底想要什么?


图片、视频统一存储检索系统,提供图片、视频文件的存储、检索服务(需要注意的是我们往往会给图片或者视频打上很多的标签,比如:美食、房屋等等,这里提及的检索是根据标签进行检索),数据大多都是小文件(80%大小在数MB以内),数据体量大,增长快速等特点。


根据以上信息,我们得出以下功能需求:

1)图片或者视频数据作为单独的对象存储到一个大容器中;

2)应用可以通过标签查询来获取每个单独的对象数据(图片或者视频);

3)支持海量数据,高性能,可扩展,高可用。


基于以上需求,我们如何设计一个图片视频统一存储检索系统?


图片视频统一存储检索系统设计


(一)技术选型


在技术选型方面,我们最终选择HBase。


HBase的优势:

1)HBase 可以很好地支持非结构化的数据存储,且基于HDFS保证数据的可靠性;

2)HBase 吞吐量非常高,足够支撑业务;
3)HBase 基于Hadoop集群,不需要重新维护其他数据存储服务。


对于我们的需求,HBase有哪些不足之处:

1)HBase 对小文件(小于10MB)支持很好,但是对于较大的文件无法满足;

2)由于HBase的设计,HBase会发生Compact和Split操作,文件存储会频繁的触发此类的操作导致写放大等不良的影响;

3)HBase不适合复杂的检索操作,功能上可能会有限制。


针对以上问题,我们该如何来弥补这些不足呢?


大文件存储方案

方案一:将大文件分片存储在HBase中,例如100M的文件,我们可以以每片1M分成100个,然后存储在HBase的表里面。但是这个方案对后期的一些实现,比如查询、整合,可能需要一些比较复杂的设计来保证整个流程是可行的。

方案二:将大文件直接存储到HDFS中,HBase中只存储图片或者视频的元数据以及标签信息。这个方案既避免把一个文件拆分成多个,而且可以充分利用底层的HDFS来保证整体数据的可靠性。


基于第二个方案,我们设计了如下技术架构图。

image001.png

如上图所示,用户直接将数据写入到统一文件服务,然后统一文件服务进行判断,如果它 一个大于10M的数据,那么直接将数据存储在HDFS当中,而其它的一些比如文件的Meta信息和标签信息,则统一存储在HBase当中。


如果是小于10M的一些文件,那么我们可以直接将文件存储在HBase当中。


第二个问题是复查查询支持:

1)HBase 本身根据字典排查,我们可以将一些较为固定的标签设计在 Rowkey中,以便满足我们常规查询的需要;

2)如果系统需要支持更加灵活的检索功能,我们也可以引入Phoenix 来构建二级索引或者ElasticSearch来满足我们的检索功能。


(二)需求分析


我们选择上方的方案二来构建统一存储检索系统,整体架构图如下所示。

image002.png

该项目是一个Spring Boot的项目,主要提供Rest API和SDK两种接口,支持以下功能:

1)Bucket的创建,删除,查询等接口;

2)上传文件,查询文件内容以及基本的信息;

3)根据标签信息查询获取文件信息以及文件的具体内容。


在数据存储上,每一个 Bucket 对应 HBase 的一张表,对于小文件(我们将所有小于2MB的文件定义为小文件,而大于2M的文件者称为较大文件)直接存储在HBase的表中,而大于2MB文件我们存储在HDFS中,并且将文件的Meta信息存储在HBase的表中。


额外说明:

1)在下面的实践项目中,我们只是简单的实现其中的部分功能,针对于服务本身的高可用和SDK等功能并不加以实现。

2)对于检索功能而言也只是实现一些简单的检索功能。


图片视频统一存储检索系统编码实践


(一)准备工作


接下来我们看一下应该做哪些前期工作。

image003.png

如上所示,首先需要购买HBase增强版的服务,然后在用户的控制台详情里面去获取HBase的一些链接信息。


接着我们需要配置集群,开通公网,获取连接配置,还有本机一些白名单的东西,最后是开发环境的配置。


(二)HBase 表结构设计

image004.png

说明:

1)为了能够支持检索功能,我们在RowKey的设计上采用 BucketName+标签+key 的方式,通过这种方式,可以使用HBase前缀扫描的方式找到在一个特定bucket下标签为tag_1的数据。

2)在数据存储上,我们存储了文件名,文件大小,文件创建时间和过期时间,还有它Bucket的名称。Content主要分为两块,第一个是追对小文件,会直接将数据存储在HBase当中,而针对于大文件,在Content里面是文件存在HDFS的路径。

3)虽然这种设计可以满足我们检索的功能,但是这种设计只能应用在一些标签相对比较固定的场景,而且会存在数据的热点问题。

4)该设计对于删除操作不友好,因为我们在RowKey前面加了一些其他信息,所以在删除的时候,我们需要先获取完整 的信息包括标签信息,单考虑到删除操作并不多,所以该设计在一定程度上还是可以满足我们的需求。


(三)项目目录介绍


这个项目主要有以下几个目录。

image005.png

其中,common目录包含:
1)公用层,包括工具类和基础的bean类;

2)Controller层,对外提供的API接口;

3)Service层,核心处理逻辑,包括对HBase和HDFS操作的封装类等。


(四)Service 层


接下来我们看一下当用户上传一个文件的时候,服务端这边的处理流程。

image006.png

服务端收到图片或者是视频文件的时候,首先会在HBase中存储Meta信息, 接着判断文件的大小是否超过长度限制: 1)如果长度没有超过限制,那么我们会将文件的内容直接存储在HBase表 中的fc:_content 2)如果长度超过了限制,那么我们先将文件写入到HDFS的特定的文件夹中,接着将文件的路径存储在fc:_content 当数据存储之后,用户如果要通过某一个标签进行查询,具体流程如下。

image007.png

当服务端接收到查询请求,会根据容器名称和标签进行模糊查询, 获取文件的Mate信息,接着根据文件的长度进行判断:


1)如果长度小于存放HBase的阈值,说明文件是存储在HBase中的,直接从HBase中获取,整合数据之后返回给用户。

2)如果长度大于存储HBase的阈值,说明文件是存储在HDFS中,需要根据cf:content中存储的文件路径从HDFS中获取文件信息,组装完成之后返回给用户。


(五)效果演示

image008.png

创建容器

image009.png

查询容器

image010.png

上传带有标签的图片(小图片)

image011.png

上传一个50MB的大文件(代替视频文件)

image012.png

根据标签查询文件


总结


虽然我们基本已经完成了老板交待的任务,项目也正常上线,但是从设计上来说,我们依旧遗留两个问题:

1)RowKey的热点问题,因为我们是将容器名称和标签作为前缀,那么当存储的文件达到一定程度之后势必会导致热点,影响HBase的稳定性。

2)无法支持复杂的查询,并且由于用于查询条件的标签是开始就固定在RowKey当中的,所以之后如果想扩展标签的维度势必会非常困难。


那么针对上面的两个问题,我们应该如何解决呢?

其实上面的两个问题,都是由于我们将RowKey作为查询的依据而产生的问题,那么我们是否可以将查询所使用到的字段不存储在RowKey上,这样我们就可以使用一个随机的RowKey避免热点问题,答案是肯定的。


下面介绍两种比较常见的开源方案。

方案一:使用HBase + Phoenix 的方案,创建容器名称和标签作为二级索引,查询通过Phoenix对二级索引进行加速。通过这种方式,我们可以支持更多字段的查询,而且后期在扩展的时候,我们只要添加更多的二级索引,就可以通过其他标签进行查询。


方案二:使用HBase + ElasticSearch 方案,索引信息通过 hbase-indexer 服务将标签同步到ES 中,查询的时候先查询ES,通过标签获取HBase明细表里的RowKey信息,再从HBase中获取明细数据。通过这种方式,我们可以支持更多更复杂的查询条件。


是否有更好的方案?


阿里巴巴Lindorm多模引擎集成了宽表,时序,搜索还有文件系统,完全可以支持这种统一存储,而且通过它的Solr的功能,可以为我们提供一些更好的复杂查询来满足各种需求。

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
缓存 监控 Shell
如何使用 HBase Shell 进行数据的实时监控和备份?
如何使用 HBase Shell 进行数据的实时监控和备份?
|
1月前
|
Shell 分布式数据库 Hbase
如何使用 HBase Shell 进行数据的批量导入和导出?
如何使用 HBase Shell 进行数据的批量导入和导出?
|
5月前
|
存储 分布式数据库 数据库
Hbase学习二:Hbase数据特点和架构特点
Hbase学习二:Hbase数据特点和架构特点
93 0
|
2月前
|
存储 监控 分布式数据库
百亿级存储架构: ElasticSearch+HBase 海量存储架构与实现
本文介绍了百亿级数据存储架构的设计与实现,重点探讨了ElasticSearch和HBase的结合使用。通过ElasticSearch实现快速检索,HBase实现海量数据存储,解决了大规模数据的高效存储与查询问题。文章详细讲解了数据统一接入、元数据管理、数据一致性及平台监控等关键模块的设计思路和技术细节,帮助读者理解和掌握构建高性能数据存储系统的方法。
百亿级存储架构: ElasticSearch+HBase 海量存储架构与实现
|
4月前
|
分布式计算 大数据 分布式数据库
"揭秘HBase MapReduce高效数据处理秘诀:四步实战攻略,让你轻松玩转大数据分析!"
【8月更文挑战第17天】大数据时代,HBase以高性能、可扩展性成为关键的数据存储解决方案。结合MapReduce分布式计算框架,能高效处理HBase中的大规模数据。本文通过实例展示如何配置HBase集群、编写Map和Reduce函数,以及运行MapReduce作业来计算HBase某列的平均值。此过程不仅限于简单的统计分析,还可扩展至更复杂的数据处理任务,为企业提供强有力的大数据技术支持。
86 1
|
5月前
|
缓存 监控 Shell
使用 HBase Shell 进行数据的实时监控和备份
使用 HBase Shell 进行数据的实时监控和备份
100 6
|
4月前
|
存储 分布式计算 分布式数据库
《HBase MapReduce之旅:我的学习笔记与心得》——跟随我的步伐,一同探索HBase世界,揭开MapReduce的神秘面纱,分享那些挑战与收获,让你在数据的海洋里畅游无阻!
【8月更文挑战第17天】HBase是Apache顶级项目,作为Bigtable的开源版,它是一个非关系型、分布式数据库,具备高可扩展性和性能。结合HDFS存储和MapReduce计算框架,以及Zookeeper协同服务,HBase支持海量数据高效管理。MapReduce通过将任务拆解并在集群上并行执行,极大提升处理速度。学习HBase MapReduce涉及理解其数据模型、编程模型及应用实践,虽然充满挑战,但收获颇丰,对职业发展大有裨益。
58 0
|
3月前
|
分布式计算 Java Hadoop
java使用hbase、hadoop报错举例
java使用hbase、hadoop报错举例
122 4
|
2月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
87 4
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
39 3