1.本文说明
笔者最近一年从事维护Hbase相关工作,总结相关文章用于阐述对于Hbase的部分理解,本文知识点来源于
《HBase原理与实践》第三章
2.Hbase依赖服务
2.1 正常的依赖
至少依赖ZK、HDFS,特殊场景,如Copy SnapShot和验证集群间数据一致性,需要借助YARN集群的分布式计算能力
2.2 ZK简介
- ZK之所以占据如此重要的地位,是因为它解决了分布式系统中一些最基础的问题
1.提供极低延迟、超高可用的内存KV数据库服务
2.提供中心化的服务故障发现服务
3.提供分布式场景下的锁、Counter、Queue等协调服务 - ZK核心特性
1.多类型节点,ZK数据树节点可以设置多种节点类型,每种节点类型具有不同节点特性。
2.Watcher机制,该机制是ZK实现的一种时间异步反馈机制,就像现实生活中某读者订阅了某个主题,这个主题一旦有任何更新都会第一时间反馈给该读者一样。
3.Session机制,ZK启动时,客户端会根据配置文件中ZK服务器列表配置项,选择其中任意一台服务器相连,如果连接失败,会尝试连接另一台服务器,直到与一台服务器成功创建连接或因为ZK服务器都不可用而失败。
ZK对于网络连接断开和Session过期是两种处理机制。
客户端与服务端之间维持一个长链接,在Session超时时间内,服务端会不断检测该客户端是否还处于正常连接,服务端会将客户端的每次操作视为一次有效的心跳检测来反复地进行Session激活。因此,在正常情况下,客户端Session是一直有效的。
当客户端与服务端之间的连接断开后,用户在客户端可能主要看到:CONNECTION_LOSS和SESSION_EXPIRED 两类异常。 - CONNECTION_LOSS
网络一旦断连,客户端就会收到CONNECTION_LOSS异常,此时它会自动从ZK服务器列表中重新选择去新的地址,并尝试重新连接,知道最终成功连上服务器。 - SESSION_EXPIRED
客户端与服务端断开连接后,如果重连时间耗时太长,超过了Session超时时间,服务器会进行Session清理,此时客户端不知道Session已经失效,状态还是DISCONNECTED,如果客户端重新连上了服务器,此时状态会变更为SESSION_EXPIRED。 -
ZK典型使用场景
HBASE使用ZK实现了Master的高可用管理,RS宕机异常检测、分布式锁等一些列功能
分布式锁的具体实现步骤
- Hbase中ZK的重要配置
1.hbase.zookpeer.quorum
zk集群地址,必须进行配置
2.hbase.zookpeer.property.clientport
zk集群端口,可以不进行配置
3.zookeeper.znode.parent
hbase的位置
4.zookeeper.session.timeout
rs与zk会话超时时间 -
ZK存储信息
2.3 HDFS简介
HDFS本质上是一个分布式文件系统,可以部署在大量廉价的服务器上,提供可扩展的、高容错性的文件读写服务。
Hbase项目本身并不负责文件侧面的高可用和扩展性,它通过把数据存储在HDFS上来实现大容量文件存储和文件备份。
HDFS擅长的场景是大文件的顺序读、随机读和顺序写。
- HDFS高可用服务
NN、DN、JN、ZKFC -
架构图如下:
-
文件写入流程
- 步骤1:
DFS Client 在创建FSDataOutputStream时,把文件元数据发给NN,得到一个文件唯一表示的field,并向用户返回一个OutputStream - 步骤2:
用户拿到OutPutStream之后,开始写数据。注意写数据都是按照Block来写的,不同的Block可能分布在不同的DN上,因此如果发现当前的Block已经写满,DFSClient就需要再发起请求向NN申请一个新的Block,在一个Block内部,数据由若干个Packet组成,若当前的Packet写满了,就放入DataQueue队列,DataStreamer线程异步地把Packet写入到对应的DN。3个副本中的某个DN收到Packet之后,会先写本地文件,然后发送一份到第2个DN,第2个执行类似步骤后,发给第3个DN。等待所有的DN都写完数据之后,就发送Packet的ACK给DFS Client,只有收到ACK的Packet才是写入成功的。 - 步骤3:
用户执行完写入操作后,需要关闭OutPutStream,关闭过程中,DFSClient会先把本地DataQueue中未发出去的Packet全部发送到DN,若忘记关闭,对那些已经成功缓存在DFS Client的DataQueue中,但尚未成功写入DN的数据,就没机会写入DataNode中。 - FsDataOutputStream中的hflush和hsync的区别
hflush成功返回,则表示DFSClient的DataQueue中所有Packet都已经成功发送到了3个DN上,但是对每个DN而言,数据仍然可能存放在操作系统的Cache上,若存在至少一个正常运行的DN,则数据不会丢失。
hsync成功返回,则表示DFSClient DataQueue中的Packet不但成功发送到3个DN,而且每个DN上的数据都持久化到了磁盘上,这样就算所有的DN都重启,数据仍然存在。 -
文件读取
- 读取流程描述
1.1 DFSClient请求NN,获取到对应read position的Block信息(包括Block落在哪些DN上)。
1.2 DFSClient从Block对应的DN中选择一个合适的DN,对选中的DN创建一个BlockReader以进行数据读取。
HDFS读取流程简单,但对Hbase的读取性能影响重大,尤其是Locality和短路读这两个最为核心的因素。 - Locality
DN本身需要消耗的内存资源和CPU资源都非常少,主要消耗网络带宽和磁盘资源。而Hbase的RS服务本身是内存和CPU消耗型服务,于是我们把RS和DN部署在一批机器上,对DFSClient来说,一个文件在这台机器上的locality可以定义为:
locality=该文件存储在本地机器的字节数之和/该文件总字节数 - 短路读
短路读是指那些Block落在和DFSClient同一台机器上的数据,可以不走TCP协议进行读取,而是直接由DFSClient向本机的DN请求对应的Block文件描述符,然后创建一个BlockReaderLocal,通过fd进行数据读取,这样就节省了走本地TCP协议栈的开销。
测试数据表明:
locality和短路读对Hbase的读性能影响重大,在locality=1.0情况下,不开短路读的p99性能要比开短路读差10%左右。 - HDFS在Hbase系统中扮演的角色
1.Hbase本身并不存储文件,它只规定文件格式以及文件内容,实际文件存储由HDFS实现。
2.HBase不提供机制保证存储数据的高可靠性,数据的高可靠性由HDFS的多副本机制保证。
3.HBase-HDFS体系是典型的计算存储分离架构,这种轻耦合架构的好处是,一方面可以非常方便地使用其他存储替代HDFS作为Hbase的存储方案,另一方面对于云上服务来说,计算资源和存储资源都可以独立扩容、缩容,给云上用户带来了极大便利。
2.4 HBase在HDFS中的文件布局
具体的布局情况