HDFS3+Hbase2的异构存储
记录一下1SSD + 2HDD
(One_SSD) 策略在HDFS3 + Hbase2
的环境中如何使用, 暂不涉及异构实现的原理和细节
此文作为后面的选DN/选盘分析的铺垫, 先放出来, 后续会补上源码分析, 以及相关改动考虑
0x00. 简介
1. 基本模式
异构存储(Heterogeneous Storage
)简单说是很好理解的, 因为分布式系统里一般都有多个副本存储数据, 实际就造成了大量的数据冗余, 如果所有数据都用某种高速存储介质成本太高, 都用低速存储性能太差, 大家希望有一种组合模式, 把使用的数据放高速, 副本的数据放低速存储.
其实感觉也是某种意义上的冷热分离 , 把热数据用更快的介质存储(内存/Flash卡/SSD), 冷数据用HDD存储, 分为几种存储介质:
异构存储(Heterogeneous Storage), 其实我觉得也是某种意义上的冷热分离 (在读多写少的场景下), 把热数据用更快的介质存储(内存/Flash卡/SSD), 冷数据用HDD存储, 分为几种存储介质:
- RAM_Disk: 内存类极高速存储.
- SSD : 一般指固态硬盘存储 (注意仍然是抽象. 比如Flash卡, 傲腾这种新硬件也算)
- Disk : 磁盘, 一般指HDD这类低速存储
- Archive : 归档存储(比如历史数据), 代表抽象的冷存储.
对应可以理解为以下的图:
目前HDFS3.x版本支持以下组合模式:
- Hot(默认策略) :热数据模式, 当出现热块, 所有的副本都存储在磁盘 (Disk, 默认代表HDD这类)
- Cold : 冷数据模式, 所有冷数据块副本存储在
Archive
中. - Warm : 中和模式, 冷热比较均匀的块部分存Disk, 部分存Archive.
- All_SSD : 所有数据都存SSD
- One_SSD : 1副本存SSD(通常是优先访问). 其他副本存Disk.
- Lazy_Persist : 1副本写内存, 然后延时写入Disk (比较危险?)
2. 关注点
我们重点关注的是One_SSD
模式, 并检验是否符合我们的预期:
- 设置完成后, Hbase是否读都走了SSD (或者绝大部分走的SSD)
- SSD的
IOPS
不是瓶颈的时候, Hbase的随机读瓶颈在哪. (并发? 读延时?) - 如果某块SSD坏了, 此时访问数据会自动降级到HDD么? 后台会修补这块SSD缺失的数据么 (不会, 需要手动用mover)
- HDFS的balance策略, 会影响到
ONE_SSD
么 (会, 这里后续需要改HDFS代码, 并研究磁盘间的balance策略)
0x02. 具体使用
1. 降级策略
这里是官方给出的几个异构策略的解释表:
策略ID | 策略名 | 块存储 (n副本) | 数据降级存储^1^ | 副本降级存储^2^ |
---|---|---|---|---|
10 | One_SSD | 1SSD + (n-1) DISK | SSD, DISK | SSD, DISK |
12 | All_SSD | n * SSD | DISK | DISK |
15 | Lazy_Persist | 1RAM + (n-1)DISK | DISK | DISK |
- ^1^理解的是如果SSD上写入数据失败, 则降级为写HDD (这里降级为SSD应该是说一台节点SSD1失败, 优先尝试写SSD2么, 下同)
- ^2^理解的是如果SSD上写入副本失败, 则降级为写HDD, 不过还是没搞清楚数据降级和副本降级的区别? (待源码确定)
2. 相关配置
首先配置一下磁盘的异构存储. 修改hdfs-site.xml
中dfs.datanode.data.dir
项的值. (通常在/path/to/hadoop3/etc/hadoop/
下)
1 | <!-- 假设我们有2SSD盘,4HDD盘,配置为1:2 --> |
然后, 再使用storagepolicies -setStoragePolicy
命令来指定具体的存储策略, 并且指定A目录的策略后, 它的子孙目录也会默认继承A目录的策略, 常用方式:
1 | # 1.1显示某目录当前策略 |
3. 副本策略
先引用一下之前HDFS默认的副本存放策略, 以常见的1份数据, 3份副本为例. 参考ibm文章
一般情况下
replic
为 3. HDFS 的副本放置策略是:优先将第一个副本写本地节点,将第二个副本放到本地机架上的另外一个节点,而将第三个副本放到不同机架上的节点。这种方式减少了机架间的写流量,从而提高了写的性能。机架故障的几率远小于节点故障。这种方式并不影响数据可靠性和可用性的限制,并且它确实减少了读操作的网络聚合带宽,因为文件块仅存在两个不同的机架,而不是三个。文件的副本不是均匀地分布在机架当中,1副本在同一个节点上,1副本在同一个机架上,另外1副本均匀地分布在其他机架上。这种方式提高了写的性能,并且不影响数据的可靠性和读性能
注意: 高版本(HDFS3)的默认放置策略有所不同, 当然没啥本质变化倒是, 之后在Namenode选DN的篇章会单独说, 这里了解即可.
确认当前的文件写到了本机SSD, 副本放在其他的HDD上了
1 | #fsck命令确定block |
4. 记线上的一次升级问题 (可略)
问题描述:
在线上HDFS3+Hbase2升级版本的一次意外操作之后, Hbase存储hfile的目录的存储策略都被修改为了HOT
(期望是ONE_SSD
), 但是其他的文件夹和它们的父目录都是ONE_SSD
的.
问题背景:
那次升级的时候因为配置SSD的path
有误, 导致了一些情况, 虽然不一定和这个问题相关, 也一并记录一下:
- 升级时每台机器的4块SSD盘被摘了3个
- HDFS的版本从
3.0
升级到了3.1.2
- 升级时Hbase出现过启动失败的情况, 具体原因不确定(日志过期)
- 升级完成后, SSD空间不足, 所以我
unset
了/home/hbase/data
的策略. 只指定单独的几张表 (之前是所有) - 修改策略之后, 使用了
mover
工具, 对/home/hbase/data
进行了实际数据搬运 - 搬运完发现所有设置
ONE_SSD
的hbase表, 它们的hfile
存储的文件夹策略都莫名变成了HOT
(导致数据都被从SSD中搬走)
问题尝试:
在给父目录设置策略的时候, 为什么有些子目录没有继承, 按照期望应该是, 普通的目录是没有设置的状态(unset), 那么默认是HOT, 但是实际测试中发现给/path/parent
设置了ONE_SSD
策略, 它的子目录会比如/path/parent/child/xx
会出现HOT的策略, 导致实际文件被错误搬运. 这是什么情况呢
这里先从HDFS本身的情况开始分析, 做了以下测试, 都符合预期:
- 创建一个多级目录的文件夹, 写入文件A, 只对父目录设置存储策略
ONE_SSD
, 文件应该自动继承 (√) - 创建另一个文件夹, 设置为
HOT
策略, 写入文件B, 然后通过cp
或mv
命令移动到A所在目录, 期望新移入的文件也是ONE_SSD
(√) - 执行mover命令前, fsck查看A/B文件的磁盘, 期望全DISK, 使用mover后, 期望有一个SSD (√)
unsetStoragePolicy
命令如果设置给父目录, 那么子目录应该也变为unset
状态 (而不是HOT
) (√)
验证如下:
1 | # 1.1 新建一个目录. 创建一个空文件 |
结论是目前除了发现问题结果比较特殊, 只有hfile的目录被设置为了HOT
, 其他因日志缺失, 升级操作偏多导致不好分析, 搜了下也没有相关issue
, 先记录一下, 方便以后参考
0x03. 实际测试
1 | # 1.清除OS的page缓存 |
0x04. 其他
下面是图相关的性能监测, 和HDFS异构没有直接关系, 只是测试下换SSD后的实际提升, 后续这部分会移动到单独图的性能分析文章.
当loader线程过大时(比如100) , 会出现不少Broken-pipe, 并且从server来看, 发送请求就少了很多. 说明server或loader本身没有成功处理这么多请求, 并发送给Hbase, 我们采取的思路用Arthas
在Loader & Client这里做一次监听, 在Server的入口处做一次监听, 看看到底是以下哪种情况:
- Loader就没有成功把请求发送给Server, 中途就中断了
- Server接收到了过多的请求, 或者是HTTP框架的有界队列满了. 以至于来不及相应处理.
1 | # 1.loader端 |