皮皮网
皮皮网

【风暴启动源码】【linux环境源码】【taro源码项目】zookeeper hbase源码

来源:发券助手源码 发表时间:2024-12-22 13:16:29

1.zookeeper是源码什么?
2.Hbase读写原理
3.ZooKeeper在HBase中的应用
4.HBase 底层原理详解(深度好文,建议收藏)
5.要不要用hbase自带的zookeeper?
6.JAVA连接HBase客户端及HBase写入数据和读取数据原理解析

zookeeper hbase源码

zookeeper是源码什么?

       zookeeper是动物管理员的意思。

       ZooKeeper是源码一个分布式的,开放源码租前慎的源码分布式应用程序协调服务,是源码Google的Chubby一个开源的实现,是源码风暴启动源码Hadoop和Hbase的重要组件。它是源码一个为分布式应用提供一致性服务的软件,提供的源码功能包括:配置维护、域名服务、源码分布式同步、源码组服务等。源码

       ZooKeeper的源码目标就是封装好复杂易出错的关键服务,将简单易用的源码接口和性能高效、功能稳定的源码系统提供给用户。

       ZooKeeper包含一个简单的源码原语集,提供Java和C的接口。

       ZooKeeper代码版本中,提供了分布式独享锁、选举、linux环境源码队列的接口,代码在$zookeeper_home\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。

       它的原理:

       ZooKeeper是以Fast Paxos算悔判法为基础的,Paxos 算法存在活锁的问题,即当有多个proposer交错提交时,有弊敬可能互相排斥导致没有一个proposer能提交成功,而Fast Paxos做了一些优化,通过选举产生一个leader (领导者),只有leader才能提交proposer,具体算法可见Fast Paxos。因此,要想弄懂ZooKeeper首先得对Fast Paxos有所了解。

       ZooKeeper的基本运转流程:1、选举Leader。2、同步数据。taro源码项目3、选举Leader过程中算法有很多,但要达到的选举标准是一致的。4、Leader要具有最高的执行ID,类似root权限。5、集群中大多数的机器得到响应并接受选出的Leader。

Hbase读写原理

        不同列族分别存在不同的文件夹里。

        与MySQL比较

        首先Hbase是依赖于HDFS和zookeeper的。

        Zookeeper分担了Hmaster的一部分功能,客户端进行DML语句的时候,都是先跟ZK交互。

        RegionServer管理了很多的Region(表),RegionServer里面的WAL(HLog)是预写入日志,功能是防止内存中的数据没有来的及落盘时丢失。在Region里面管理的Store管理的是列族,Store里面有Mem Store(内存),Flush之后,删除内存中的数据,同时写入文件StoreFile Hfile,Hfile 其实是在DataNode里面的。

        Hbase的读比写慢。

        Hbase命名空间下有一张元数据表meta表和namespace表。meta表里面保存了要操作的表所在的位置等元数据。

        (1)首先客户端向zk请求元数据表所在的RegionServer,zk返回给客户端meta表所在的regionServer。

        (2)然后客户端再去对应的RegionServer查找meta表,找到真正要操作的表所在的regionServer,同时把meta表的信息缓存下来,加快后续的查询。

        (3)然后客户端再向目标表所在的RegionServer发送put请求。先把数据写到Hlog里面,再写到内存MemStore,数据会在内存排序,然后向客户端发送ack,到这里对于客户端来说写数据已经结束了。再等到MemStore的刷写时机后,将数据刷写到Hfile.

        注:meta表所在的位置信息保存在zk的meta-region-server节点上,客户端首先就是在这个节点上差询meta表所在的RegionServer。meta表里面的信息就是表与其对应的RegionServer的信息

        这个stu表可能不止一条,因为stu表可能数据量大了之后根据RowKey进行了切分,并且可能会在不同的机器上。

        不同的列族是在不同的文件夹。

        MemStore刷写时机:

        全局的MemStore的容量,默认是堆内存的%。这个容量值会触发flush操作,所有的MemStore都要刷写,flush操作会阻塞读写操作。

        会刷写并阻塞到到MemStore大小降到它的最大容量的%

        WAL日志的刷写时机:

        可以设置日志的大小和数量,当达到一定数量,刷写到HDFS

        (1)从zk找meta表所在的RegionServer

        (2)从上述RegionServer里的meta表里找目标表所在的RegionServer,同时把meta表缓存,加速后面的查询。

        (3)向目标表所在的RegionServer发送get请求。可以从block Cache,MemStore还有StoreFile里面查,具体从哪查根据时间戳,查时间戳大的,具体就都查然后merge取最新。

        RegionServer里面有block Cache可以缓存磁盘的数据,加速查询。如果block Cache里面有,就将缓存和MemStore的数据merge然后取最新时间戳,没有就是把磁盘读的和MemStore里面的合并。所以hbase大多数读要走磁盘,所以读很慢。

        每次刷写会生成新的Hfile,Hfile很小并且数量多的时候会影响查询的速度。所以要进行合并。合并分为minor Compaction和major Compaction

        minor Compaction将临近的若干较小的Hfile合并成一个较大的Hfile,不会清理过期和删除的数据,major Compaction会将一个Store里面的所有Hfile合并成一个大的Hfile,并且会清理掉过期和删除的数据。

        数据的读写可以不依赖Hmaster,只需要指定zookeeper,但是Hmaster负责region调度的元数据

        但是DDL语言是要有Hmaster的

        Flush和major Compact

        (1)flush在同一个内存中清除过期或删除(删除标记也是一行数据)的数据,但是如果数据不同的版本分布在不同的memStroe,就不能清除。删除的标记在flush之后不会被删,但在后面的major compaction会把删除标记删除掉。

        (2)major compaction 会清除过期或删除的数据。

        默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动拆分,两个子Region开始都会在一个Regionserver里面,但是出于负载均衡的考虑,Hmaster有可能会将某个Region传给其他的RegionServer。

        Split的时机:

        (1)当一个Region中的某个Store下的StoreFile的总大小查过某个值,由参数hbase.hregion.max.filesize设定(默认g),该Region就会按照RowKey进行拆分。

        (2)在新版本中这个值是Min(R^2*"hbase.hregion.memStore.flush.size(M)","hbase.hregion.max.filesize"),R是当前RegionServer中属于该Table的Region个数。分region是按照RowKey切分的。这会导致数据倾斜,就是因为切分的阈值在变化,导致切分之后的region数据量不均匀,导致热点的问题。所以在建表的时候要做预分区,就是用RowKey规划好多少个region,不让hbase自己的切分逻辑切分。

        官方建议只用一个列族,防止不同的列族之间数据不均匀,单一列族数据量增多,导致全局的flush,数据量小的列族也要flush,这样会形成很多小的storeFile。

        delete操作:

        (1)设置RowKey:打的删除标记是deleteFamily,删除多个版本

        (2)设置RowKey+Family:打的标记是deleteFamily,删除多个版本

        (3)设置RowKey+family+column:有addColumn()和addColumns().addColumn是删除最新的版本或者删除指定时间戳的版本,删除标记是delete标记。addColumns是删除所有的版本或者删除指定时间戳或之前的版本,删除标记是deleteColumn

        Delete的操作其实也是put操作,put的是删除的标记。

        在Hbase中HMaster负责监控HRegionServer的生命周期,均衡RegionServer的负载,如果HMaster挂掉了,那个整个Hbase集群将处于不健康的状态,并且此时的工作状态不会维持太久。所以Hbase支持对HMaster的高可用配置。

        在Hbase的conf目录下新建backup-masters文件,vim加入备份Master,比如slave,slave.在把文件分发到各个slave里,然后再启动hbase 就能实现HMaster的高可用了。

        每一个region维护着StartRow和EndRow,如果加入的数据符合某个region维护的RowKey范围,则该数据交给这个region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高Hbase性能。

        (1)手动设定预分区

        手动设置RowKey分了5个region

        (2)生成进制序列预分区

        (3)按照文件中设置的规则预分区

        创建split.txt

        然后执行

        这里如果文件里面给的分区键不是按照顺序的,hbase会先帮我们把键排序,然后按照键来分区。

        (4)使用JavaAPI预分区

        admin的创建表的方法有多个重载,可以只传表的描述,也可以加入分区的信息。admin.createTable

        规划分区要考虑未来数据量和机器的规模。虽然提前做了分区,但是最后如果分区大于了G,还是会触发split。假设一台机器有G磁盘,那么预分区尽量大于个,这样就能避免预分区之后又触发了大于G的split。

        (1)希望数据能够尽量均匀的分配在多个分区里面(散列性)。

        (2)唯一性

        (3)长度原则(生产环境到位)

        常见的设计方案:

        (1)生产随机数、hash、散列值

        (2)字符串反转

        (3)字符串拼接

        电信项目:

        一次通话的记录:-> -- ::

        假设分个区

        分区键怎么设计:

        (个键)

        |

        |

        ...

        |

        RowKey的前面一般会拼上_,_,...,_

        这样做的好处是,根据前三位就能知道哪个分区。

        (1)我们希望手机号尽量分布在不同的分区,但是相同的手机号数据集中在同一个分区,这样方便查询某个用户的通话信息。_

        (2)因为每个人通话的需求不同,也希望把同一个人的通话记录也分布在不同的分区里面。__--

        哈希取余:[(^).hash]%

        假设要查询某用户年2月的通话记录,可以用 做startRowkey, 做endRowKey

        微博。

        1、需求

        (1)微博内容的浏览

        (2)用户社交:关注用户,取关用户

        (3)拉取关注人的微博用户

        2、设计表

        (1)微博内容表Content

        行键:用户id+时间戳

        (2)用户关系表

        因为正常情况一个用户的粉丝和关注都不多,可以用一行存储关注和粉丝的情况。

        行键:用户id

        (3)初始化页面的表(显示关注的人的最近三条微博)

ZooKeeper在HBase中的应用

       ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。分布式应用程序可以基于ZooKeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。

        既然ZooKeeper的作用这么大,那我们就来详细说说ZooKeeper在HBase中的应用叭!

        一个分布式HBase系统安装依赖于一个运行着的ZooKeeper集群,所有参与的节点和客户端必须能够正常访问运行着的ZooKeeper集群。HBase默认为你提供一个节点的ZooKeeper集群,它会伴随着HBase start/stop进程的启动/停止而启动/停止。那么HBase主要用ZooKeeper来干什么呢?HBase主要用ZooKeeper来实现HMaster选举与主备切换、系统容错、RootRegion管理、Region状态管理和分布式SplitWAL任务管理等。

        一,HMaster选举与主备切换

        HMaster选举与主备切换的原理和HDFS中NameNode及YARN中ResourceManager的HA原理相同。

        二,系统容错

        当HBase启动时,每个RegionServer都会到ZooKeeper的/hbase/rs节点下创建一个信息节点(下文中,我们称该节点为”rs状态节点”),例如/hbase/rs/[Hostname],同时,HMaster会对这个节点注册监听。当某个 RegionServer 挂掉的时候,ZooKeeper会因为在一段时间内无法接受其心跳(即 Session 失效),而删除掉该 RegionServer 服务器对应的 rs 状态节点。与此同时,HMaster 则会接收到 ZooKeeper 的 NodeDelete 通知,从而感知到某个节点断开,并立即开始容错工作。

        按照上面所说,那为什么HBase不直接让HMaster来负责RegionServer的监控呢?如果HMaster直接通过心跳机制等来管理RegionServer的状态,随着集群越来越大,HMaster的管理负担会越来越重,另外它自身也有挂掉的可能,因此数据还需要持久化。在这种情况下,ZooKeeper就成了理想的选择。

        三,Region管理

        对于大的HBase集群来说,Region的数量可能会多达十万级别,甚至更多,这样规模的Region状态管理交给ZooKeeper来做也是一个非常nice的选择。

        四,分布式SplitWAL任务管理

        当某台RegionServer服务器挂掉时,由于总有一部分新写入的数据还没有持久化到HFile中,因此在迁移该RegionServer的服务时,一个重要的工作就是从WAL中恢复这部分还在内存中的数据,而这部分工作最关键的一步就是SplitWAL,即HMaster需要遍历该RegionServer服务器的WAL,并按Region切分成小块移动到新的地址下,并进行日志的回放(replay)。

        由于单个RegionServer的日志量相对庞大(可能有上千个Region,上GB的日志),而用户又往往希望系统能够快速完成日志的恢复工作。因此一个可行的方案是将这个处理WAL的任务分给多台RegionServer服务器来共同处理,而这就又需要一个持久化组件来辅助HMaster完成任务的分配。当前的做法是,HMaster会在ZooKeeper上创建一个SplitWAL节点(默认情况下,是/hbase/SplitWAL节点),将“哪个RegionServer处理哪个Region”这样的信息以列表的形式存放到该节点上,然后由各个RegionServer服务器自行到该节点上去领取任务并在任务执行成功或失败后再更新该节点的信息,以通知HMaster继续进行后面的步骤。ZooKeeper在这里担负起了分布式集群中相互通知和信息持久化的角色。

        ​

        综上,就是ZooKeeper在HBase中的应用,在这里只列举出了一部分,相对说比较突出的作用,其实ZooKeeper在HBase中的应用远不止这些,比如HMaster还依赖ZooKeeper来完成Table的enable/disable状态记录,以及HBase中几乎所有的元数据存储都是放在ZooKeeper上的等等。

HBase 底层原理详解(深度好文,建议收藏)

       HBase是一个分布式的、面向列的开源数据库,基于Hadoop,主要用于存储大量数据。它在HDFS之上构建,依赖Hadoop生态系统。HBase介于NoSQL和RDBMS之间,只能通过主键(row key)和范围检索数据,支持单行事务。小牛源码网其表具有行键排序和位置相关性特性。

       HBase中表的特点是行键用于检索记录,支持三种访问方式:按行键、按行键范围和通过Zookeeper。行键可以是任意字符串,长度为KB,实际应用中长度一般为-bytes,存储为字节数组。行键排序存储,设计时应考虑经常一起读取的行应放在一起。存储时数据按字典顺序排序,读写操作是原子的。

       列族是表的结构的一部分,列归属于列族。列族用于访问控制、磁盘和内存使用统计。列族过多会增加读取数据的I/O和搜索文件次数,因此除非必要,netty源码后端不要设置过多列族。

       列是列族下的具体列,类似于MySQL中的具体列。时间戳用于记录数据的多个版本,通过行键、列和时间戳确定数据单元(cell)。HBase提供两种数据版本回收方式,根据列族设置。单元由row key、column和version唯一确定。数据存储为字节码,版本号为默认时间戳,类型为Long。

       HRegion存储在HDFS上的StoreFile格式,每个StoreFile包含Trailer、FileInfo、Data Index、Meta Index和Data Block。Data Block是HBase I/O的基本单位,可选择压缩方式存储,以提高效率。每个Data Block由Magic、Key、Value组成,其中Value为二进制数据。

       Memstore和StoreFile组成一个HRegion,写操作先写入Memstore,当达到阈值时,触发Flush到StoreFile。StoreFile达到一定大小,触发Compact合并操作或Split操作,实现负载均衡。读操作先在Memstore查找,找不到再查找StoreFile。

       HLog(WAL log)用于记录数据变更,用于灾难恢复。每个Region Server维护一个Hlog,而非每个Region一个。合并操作分为Minor Compact和Major Compact,将相同Key的修改合并,形成大StoreFile。当StoreFile大小达到阈值,进行Split,分为两个StoreFile。

       HBase的读写过程包括读请求和写请求。读请求先从Zookeeper获取Meta表信息,访问Meta表所在HRegionServer,扫描Memstore和StoreFile获取数据。写请求先写入HLog和Memstore,Memstore达到阈值触发Flush到StoreFile,系统记录redo point。数据写入后,进行Compact和Split操作,以维持高效的数据管理。

       HRegion管理包括分配、上线和下线。HMaster记录HRegion Server状态,当需要分配HRegion时,发送装载请求给有空闲空间的HRegion Server。HRegion Server上线和下线由HMaster监控,HRegion Server下线时,HMaster重新分配HRegion。

       HMaster工作机制包括上线和下线。HMaster下线导致元数据修改被冻结,集群短时间内不受影响。HMaster下线后,集群中会有一个HMaster等待时机抢占位置。

       HBase的三个重要机制包括Flush机制、Compact机制和Split机制。Flush机制控制Memstore大小,触发数据写入StoreFile。Compact机制合并StoreFile,清理过期数据,将版本号保存为1。Split机制将过大的HRegion一分为二,减少StoreFile数量。

要不要用hbase自带的zookeeper?

       HBase的安装包里面有自带zookeeper的。很多系统部署也是直接启动上面的zookeeper。

       æœ¬æ¥ä¹Ÿæ˜¯æ²¡æœ‰é—®é¢˜çš„,想想吧,系统里也只有hbase在用zookeeper。先启动zookeeper,再将hbase起来就好了

       ä½†æ˜¯ä»Šå¤©é‡åˆ°äº†ä¸€ä¸ªå¾ˆè›‹ç–¼çš„问题。和同事争论了很久。

       å› ä¸ºæˆ‘们是好多hbase集群共用一个zookeeper的,其中一个集群需要从hbase 0..2 升级到hbase 0.上,自然,包也要更新。但是其中一台regionserver上面同时也有跑zookeeper,而zookeeper还是用hbase 0..2 自带的zookeeper在跑。

       çŽ°åœ¨å¥½äº†ï¼Œå‡çº§ä¸€ä¸ªregionserver,连着zookeeper也要受到牵连,看来必须要重启,不然,jar包替换掉,可能会影响到zk正在跑的经常。但是重启zk毕竟对正在连接这个zk的client端会有短暂的影响。

       çœŸæ˜¯è›‹ç–¼ã€‚本来只是升级hbase,zk却强耦合了。

       è™½ç„¶åŽæ¥è¯æ˜Žzookeeper只要启动了,哪怕jar包删除也不会影响到正在跑的zk进程,但是这样的不规范带来的风险,实在是没有必要。

       æ‰€ä»¥ä½œä¸ºè¿ç»´ï¼Œæˆ‘强烈建议zk 和hbase分开部署,就直接部署官方的zk 好了,因为zk本身就是一个独立的服务,没有必要和hbase 耦合在一起。

       åœ¨åˆ†å¸ƒå¼çš„系统部署上面,一个角色就用一个专门的文件夹管理,不要用同一个目录下,这样子真的容易出问题。

       å½“然datanode和tasktracker另当别论,他们本身关系密切。

JAVA连接HBase客户端及HBase写入数据和读取数据原理解析

       JAVA连接HBase客户端进行一系列操作,借助HbaseUtil工具类静态代码块一次性创建连接对象、Table对象与Admin对象,实现数据展示、创建表、扫描表、写入数据与读取数据等功能。

       写入数据原理图步骤解析如下:客户端向Zookeeper发送请求,请求向Hbase中写入数据至特定表。Zookeeper返回元数据表meta位置,客户端向指定regionserver请求meta表,下载并缓存到本地。解析meta表找到目标数据所在的hostname与regionname,向对应的regionserver写入数据。数据先存入regionserver的内存memorystore中,当内存达到M或触发flush时,数据被写入到hdfs的文件中,形成store file,即hfile。

       读取数据原理图步骤解析:客户端向Zookeeper请求读取数据,获得meta表位置,下载并解析meta表,请求对应regionserver读取数据。regionserver首先在内存缓存与内存存储中查找数据,找到直接返回;未找到,则在hdfs中利用布隆过滤器快速定位并返回所需数据。布隆过滤器原理见:你不知道的查找算法之布隆过滤器。

       注意点包括flush时机与hdfs中数据真实路径。路径为/hbase/data/namespace/table_name/region_name/cf_name/hfile。

相关栏目:百科