Hbase数据存储需要依赖HDFS,集群交互需要依赖zookeeper。首先说明zookeeper在Hbase中的作用。其实zookeeper在各分布式组件中的作用都是大同小异的。
Zookeeper
zookeeper在大数据领域中能占据如此重要的地位,是因为解决了分布式系统中的最基本问题:
1、提供极低延迟超高可用的内存kv数据服务。
2、提供中心化的服务故障发现服务
3、提供分布式锁,counter和Queue等协调服务
zookeeper也是集群模式,zookeeper的主节点是通过活跃的节点选举机制选出来的。在zookeeper集群中,任何zookeeper节点都可能成为主节点。各节点都存储同一份数据,通过ZAB协议作为数据行一致算法。
zookeeper核心特性:
1、多类型节点:可以分为四种类型的节点
持久节点 | 创建后一直存在,直到主动进行删除 |
临时节点 | 临时节点生命周期和客户端session绑定,session失效节点会被自动清理。 临时节点下不能创建子节点 |
持久顺序节点 | 具有持久性和顺序性。持久性和上面持久节点一致。 顺序性指父节点会维护一份时序,记录每个子节点的先后顺序。 |
临时顺序节点 | 包含了临时性和顺序性,和上面一致 |
2、watcher机制:
是一种事件异步反馈机制,类似于公众号订阅推送,或者观察者模式。
watcher设置:可以为所有读操作设置watcher,包括getChildren(),exists(),getData()。
getChildren()设置子节点watcher,关注子节点的创建,删除等
exists()和getData()设置数据watcher,关注数据更新,子节点创建删除等。
watcher触发反馈:客户端与服务端长连接。一但发生事件,就会通知给服务端。
watcher特性:事件是一次性的触发器。触发一次之后需要重新设置watcher。
3、session机制:客户端通过配置逐个尝试连接zookeeper服务器,直到建立连接成功或者都不能连接而失败。
连接一但建立就会创建session,zookeeper长期没有收到任何请求,时间超过超时时间,session就会过期清理,临时节点和watcher时间都会清理。
zookeeper典型应用场景
在hbase中,hbase通过zookeeper实现了高可用和regionserver宕机检测分布式锁等功能。
以分布式锁为例,主要实现以下步骤。
1、客户端通过create创建临时顺序节点
2、客户端通过getchildren获取所有已经创建的子节点
3、获取到的所有子节点都会带有序号(时序),如果序号最小,则认为当前客户端拿到了锁
4、如果不是最小的,客户端会找到最小的节点,追后设置watcher进行监听。
5、监听的节点执行完成释放锁,客户端收到通知调用getchildren(),回到第三步
Hbase在Zookeeper中的布局:
meta-region-server | 存储hbase:meta元数据表所在的RegibServer地址 |
master/backup-masters | 记录主备Master节点,主节点只有一个在运行,备用节点可以有多个 |
table | 集群中所有表的信息 |
region-in-transition | regionserver在这个节点中记录region状态,master通过监听对应节点,region状态发生变化后通知master,master更新region在元数据表中的状态和在内存中的状态 |
table-lock | 表锁。因为一个表会被分割成多个region,所以在DDL操作时,需要通过锁保持数据一致。每次执行DDL操作时,都需要获取对应的表锁。 |
online-snapshot | 在线快照操作。master通过zookeeper下达快找指令给regionserver,regionserver通过zookeeper将快照状态反馈给master |
replication | hbase复制功能 |
splitWAL/ recovering-regions | 用于hbase故障恢复,为提高恢复速度,zookeeper协调所有regionserver都参与日志回放 |
rs | 集群中正在运行的regionserver |
HDFS: 分布式文件系统
目前主流的大数据存储都是存储在hdfs上,其实现的高可用,容灾备份等机制,在大量廉价机器上布置也可以实现系统数据的准确性。
HDFS擅长大文件(文件存储按照块进行划分)的顺序读,随机读,顺序写。HDFS也是主从架构的,大多数大数据组建基本都是主从架构,通过主节点的备份来实现高可用。
HDFS分为以下4个服务组成
NameNode | 线上一般部署两个,一个active(工作的),一个standby(备份)。在主节点发生故障后,zookeeper会将备份节点变为活跃节点。 比较重要的是,namenode需要存储所有操作步骤,和Hbase的Hlog一样,通过记录操作,在出现问题后,可以通过Hlog进行执行恢复。 NameNode会将原数据存储在FsImage和EditLog中。每次文件元数据的写入,都是EditLog的一次顺序写,NameNode在内部的线程,会周期性的将变更写成Fsimage,持久化在磁盘。生成的时间点为t,那么在这之前的EditLog就是过期可删除的。 |
DataNode | 数据存放的节点,一个数据块的多个备份会根据副本存放策略存放在不同的DataNode上。 |
JournaNode | 内部通过Paxos协议保证数据一致性,保证两个NameNode中的数EditLog数据保持一致。 |
ZKFailoverController | 实现NameNode的主备切换 |
Hdfs的写流程
1、向NameNode申请一个唯一文件表示fileld,返回一个OutPutStream,包括了将要写出的DataNode的队列。
2、在数据写入的过程中,数据都是按照块进行存储,写满了一个数据块之后,会重新执行第一步。在写入数据块时,并不是一次直接写入大量数据,而是将数据分为更小的部分packet(64k),每次写满一个packet,就会将它放入到Dataqueue中。之后通过异步线程的方式把数据写入到DataNode,packet会循环的流转在NameNode分配的DataNode之间(第一步分配的几个DataNode),数据都写入成功,就会发送ACK(确认回执)返送到Dfs client,packet写入成功。
3、关闭OutPutStream,若不进行关闭,则会导致缓存(Packet和PacketQueue)在DFSClient中的数据丢失。
这里有两种数据写入的方式:
hflush:数据成功发送到所有的Datanode上,并且至少有一个DataNode,正常运行hflush返回成功。但是数据可能还没有写入磁盘,仍在缓存中。
hsync:数据不但都发送到了DataNode上,并且数据都持久化在了磁盘上。
HDFS数据读取:
DFS申请Block(多个),DFSClient会选择一个合适的DataNode创建BlockReader进行数据读取(影响因素有是否同一个机架,是否在同一个网段,是否跨网进行传输)
HDFS读取流程很简单,但对于HBase的读取性能影响重大,尤其Locality和短路度两个核心因素:
Locality:一般情况下,DataNode(磁盘消耗型)和Hbase的RegionServer(内存Cpu消耗型)部署在统一台机器上。对某个DFSClient来说,这台机器的Locality可以定义为:
locality=该文件存储在本地机器的字节数之和/该文件总字节数 =>(文件分为好几个Block,是否都存储在同一个机器上)。这样Locality是一个[0-1] 之间的数字。Locality越高,本地化率越高,文件都存储在本地。
短路读:需要读取的Block和DFSClient在同一台机器上,则可以直接读取本地服务器上的数据,这样节省了TCP协议读取数据的网络开销。
HBASE在HDFS中的布局:
.hbase-snapshot | snapshot文件存储目录 |
.tmp | 临时文件目录,主要用于Hbase表的创建和删除。创建时会先在tmp目录下执行,成功后将tmp目录下的表信息移动到实际目录。删除时即哪个表目录移动到tmp下,一段时间后删除 |
MasterProcWALs | 用于实现可恢复的分布式DDL操作。MasterProcedure功能使用WAL记录DDL执行的中间状态,异常发生时通过WAL回放继续执行后续操作。 |
WALs | 存储集群所有RegionServer的Hlog日志 |
archive | 文件归档目录。 1、Hfile的删除都会临时放到该目录 2、进行Snapshot或者升级时 3、Compaction(hbase hfile合并)删除hfile时。 |
corrupt | 存储损坏的Hlog或Hfile文件 |
data | 存储集群中所有Region的Hfile文件。其路径构造为 /hbase/data/default(表schema)/test(表名)/region名称/TK(列簇名)/hfile名 除了存储hfile外,还存储一些重要的子目录和子文件。 .tabledesc:表文件描述 .tmp:表临时目录。主要存储Flush和Compaction过程中的中间结果。Memostore数据刷到Hfile中时,会先存储在此目录,成功后在移动到实际对应的目录下。 .regioninfo:region描述文件 recovered.edits:存储故障恢复时,该Region需要回放的WAL日志数据。RegionServer宕机之后,那些没来得及flush到磁盘的数据需要通过WAl回放。WAL首先会按照Region进行切分,回放时只需要回放自己的WAL数据片段即可。 |
集群启动初始化的时候,创建集群唯一id | |
hbase.version | Hbase版本号 |
oldWALs | WAL归档目录,一旦一个WAL中记录的多有kv数据都已经从MemoStore持久化到了hfile中,那么该WALs就会移动到此目录 |
















