history
started by chad walters and jim
2006.11 G release paper on BigTable
2007.2 inital HBase prototype created as Hadoop contrib
2007.10 First useable Hbase
2008.1 Hadoop become Apache top-level project and Hbase becomes subproject
2008.10 Hbase 0.18,0.19 released
hbase是bigtable的开源山寨版本。是建立的hdfs之上Q提供高可靠性、高性能、列存储、可伸羃、实时读写的数据库系l?/p>
它介于nosql和RDBMS之间Q仅能通过主键(row key)和主键的range来检索数据,仅支持单行事?可通过hive支持来实现多表join{复杂操?。主要用来存储非l构化和半结构化的松散数据?/p>
与hadoop一PHbase目标主要依靠横向扩展Q通过不断增加廉h的商用服务器Q来增加计算和存储能力?/p>
HBase中的表一般有q样的特点:
1 大:一个表可以有上亿行Q上百万?/p>
2 面向?面向??的存储和权限控制Q列(?独立索?/p>
3 E?对于为空(null)的列Qƈ不占用存储空_因此Q表可以设计的非常稀疏?/p>
下面一q图是Hbase在Hadoop Ecosystem中的位置?/p>
HBase以表的Ş式存储数据。表有行和列l成。列划分q个列族(row family)
Row Key | column-family1 | column-family2 | column-family3 | |||
column1 | column1 | column1 | column2 | column3 | column1 | |
key1 | t1:abc t2:gdxdf | t4:dfads t3:hello t2:world | ||||
key2 | t3:abc t1:gdxdf | t4:dfads t3:hello | t2:dfdsfa t3:dfdf | |||
key3 | t2:dfadfasd t1:dfdasddsf | t2:dfxxdfasd t1:taobao.com |
Row Key
与nosql数据库们一?row key是用来检索记录的主键。访问hbase table中的行,只有三种方式Q?/p>
1 通过单个row key讉K
2 通过row key的range
3 全表扫描
Row key行键 (Row key)可以是Q意字W串(最大长度是 64KBQ实际应用中长度一般ؓ 10-100bytes)Q在hbase内部Qrow key保存为字节数l?/p>
存储Ӟ数据按照Row key的字典序(byte order)排序存储。设计keyӞ要充分排序存储这个特性,经怸赯取的行存储放C赗?位置相关?
注意Q?/p>
字典序对int排序的结果是1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。要保持整Ş的自然序Q行键必ȝ0作左填充?/p>
行的一ơ读写是原子操作 (不论一ơ读写多列)。这个设计决{能够用户很容易的理解E序在对同一个行q行q发更新操作时的行ؓ?/p>
列族
hbase表中的每个列Q都归属与某个列族。列族是表的chema的一部分(而列不是)Q必d使用表之前定义。列名都以列族作为前~。例?em>courses:history Q?/em> courses:math 都属?/em> courses q个列族?/p> 讉K控制、磁盘和内存的用统计都是在列族层面q行的。实际应用中Q列族上的控制权限能 帮助我们理不同cd的应用:我们允许一些应用可以添加新的基本数据、一些应用可以读取基本数据ƈ创徏l承的列族、一些应用则只允许浏览数据(甚至可能?为隐U的原因不能览所有数据)?/p> 旉?/strong> HBase中通过row和columns定的ؓ一个存贮单元称为cell。每?cell都保存着同一份数据的多个版本。版本通过旉x索引。时间戳的类型是 64位整型。时间戳可以由hbase(在数据写入时自动 )赋|此时旉x_到毫U的当前pȝ旉。时间戳也可以由客户昑ּ赋倹{如果应用程序要避免数据版本冲突Q就必须自己生成h唯一性的旉戟뀂每?cell中,不同版本的数据按照时间倒序排序Q即最新的数据排在最前面?/p> Z避免数据存在q多版本造成的的理 (包括存贮和烦?负担Qhbase提供了两U数据版本回收方式。一是保存数据的最后n个版本,二是保存最q一D|间内的版本(比如最q七天)。用户可以针Ҏ个列族进行设|?/p> Cell ?em>{row key, column( 1 已经提到q,Table中的所有行都按照row key的字典序排列?/p> 2 Table 在行的方向上分割为多个Hregion?/p> 5 HRegion虽然是分布式存储的最单元,但ƈ不是存储的最单元?/p> 事实上,HRegion׃个或者多个Storel成Q每个store保存一个columns family?/p> 每个Strore又由一个memStore?臛_个StoreFilel成。如图: StoreFile以HFile格式保存在HDFS上?/p> HFile分ؓ六个部分Q?/p> Data Block D?#8211;保存表中的数据,q部分可以被压羃 Meta Block D?(可选的)–保存用户自定义的kv对,可以被压~?/p> File Info D?#8211;Hfile的元信息Q不被压~,用户也可以在q一部分d自己的元信息?/p> Data Block Index D?#8211;Data Block的烦引。每条烦引的key是被索引的block的第一条记录的key?/p> Meta Block IndexD?(可选的)–Meta Block的烦引?/p> Trailer–q一D|定长的。保存了每一D늚偏移量,d一个HFileӞ会首?dTrailerQTrailer保存了每个段的v始位|?D늚Magic Number用来做安全check)Q然后,DataBlock Index会被d到内存中Q这P当检索某个keyӞ不需要扫描整个HFileQ而只需从内存中扑ֈkey所在的blockQ通过一ơ磁盘io整?blockd到内存中Q再扑ֈ需要的key。DataBlock Index采用LRU机制淘汰?/p> HFile的Data BlockQMeta Block通常采用压羃方式存储Q压~之后可以大大减网lIO和磁盘IOQ随之而来的开销当然是需要花费cpuq行压羃和解压羃?/p> 目标Hfile的压~支持两U方式:GzipQLzo?/p> HLog(WAL log) WAL 意ؓWrite ahead log(http://en.wikipedia.org/wiki/Write-ahead_logging)Q类似mysql中的binlog,用来 做灾难恢复只用,Hlog记录数据的所有变?一旦数据修改,可以从log中进行恢复?/p> 每个Region Serverl护一个Hlog,而不是每个Region一个。这样不同region(来自不同table)的日志会混在一Pq样做的目的是不断追加单?文g相对于同时写多个文g而言Q可以减磁盘寻址ơ数Q因此可以提高对table的写性能。带来的ȝ是,如果一台region server下线Qؓ了恢复其上的regionQ需要将region server上的logq行拆分Q然后分发到其它region server上进行恢复?/p> HLog文g是一个普通的Hadoop Sequence FileQSequence File 的Key是HLogKey对象QHLogKey中记录了写入数据的归属信息,除了table和region名字外,同时q包?sequence number和timestampQtimestamp?#8221;写入旉”Qsequence number的v始gؓ0Q或者是最q一ơ存入文件系l中sequence number。HLog Sequece File的Value是HBase的KeyValue对象Q即对应HFile中的KeyValueQ可参见上文描述?/p> Client 1 包含讉Khbase的接口,clientl护着一些cache来加快对hbase的访问,比如regione的位|信息?/p> Zookeeper 1 保证M时候,集群中只有一个master 2 存贮所有Region的寻址入口?/p> 3 实时监控Region Server的状态,Region server的上U和下线信息实时通知lMaster 4 存储Hbase的schema,包括有哪些tableQ每个table有哪些column family Master 1 为Region server分配region 2 负责region server的负载均?/p> 3 发现失效的region serverq新分配其上的region 4 GFS上的垃圾文g回收 5 处理schema更新h Region Server 1 Region serverl护Master分配l它的regionQ处理对q些region的IOh 2 Region server负责切分在运行过E中变得q大的region 可以看到Qclient讉Khbase上数据的q程q不需要master参与Q寻址讉Kzookeeper和region serverQ数据读写访问regione serverQ,master仅仅l护者table和region的元数据信息Q负载很低?/p> region定位 pȝ如何扑ֈ某个row key (或者某?row key range)所在的region bigtable 使用三层cMB+树的l构来保存region位置?/p> W一层是保存zookeeper里面的文Ӟ它持有root region的位|?/p> W二层root region?META.表的W一个region其中保存?META.z表其它region的位|。通过root regionQ我们就可以讉K.META.表的数据?/p> .META.是第三层Q它是一个特D的表,保存了hbase中所有数据表的region 位置信息?/p> 说明Q?/p> 1 root region永远不会被splitQ保证了最需要三ơ蟩转,p定位CQ意region ?/p> 2.META.表每行保存一个region的位|信息,row key 采用表名+表的最后一L码而成?/p> 3 Z加快讉KQ?META.表的全部region都保存在内存中?/p> 假设Q?META.表的一行在内存中大U占?KB。ƈ且每个region限制?28MB?/p> 那么上面的三层结构可以保存的region数目为: (128MB/1KB) * (128MB/1KB) = = 2(34)个region 4 client会将查询q的位置信息保存~存hQ缓存不会主动失效,因此如果client上的~存全部失效Q则需要进?ơ网l来回,才能定位到正的region(其中三次用来发现~存失效Q另外三ơ用来获取位|信??/p> dq程 上文提到Qhbase使用MemStore和StoreFile存储对表的更新?/p> 数据在更新时首先写入Log(WAL log)和内?MemStore)中,MemStore中的数据是排序的Q当MemStore累计C定阈值时Q就会创Z个新的MemStoreQƈ 且将老的MemStored到flush队列Q由单独的线Eflush到磁盘上Q成Z个StoreFile。于此同Ӟpȝ会在zookeeper?记录一个redo pointQ表C个时M前的变更已经持久化了?minor compact) 当系l出现意外时Q可能导致内?MemStore)中的数据丢失Q此时用Log(WAL log)来恢复checkpoint之后的数据?/p> 前面提到qStoreFile是只ȝQ一旦创建后׃可以再修攏V因此Hbase的更 新其实是不断q加的操作。当一个Store中的StoreFile辑ֈ一定的阈值后Q就会进行一ơ合q?major compact),对同一个key的修改合q到一P形成一个大的StoreFileQ当StoreFile的大达C定阈值后Q又会对 StoreFileq行splitQ等分ؓ两个StoreFile?/p> ׃对表的更新是不断q加的,处理读请求时Q需要访问Store中全部的 StoreFile和MemStoreQ将他们的按照row keyq行合ƈQ由于StoreFile和MemStore都是l过排序的,q且StoreFile带有内存中烦引,合ƈ的过E还是比较快?/p> 写请求处理过E?/p> 1 client向region server提交写请?/p> 2 region server扑ֈ目标region 3 region查数据是否与schema一?/p> 4 如果客户端没有指定版本,则获取当前系l时间作为数据版?/p> 5 更新写入WAL log 6 更新写入Memstore 7 判断Memstore的是否需要flush为Store文g?/p> region分配 M时刻Q一个region只能分配l一个region server。master记录了当前有哪些可用的region server。以及当前哪些region分配l了哪些region serverQ哪些regionq没有分配。当存在未分配的regionQƈ且有一个region server上有可用I间Ӟmasterqq个region server发送一个装载请求,把region分配l这个region server。region server得到h后,开始对此region提供服务?/p> region server上线 master使用zookeeper来跟tregion server状态。当某个region server启动Ӟ会首先在zookeeper上的server目录下徏立代表自q文gQƈ获得该文件的独占锁。由于master订阅了server 目录上的变更消息Q当server目录下的文g出现新增或删除操作时Qmaster可以得到来自zookeeper的实旉知。因此一旦region server上线Qmaster能马上得到消息?/p> region server下线 当region server下线Ӟ它和zookeeper的会话断开Qzookeeper而自动释放代表这台server的文件上的独占锁。而master不断轮询 server目录下文件的锁状态。如果master发现某个region server丢失了它自己的独占锁Q?或者masterq箋几次和region server通信都无法成?,master是试去获取代表这个region server的读写锁Q一旦获取成功,可以确定: 1 region server和zookeeper之间的网l断开了?/p> 2 region server挂了?/p> 的其中一U情况发生了Q无论哪U情况,region server都无法lؓ它的region提供服务了,此时master会删除server目录下代表这台region server的文Ӟq将q台region server的region分配l其它还zȝ的同志?/p> 如果|络短暂出现问题Dregion server丢失了它的锁Q那么region server重新q接到zookeeper之后Q只要代表它的文件还在,它就会不断尝试获取这个文件上的锁Q一旦获取到了,可以l提供服务?/p> master上线 master启动q行以下步骤: 1 从zookeeper上获取唯一一个代码master的锁Q用来阻止其它master成ؓmaster?/p> 2 扫描zookeeper上的server目录Q获得当前可用的region server列表?/p> 3 ?中的每个region server通信Q获得当前已分配的region和region server的对应关pR?/p> 4 扫描.META.region的集合,计算得到当前q未分配的regionQ将他们攑օ待分配region列表?/p> master下线 ׃master只维护表和region的元数据Q而不参与表数据IO的过 E,master下线仅导致所有元数据的修改被ȝ(无法创徏删除表,无法修改表的schemaQ无法进行region的负载均衡,无法处理region 上下U,无法q行region的合qӞ唯一例外的是region的split可以正常q行Q因为只有region server参与)Q表的数据读写还可以正常q行。因此master下线短时间内Ҏ个hbase集群没有影响。从上线q程可以看到Qmaster保存?信息全是可以冗余信息Q都可以从系l其它地Ҏ集到或者计出来)Q因此,一般hbase集群中L有一个master在提供服务,q有一个以??#8217;master’在等待时机抢占它的位|?/p> 六、访问接?/strong> § 七、结语: 全文?/strong> Hbase做了 单的介绍Q有错误之处Q敬h正。未来将l合 Hbase 在淘宝数据^台的应用场景Q在更多l节上进行深入?/strong> 参考文?/strong> Bigtable: A Distributed Storage System for Structured Data HFile: A Block-Indexed File Format to Store Sorted Key-Value Pairs for a thorough introduction Hbase Architecture 101 Hbase source code 很久没写博客了,因ؓ很忙Q不q今天发C不错的文章Q帮我梳理了下HBaseQ原文地址Qhttp://www.tbdata.org/archives/1509三?/strong> 物理存储
3 region按大分割的Q每个表一开始只有一个regionQ随着数据不断插入表,region不断增大Q当增大C个阀值的时候,Hregion׃{分会两个新的Hregion。当table中的行不断增多,׃有越来越多的Hregion?br />
4 Hregion是Hbase中分布式存储和负载均衡的最单元。最单元就表示不同的Hregion可以分布在不同的HRegion server上。但一个Hregion是不会拆分到多个server上的?br />四?/strong> pȝ架构
五、关键算?/strong> / 程