移动云使用 JuiceFS 支持 Apache HBase 增效降本的探索
作者简介:
陈海峰,移动云数据库 Apache HBase 开发人员,对 Apache HBase、RBF、Apache Spark 有浓厚兴趣。
背景
Apache HBase 是 Apache Hadoop 生态体系中的大规模、可扩展、分布式的数据存储服务。同时它还是 NoSQL 数据库。它的设计初衷是为包含了数百万列的数十亿行记录提供随机的、强一致性的实时查询。默认情况下,HBase 的数据会保存在 HDFS 上,HBase 为 HDFS 做了很多优化来保证稳定性与性能。但是维护 HDFS 本身一点也不轻松,要不断进行监控、运维、调优、扩容、灾难恢复等一系列事情,而且在公有云上搭建 HDFS 的费用也是相当高的。为了节省费用、降低维护成本,一些用户使用 S3(或其他对象存储)存储 HBase 的数据。使用 S3 省去了监控运维的麻烦,同时还实现了存储计算分离,让 HBase 的扩容缩容都变得更加容易。
然而,HBase 数据接入对象存储却不是一件容易的事儿。对象存储一方面因为自身特性,功能和性能有限,一旦数据被写入对象存储后,数据对象即不可改变,另一方面使用文件系统语义访问块存储有天然局限性。在使用 Hadoop 原生的 AWS 客户端来访问对象存储时,目录重命名操作会遍历整个目录下文件进行拷贝和删除,性能非常低下。另外重命名操作也会导致原子性问题,即原本的重命名操作分解为拷贝和删除两个操作,在极端情况下易产生用户数据视图不一致情况。类似的还有查询目录所有文件的总大小,原理是通过遍历迭代依次获取某个目录的所有文件信息。如果目录下的子目录和文件数量庞大的话,查询目录所有文件总大小复杂度更大,性能更差。
方案选型
经过大量方案调研和社区问题跟踪,目前云 HBase 数据接入对象存储有三种方案。
第一种是 HBase 使用 Hadoop 原生 AWS 客户端来访问对象存储,即 S3AFileSystem。HBase 内核代码只需要稍加改动即可使用 S3AFileSystem。这种 HBase 直接对接对象存储的方案一个需要解决的痛点问题,即目录的 rename。HBase 在 Hlog 文件管理、MemStore Flush、表创建、region compaction 和 region split 时都会涉及目录的 rename。社区对 StoreFIle 进行了优化,解决了一部分的 rename 性能问题。完全解决目录操作性能问题需要对 HBase 内核源码进行大刀阔斧地变动。
第二个方案是引入 Alluxio 作为缓存加速,不仅大大提升读写性能,而且引入文件元数据管理,彻底解决了目录操作性能低下问题。看似圆满的结局,背后却有很多限制条件。当 Alluxio 配置仅仅使用内存时,对目录操作耗时才是 ms 级别。如果配置 Alluxio 的 UFS,Alluxio 中的元数据操作有两个步骤:第一步是修改 Alluxio master 的状态,第二步是向 UFS 发送请求。可以看到,元数据操作仍然不是原子的,当操作正在执行或发生任何故障时,其状态是不可预测的。Alluxio 依赖 UFS 来实现元数据操作,比如重命名文件操作会变成复制和删除操作。HBase 中数据必定是需要落盘的,Alluxio 解决不了目录操作性能问题。
第三种方案是在 HBase 与对象存储之间引入 JuiceFS 共享文件系统。使用 JuiceFS 存储数据,数据本身会被持久化在对象存储(例如,移动云 EOS),相对应的元数据可以按需持久化在 Redis、MySQL 等多种数据库中。此方案中对目录操作完成是在 Metadata Engine 中完成,与对象存储无交互,操作耗时在 ms 级别,可以解决 HBase 数据接入对象存储的痛点问题。但是由于 JuiceFS 内核采用 Go 语言编写,对后期性能调优和日常维护带来一定挑战。
权衡上述三个方案利弊,最终采用 JuiceFS 作为云 HBase 支持对象存储的解决方案。下面着重讨论 JuiceFS 在云 HBase 支持对象存储中的实践以及性能调优。
方案介绍
首先介绍下 JuiceFS 的架构。JuiceFS 由两个主要部分组成:JuiceFS 元数据(Metadata)服务和对象存储。JuiceFS Java SDK 完全兼容 HDFS API,同时也提供基于 FUSE 的客户端挂载,完全兼容 POSIX。作为文件系统,JuiceFS 会分别处理数据及其对应的元数据,数据会被存储在对象存储中,元数据会被存储在元数据引擎中。在数据存储方面,JuiceFS 支持几乎所有的公有云对象存储,同时也支持 OpenStack Swift、Ceph、MinIO 等支持私有化部署的开源对象存储。在元数据存储方面,JuiceFS 采用多引擎设计,目前已支持 Redis、TiKV、MySQL/MariaDB、PostgreSQL、SQLite 等作为元数据服务引擎。
任何存入 JuiceFS 的文件都会被拆分成固定大小的 "Chunk",默认的容量上限是 64 MiB。每个 Chunk 由一个或多个 "Slice" 组成,Slice 的长度不固定,取决于文件写入的方式。每个 Slice 又会被进一步拆分成固定大小的 "Block",默认为 4 MiB。最后,这些 Block 会被存储到对象存储。与此同时,JuiceFS 会将每个文件以及它的 Chunks、Slices、Blocks 等元数据信息存储在元数据引擎中。
使用 JuiceFS,文件最终会被拆分成 Chunks、Slices 和 Blocks 存储在对象存储。因此,对象存储平台中找不到存入 JuiceFS 的源文件,存储桶中只有一个 chunks 目录和一堆数字编号的目录和文件。
HBase 组件使用 JuiceFS 需要以下配置。首先将编译好的客户端 SDK 置于 HBase classpath 内。其次将 JuiceFS 相关配置写入配置文件 core-site.xml,如下表所示。最后使用 juicefs 客户端格式化文件系统。
配置项 | 默认值 | 描述 |
---|---|---|
fs.jfs.impl | io.juicefs.JuiceFileSystem | 指定要使用的存储实现,默认使用 jfs:// |
fs.AbstractFileSystem.jfs.impl | io.juicefs.JuiceFS | |
juicefs.meta | 指定预先创建好的 JuiceFS 文件系统的元数据引擎地址。 |
在元数据存储方面,使用 MySQL 作为元数据存储。格式化文件系统命令如下。可见,格式化文件系统需要提供以下信息:
--storage
:设置存储类型,比如移动云 EOS;--bucket
:设置对象存储的 Endpoint 地址;--access-key
:设置对象存储 API 访问密钥 Access Key ID;--secret-key
:设置对象存储 API 访问密钥 Access Key Secret。
juicefs format --storage eos \
--bucket https://myjfs.eos-wuxi-1.cmecloud.cn \
--access-key ABCDEFGHIJKLMNopqXYZ \
--secret-key ZYXwvutsrqpoNMLkJiHgfeDCBA \
mysql://username:password@(ip:port)/database NAME
方案验证与优化
介绍完 Juicefs 使用方法后,开始进行测试工作。测试环境中选用了一台 48 核、187G 内存的服务器。在 HBase 集群中,分别有一个 HMaster、一个 RegionServer 和三个 zookeeper。在 Meta data engine 选用主从复制的三节点 MySQL。对象存储则使用移动云对象存储 EOS,网络策略走公网。Juicefs 配置 chunk 大小为 64M,物理存储块大小为 4M,无 cache,MEM 使用 300M。我们搭建了两套 HBase 集群,一套是 HBase 直接落盘到移动云对象存储上,另一套是在 HBase 和移动云对象存储之间引入 Juicefs。顺序写和随机读是 HBase 集群两个关键性能指标,使用 PE 测试工具测试这两个性能指标。测试读写性能如下表所示。
集群环境
集群环境 HBase-juicefs-EOS (row/s) | 集群环境 HBase-EOS (row/s) | |
---|---|---|
顺序写 | 79465 | 33343 |
随机读 | 6698 | 6476 |
根据测试结果,采用 Juicefs 方案,集群顺序写性能提升非常明显,随机读性能却没有提升。究其原因,写请求写入 Client 内存缓冲区即可返回,因此通常来说 JuiceFS 的 Write 时延非常低(几十微秒级别)。JuiceFS 在处理读请求时,一般会按照 4M Block 对齐的方式去对象存储读取,实现一定的预读功能,同时,读取到的数据会写入本地 Cache 目录,以备后用。在顺序读时,这些提前获取的数据都会被后续的请求访问到,Cache 命中率非常高,因此也能充分发挥出对象存储的读取性能。但是在随机读取时,JuiceFS 的预先缓存效率不高,反而会因为读放大和本地 Cache 的频繁写入与驱逐使得系统资源的实际利用率降低。
为了提升随机读性能,两个方向可以考虑。一个是尽可能提升缓存的整体容量,以期达到能几乎完全缓存所需数据的效果,在海量数据的使用场景下,这个优化方向不太可行。另一个方向是深耕 JuiceFS 内核,优化读数据逻辑。
目前我们所做的优化包括:1)关闭预读机制和缓存功能,简化读数据逻辑;2)尽可能避免缓存整个块数据,更多地使用 Range HTTP 请求数据;3)设置较小的 block 大小;4)尽可能提高对象存储的读取性能。经研发环境测试,经优化后随机读性能提升大约 70%。
结合前期测试工作,云 HBase 在使用对象存储作为底层数据存储系统后,在获得与数据存储在 HDFS 差不多读写性能基础上,用户花费却只有数据存储在 HDFS 的一半以下,由此可以看出云 HBase 支持对象存储是鱼与熊掌兼得的一次研发实践。
如有帮助的话欢迎关注我们项目 Juicedata/JuiceFS 哟! (0ᴗ0✿)
移动云使用 JuiceFS 支持 Apache HBase 增效降本的探索的更多相关文章
- 【HBase学习】Apache HBase项目简介
原创声明:转载请注明作者和原始链接 http://www.cnblogs.com/zhangningbo/p/4068957.html 英文原版:http://hbase.apache.o ...
- GoldenGate实时投递数据到大数据平台(7)– Apache Hbase
Apache Hbase安装及运行 安装hbase1.4,确保在这之前hadoop是正常运行的.设置相应的环境变量, export HADOOP_HOME=/u01/hadoop export HBA ...
- How-to: Enable User Authentication and Authorization in Apache HBase
With the default Apache HBase configuration, everyone is allowed to read from and write to all table ...
- Apache HBase RPC身份验证中间人安全措施绕过漏洞(CVE-2013-2193)
漏洞版本: Apache Group HBase 0.94.x Apache Group HBase 0.92.x 漏洞描述: BUGTRAQ ID: 61981 CVE(CAN) ID: CVE-2 ...
- The Apache HBase™ Reference Guide
以下内容由http://hbase.apache.org/book.html#getting_started节选并改编而来. 运行环境:hadoop-1.0.4,hbase-0.94.22,jdk1. ...
- Apache HBase Performance Tuning 官文总结
Apache HBase Performance Tuning RAM, RAM, RAM. 不要让HBase饿死. 请使用64位的平台 必须将swapping设定为0 使用本地硬件来完成hdfs的c ...
- Apache HBase 集群安装文档
简介: Apache HBase 是一个分布式的.面向列的开源 NoSQL 数据库.具有高性能.高可靠性.可伸缩.面向列.分布式存储的特性. HBase 的数据文件最终落地在 HDFS 之上,所以在 ...
- hadoop版本与支持的hbase版本对照…
hadoop版本与支持的hbase版本对照表 分类: hbase2013-05-20 17:19 701人阅读 评论(2) 收藏 举报 HbaseHadoop As of Hive 0.9.0 the ...
- Use Apache HBase™ when you need random, realtime read/write access to your Big Data.
Apache HBase™ is the Hadoop database, a distributed, scalable, big data store. Use Apache HBase™ whe ...
随机推荐
- tf.test.is_gpu_available() 返回结果为False解决办法
安装完gpu版本的tensorflow,导入正常,但是tf.test.is_gpu_available()一直返回False,解决办法: 1.打开NVIDIA控制面板,查看CUDA的驱动版本,如果版本 ...
- JSTL详解(常用标签以及c:forEach遍历集合)
JSTL标签 一. JSTL的简介 1. 什么是JSTL 2. JSTL常用标签库 3. JSTL使用步骤 二. 核心标签库常用标签 1. c: set 标签 2. c: out 标签 3. c: i ...
- EMS查看邮箱容量限制的方法
以Exchange管理员身份打开EMS控制台.在PowerShell命令行提示符下,输入以下命令. Get-MailboxDatabase | FL name,IssueWarningQuota,Pr ...
- 浅谈一下流式处理平台Flink
浅谈一下流式处理平台(Flink) 大数据框架听过很多,比如 Hadoop,HDFS...不过自己的项目都没有上过 为什么突然提到 Flink,因为最近一个项目需要用到,所以学习最好的方式就是项目驱动 ...
- Android实现秒开效果
0x01 创建SplashActivity 新建一个Activity,取名为SplashActivity 0x02 新建资源 在res/drawable下新建一个splash.xml文件和名为ig_s ...
- 安装 UE 源码版
# 安装 UE 源码版 ## 下载安装包 > - 先去 Github 找 UE 官方开源的引擎组(这个需要申请加入) > - 加入后找到开源的源码版项目下载 zip 到本地 > - ...
- 新手小白入门C语言第二章:基本语法
1. 语句 C 语言的代码由一行行语句(statement)组成.语句就是程序执行的一个操作命令.C 语言规定,语句必须使用分号结尾,除非有明确规定可以不写分号. 如: int x = 1; 这就是一 ...
- 1903021116—吉琛—Java第三周作业—eclipse创建Java程序
项目 内容 课程班级博客链接 19级信计班 这个作业要求链接 eclipse如何创建java程序 java语言基础(上) 我的课程学习目标 1. 学习博客园更多使用技巧 2. 通过作业实践熟练与熟悉掌 ...
- IDEA小技巧:Debug时如何优雅地制造异常?
抛异常相信大家都会吧?只需要这样就可以了: throw new RuntimeException("didispace.com"); 但是,在开发过程中有一些情况,我们需要测试程序 ...
- 国产化之 .NET Core 操作达梦数据库DM8的两种方式
背景 某个项目需要实现基础软件全部国产化,其中操作系统指定银河麒麟,数据库使用达梦V8,CPU平台的范围包括x64.龙芯.飞腾.鲲鹏等.考虑到这些基础产品对.NET的支持,最终选择了.NET Core ...