HBase 简介 (Introduction)

HBase: The Hadoop Database



1.1 海量数据的黎明 (The Dawn of Big Data)


 

对于海量数据的重要性, Ralph Kimball 博士指出:

    "数据资产会取代 20 世纪传统有形资产的地位,成为资产负债表的重要组成部分。"
    "数据的价值已经超越了传统企业广泛认同的价值边界。"


    列式存储数据库 (Column-Oriented Databases)
    -------------------------------------------------------------------------------------------------------------------------------------
    列式存储数据库以列为单位聚合数据,然后将列值顺序地存入磁盘,这种存储方法不同于行式存储的传统数据库,行式存储数据库连续第存储整行。
    
    列式存储的出现主要基于这样一种假设:对于特定的查询,不是所有的值都是必须的。尤其是在分析型数据库里,这种情形很常见,因此需要选择一种
    更为合适的存储模式。

    在这种新型的设计中,减少 I/O 只是众多主要因素之一,它还有其它的优点:因为列的数据类型天生就是相似的,即便逻辑上每一行之间有轻微的不同,
    但仍旧比按行存储的结构聚集在一起的数据更利于压缩,因为大多数的压缩算法只关注有限的压缩窗口。
    
    像增量压缩或前缀压缩这类的专业算法,是基于列存储的类型定制的,因而大幅度提高了压缩比。更好的压缩比有利于在返回结果时降低带宽的消耗。

从典型 RDBMS 的角度来看, HBase 并不是一个列式存储的数据库,但是它利用了磁盘上的列存储格式,这也是 RDBMS 与 HBase 最大的相似之处,因为
HBase 以列式存储的格式在磁盘上存储数据。但它与传统的列式数据库有很大的不同:传统的列式数据库比较适合实时存取数据的场景, HBase 比较适合
键值对的数据存取,或者有序的数据存取。


1.2 关系数据库系统的问题 (The Problem with Relational Database Systems)
-----------------------------------------------------------------------------------------------------------------------------------------

先天的扩展性弱造成一系列反范式化和复杂性。

详细内容参考  Hadoop 之关于 HBase  第 6 节内容    ( 6. HBase 和 RDBMS 比较 )

 

 

 


1.3 非关系数据库系统 Not-Only-SQL 简称 NoSQL (Nonrelational Database Systems, Not-Only SQL or NoSQL)
-----------------------------------------------------------------------------------------------------------------------------------------
NoSQL 是 Eric Evans 针对 Johan Oskarsson 提出的 "为新兴的新数据存储空间命名" 问题而创造的一个名词。

标示符号化(tagword) 实际上是一个不错的选择:最新的存储系统不提供通过 SQL 查询数据的手段,只提供一些比较简单的、类似于 API 接口的方式来存取
数据。

但是,也有一些工具为 NoSQL 数据库存取提供了 SQL 语言的入口,用于执行一些关系数据库中常用的复杂条件查询。因此,从查询方式的限制来说,关系型
数据库和非关系型数据库并没有严格的区分。

实际上两者在底层上是由区别的,尤其涉及到模式或者 ACID 事务特性时,因为这是与实际的存储架构是相关的。很多这一类的新系统首先做的事情是:抛弃
一些限制因素以提升扩展性。例如,它们通常不支持事务或辅助索引。更重要的是,这一类系统没有固定的模式,可以随着应用的改变而灵活变化。



    一致性模型 (Consistency Models)
    -------------------------------------------------------------------------------------------------------------------------------------
    一开始的一致性是保证数据库客户端操作的正确性,数据库必须保证每一步操作都是从一个一致的状态到下一个一致的状态。系统没有明确地指定如何
    实现这个功能,以便系统可以有多种选择。最终,系统要选择是进入下一个一致的状态,还是回退到上一个一致的状态,从而保证一致性。
    
    一致性可以按照严格程度由强到弱分类,或者按照对客户端的保证程度分类,下面是一个非正式的分类列表。
    
    严格一致性:数据的变化时原子的,一经改变即时生效,这是一致性的最高形式。
    顺序一致性:每个客户端看到的数据依照它们操作执行的顺序而变化。
    因果一致性:客户端以因果关系顺序观察到数据的改变。
    最终一致性:在没有更新数据的一段时间里,系统将通过广播保证副本之间的数据一致性。
    弱一致性:    没有做出保证的情况下,所有的更新会通过广播的形式传递,展现给不同客户端的数据顺序可能不一样。

    
    CAP 定理(CAP theorem):
    -------------------------------------------------------------------------------------------------------------------------------------
    一个分布式系统只能同时实现一致性、可用性、和分区容忍性(或分区容错性) 中的两个。
    放宽一致性来提高系统可用性是一个非常有效的提议。不过这种方案会强制让应用层去解决一致性的问题,因此也会增加系统的复杂度。
    
各种非关系型数据库有许多共同的特性,同时这其中的许多特性与传统的存储方案也有很多共同点。因此新系统并不是革命性的产品,从工程的角度来看更像是
产品的进化。



1.3.1 维度 (Dimensions)
-----------------------------------------------------------------------------------------------------------------------------------------
在 NoSQL 范畴内,还有很多的维度可以区分系统的特定优势所在。下面列举的这些维度并不全面,并且也不是唯一的区分方式。


    数据模型 (Data model)
    -------------------------------------------------------------------------------------------------------------------------------------
    数据有多种存储的方式,包括键值对、半结构化的列式存储和文档结构存储。用户的应用如何存取数据,同时数据模式是否随着时间而变化。
    
    

    存储模型 (Storage model)
    -------------------------------------------------------------------------------------------------------------------------------------
    内存还是持久化。一旦考虑持久化存储,就需要考虑选择的方案是否会影响到访问模式
    
    
    
    一致性模型 (Consistency model)
    -------------------------------------------------------------------------------------------------------------------------------------
    严格一致性还是最终一致性?问题是存储系统如何实现它的目标:必须降低一致性要求吗?


    原子操作的读-修改-写 (Atomic read-modify-write)
    -------------------------------------------------------------------------------------------------------------------------------------
    RDBMS 数据库直接提供了很多这类操作(因为客户是与一个中心化的,单一的服务器对话),但对于分布式系统来说,这是很难实现的。这些操作可以帮助
    用户避免多线程造成的资源竞争,也可以帮助用户完成无共享应用服务器的设计。
    
    
    加锁,等待,以及死锁 (Locking, waits, and deadlocks)
    -------------------------------------------------------------------------------------------------------------------------------------
    众所周知,复杂的事务处理,如两步提交,会增加多个客户端等待某个资源的可能性。最坏的情况下,可能导致死锁,这是很难解决的。用户需要的系统
    支持哪种锁模型?这种锁模型能否避免等待和死锁?
    
    
    物理模型 (Physical model)
    -------------------------------------------------------------------------------------------------------------------------------------
    分布式还是单机模式?


    读/写性能 (Read/write performance)
    -------------------------------------------------------------------------------------------------------------------------------------
    用户必须了解自己的应用程序访问模式。是读多写少?还是读写相当?或者是写多读少?是用范围扫描数据好,还是用随机读请求数据更好?有些系统
    仅仅对这些情况中的一种支持非常好,有些系统则对各种情况都提供了很好的支持。

    

    辅助索引 (Secondary indexes)
    -------------------------------------------------------------------------------------------------------------------------------------
    辅助索引支持用户按不同的字段和排序方式来访问表。
    
        
    
    故障处理 (Failure handling)
    -------------------------------------------------------------------------------------------------------------------------------------    
    机器会崩溃是一个客观的问题,需要有一套数据迁移方案来应对这种情况。
    
    
    
    压缩 (Compression)
    -------------------------------------------------------------------------------------------------------------------------------------    
    当用户需要存储 TB 级的数据时,尤其当这些数据差异性很小或由可读性文本组成时,压缩会带来非常好的效果,能节省大量的原始数据存储。有可选择
    的压缩组件吗?有哪些压缩算法可用?
    
    
    
    负载均衡 (Load balancing)
    -------------------------------------------------------------------------------------------------------------------------------------
    假如用户有高读写吞吐率的需求,就要考虑配置一套能够随着负载变化自动均衡处理能力的系统。
    
    
    
    
    
1.3.2 可扩展性 (Scalability)
-----------------------------------------------------------------------------------------------------------------------------------------    
RDBMS 非常适合事务性操作,但不见长于超大规模的数据分析处理,因为超大规模的查询需要进行大范围的数据记录扫描或全表扫描。分析型数据库可以存储
数百或数千 TB 的数据,在一台服务器上做查询工作的响应时间,会远远超过用户可接受的合理响应时间。    
    
    
    
1.3.3 数据库的范式化和反范式化 (Database (De-)Normalization)
-----------------------------------------------------------------------------------------------------------------------------------------    
不同的规模,经常需要设计不同的系统结构,对这种原则的最佳描述是:反范式化、复制和智能主键(Denormalization, Duplication, Intelligent Keys,
简称 DDI)。这就需要重新思考在类似 BigTable 的存储系统中如何才能高效合理地存储数据。

部分原则是采用反范式化模式,
    
    
    
1.4 结构 (Building Blocks)
-----------------------------------------------------------------------------------------------------------------------------------------    
HBase 架构的总体概览,介绍数据模型的基本概念和可用的存储 API, 以及对实现进行高层次的概述。
    
    
    
1.4.1 背景 (Backdrop)
-----------------------------------------------------------------------------------------------------------------------------------------    
2003 年, Google 发表论文 "The Google File System", 这个分布式文件系统简称 GFS.
不久, Google 又发表了另一篇论文 "MapReduce: Simplified Data Processing on Large Clusters". MapReduce加上GFS 形成了处理海量数据的核心力量。
2006 年,最终成果发表于论文 "BigTable: A Distributed Storage System for Structured Data"

    "BigTable 是一个管理结构化数据的分布式存储系统,它可以扩展到非常大:如成千上万的商用服务器上存储 PB 级的数据。... 一个稀疏的、分布式的、
    持久的多维排序映射。"



1.4.2 名称空间、表、行、列和单元格 (Namespaces, Tables, Rows, Columns, and Cells)
-----------------------------------------------------------------------------------------------------------------------------------------
最基本的单位是列(column)。一列或多列形成一行(row),并由唯一的行键(row key) 来确定存储。反过来,一个表(table) 中有若干行,其中每列可能有
多个版本,在每个单元格(cell) 中存储了不同的值。在更高层次上,表被分组到名称空间中(namespace), 这很有帮助,例如,按用户或应用程序,或者访问
控制将表分组。

除了每个单元格可以保留若干个版本的数据这一点,整个结构看起来像典型的数据库描述,但很明显有比这更重要的因素。
    
所有的行按照行键字典序进行排序存储。在字典序中,是按照二进制逐字节从左到右依次对比每一个行键。行键总是唯一的,并且只出现一次。虽然 BigTable
的论文里只考虑了行键单一索引,但 HBase 增加了对辅助索引的支持。行键可以使任意的字节数组,但它并不一定是人直接可读的。    
    
一行由若干列组成,若干列又构成一个列族(column family),这不仅有助于构建数据的语义边界或者局部边界,还有助于给它们设置某些特性(如压缩),或者
指示它们存储在内存中。一个列族的所有列存储在同一个底层的存储文件中,这个存储文件叫做 HFile.

列族需要在表创建时就定义好,并且不能修改得太频繁,数量也不能太多。列族名必须由可打印字符组成。

常见的引用列的格式为 family:qualifier,qualifier 是任意的字节数组。与列族的数量有限制相反,列的数量没有限制:一个列族里可以有数百万个列。
列值也没有类型和长度的限定。
    
    
    Note:
    -------------------------------------------------------------------------------------------------------------------------------------
    固定模式的数据库在没有值的地方必须存储 NULL 值,但是在 HBase 的存储架构中,可以干脆省略这个列,换句话说,空值是没有任何消耗的:它们不
    占用任何存储空间。
    
    
每一列的值或单元格的值都具有时间戳,默认由系统指定,也可以由用户显示设置。时间戳可以被使用,例如通过不同的时间戳来区分不同版本的值。一个
单元格的不同版本的值按照降序排列在一起,访问的时候优先读取最新的值。这种优化的目的在于让新值比老值更容易被读取。    
    
HBase 是按照 BigTable 模型实现的,是一个稀疏的、分布式的、持久化的、多维的映射,由行键、列键和时间戳索引。将以上特点联系在一起,就有了如下
的数据存储模式:

    (Table,RowKey,Family,Column,Timestamp)->Value
    
可以用一种编程语言的风格表示如下

    SortedMap<
        RowKey, List<
            SortedMap<
                Column, List<
                Value, Timestamp
                >
            >
        >
    >
    
或者用一行来表示:
    
    SortedMap<RowKey, List<SortedMap<Column, List<Value, Timestamp>>>>
    
第一个 SortedMap 代表那个表,包含一个列族的 List. 列族中包含了另一个 SortedMap 存储列和响应的值。这些值在最后的 List 中,存储了值和该值被设置
的时间戳。

这个数据存取模型的一个有趣的特性是单元格可以存在多个版本,不同的列被写入的次数不同。 API 默认提供了一个所有列的统一视图,API 会自动选择单元格
的当前值。


    webtable
    -------------------------------------------------------------------------------------------------------------------------------------
    BigTable 和 HBase 的典型使用场景是 webtable, 存储从互联网中抓取的网页。
    
    行键是反转的网页 URL, 如 org.hbase.www, 有一个用于存储网页的 HTML 代码的列族 contents, 还有其他列族,如 anchor, 用于存储外向链接和入站
    链接,还有一个用于存储元数据的列族 language
    
    contents 列族使用多个版本,允许用户存储一些旧版本的 HTML 副本,使用多版本是有益的,例如帮助分析一个页面的变化频率。使用的时间戳是抓取
    该页面的实际次数。
    
行数据的存取操作时原子的(atomic), 可以读写任意数目的列。原子存取也是促成系统架构具有强一致性(strictly consistent) 的一个因素,因为并发的读
写者可以对行的状态做出安全的假设。

使用多版本和时间戳同样能帮助应用层解决一致性问题。

最后,单元格(cell), 从 HBase 0.98 开始,可以携带任意 tag 的集合(an arbitrary set of tags). 它们可用于通过元数据(metadata)标示任意单元格,
用于在数据操作期间作出决策。典型的应用场景是安全,单元格的 tag 设置为包含访问细节,一旦某个用户认证并有一个有效的安全令牌(security token),
系统能通过令牌过滤出给定用户的特定单元格。


1.4.3 自动分区 (Auto-Sharding)
-----------------------------------------------------------------------------------------------------------------------------------------
HBase 中扩展和负载均衡的基本单元成为 region, region 本质上是以行键排序的连续存储的区间。如果 region 太大,系统就会把它们动态拆分,相反,
就把多个 region 合并,以减少存储文件数量。

HBase 中的 region 等同于数据库分区中用的范围划分(range partition)。它们可以被分配到若干台物理服务器上以均摊负载,因此提供了较强的扩展性。

一张表初始的时候只有一个 region, 用户开始向表中插入数据时,系统会检查这个 region 的大小,确保其不超过配置的最大值。如果超过了限制,系统
会在中间键(middle key, region 中间的那个行键)处将这个 region 拆分成两个大致相等的子 region.

每一个 region 只能由一台 region 服务器(region server) 加载,每一台 region 服务器可以同时加载多个 region.

region 拆分和服务相当于其他系统提供的自动分区(autosharding)。当一个服务器出现故障后,该服务器上的 region 可以快速恢复,并获得细粒度的负载
均衡,因为当服务于某个 region 的服务器当前负载过大、发生错误、或者被停止使用导致不可用时,系统会将该 region 移到其他服务器上。

region 拆分的操作也非常快 ———— 接近瞬间,因为拆分之后的 region 读取的仍然是原存储文件,直到合并把存储文件异步地写成独立的文件。



1.4.4 存储 API (Storage API)
-----------------------------------------------------------------------------------------------------------------------------------------
    "BigTable 并不支持完整的关系数据模型;相反,它提供了具有简单数据模型的客户端,这个简单的数据模型支持动态控制数据的布局格式 ......"

API 提供了创建表、删除表、增加列族和删除列族操作,同时还提供了修改表和列族元数据的功能,如压缩和设置块大小。此外,还提供了客户端对给定的
行键值进行增加、删除和查找操作的功能。

scan API 提供了高效遍历某个范围的行的功能,同时可以限定返回哪些列或者返回的版本数。通过设置过滤器可以匹配返回的列,通过设置起始和终止的
时间范围可以选择查询的版本。

系统支持单行事务,基于这个特性,系统实现了对单个行键下存储的数据的原子读-修改-写(read-modify-write)序列。

单元格的值可以当做计数器使用,并且能够支持原子更新。这个计数器能够在一个操作中完成读和修改,因此尽管是分布式的系统架构,客户端依然可以利用
此特性实现全局的、强一致性的、连续的计数器。

还可以在服务器的地址空间中执行来自客户端的代码,支持这种功能的服务端框架叫做协处理器(coprocessor)。这个代码能直接访问服务器本地的数据,可以
用于实现轻量级批处理作业,或者使用表达式并基于各种操作来分析或汇总数据。

系统通过提供包装器集成了 MapReduce 框架,该包装器能够将表转换成 MapReduce 作业的输入源和输出目标。

与 RDBMS 不同,HBase 系统没有提供查询数据的特定域语言,例如 SQL 。数据存取不是以声明的方式完成的,而是通过客户端 API 以纯粹的命令完成的。
HBase 的 API 主要是 Java 代码,但是也可以用其它编程语言来存取数据。



1.4.5 实现 (Implementation)
-----------------------------------------------------------------------------------------------------------------------------------------
数据存储在存储文件(store file) 中,称为 HFile, HFile 中存储的是经过排序的键值映射结构。文件内部由连续的块组成,块的索引信息存储在文件的
尾部。当把 HFile 打开并加载到内存中时,索引信息会优先加载到内存中,每个块大小默认为 64 KB, 可以根据需要配置不同的块大小。存储文件提供了一
个设定起始和终止行键范围的 API 用于扫描特定的值。

每一个 HFile 都有一个块索引,通过一个磁盘查找就可以实现查询。首先,在内存的块索引中进行二分查找,确定可能包含给定键的块,然后读取磁盘块
找到实际要找的键。

存储文件通常保存在 Hadoop 分布式文件系统(Hadoop Distributed File System, HDFS)中,HDFS 提供了一个可扩展的、持久的、冗余的 HBase 存储层。
存储文件通过将更改写入到可配置数目的物理服务器中,以保证不丢失数据。

每次更新数据时,都会先将数据记录在提交日志(commit log) 中,在 HBase 中这叫做预写日志(write-ahead log, WAL), 然后会将这些数据写入内存中的
memstore 中。一旦内存保存的写入数据的累计大小超过了一个给定的最大值,系统就会将这些数据移除内存作为 HFile 文件刷写到磁盘中。数据移出内存
之后,系统会丢弃对应的提交日志,只保留未持久化到磁盘中的提交日志。在系统将数据移出 memstore 写入磁盘的过程中,可以不必阻塞系统的读写,通过
滚动内存中的 memstore 就能达到这个目的,即用空的新 memstore 获取更新数据,将满的旧 memstore 转换成一个文件。请注意, memstore 中的数据已经
按照行键排序,持久化到磁盘中的 HFile 也是按照这个顺序排列的,所以不必执行排序或其它特殊处理。

因为存储文件是不可被改变的,所以无法通过移除某个键值对来简单地删除值。可行的解决办法是,做个删除标记(delete marker, 又称墓碑标记),表明
给定行已被删除的事实。在检索过程中,这些删除标记掩盖了实际值,客户端读不到实际值。

读回的数据是两部分合并的结果,一部分是 memstore 中还没有写入磁盘的数据,另一部分是磁盘上的存储文件。值得注意的是,数据检索时用不着 WAL,
只有服务器内存中的数据在服务器崩溃前没有写入到磁盘,而后进行恢复数据时才会用到 WAL.

随着 memstore 中的数据不断刷写到磁盘中,会产生越来越多的 HFile 文件,HBase 内部有个解决这个问题的管家机制,即用合并将多个文件合并成一个
较大的文件。合并有两种类型: minor 合并(minor compaction) 和 major 压缩合并(major compaction)

minor 合并将多个小文件重写为数量较少的大文件,减少存储文件的数量,这个过程实际上是个多路归并的过程。因为 HFile 的每个文件都是经过归类的,
所以合并速度很快,只受到磁盘 I/O 性能的影响。

major 合并将一个 region 中一个列族的若干个 HFile 重写为一个新 HFile, 与 minor 合并相比,还有更独特的功能:major 合并能扫描所有的键值对,
顺序重写全部的数据,重写数据的过程中会略过做了删除标记的数据。断言删除此时生效,例如,对于那些超过版本号限制的数据以及生存时间到期的数据,
在重写数据时就不再写入磁盘了。

HBase 中有 3 个主要的组件:客户端库、一台主服务器、多台 region 服务器。可以动态地增加和移除 region 服务器,以适应不断变化的负载。主服务器
主要负责利用 Apache ZooKeeper 为 region 服务器分配 region, Apache ZooKeeper 是一个可靠的、高可用的、持久化的分布式协调系统。

master 服务器负责跨 region 服务器的全局 region 的负载均衡,将繁忙的服务器中的 region 移到负载较轻的服务器中。主服务器不是实际数据存储或者
检索路径的组成部分,它仅提供了负载均衡和集群管理,不为 region 服务器或者客户端提供任何的数据服务,因此是轻量级服务器。此外,主服务器还提供
了元数据的管理操作,例如,创建表和创建列族。

region 服务器负责为它们服务的 region 提供读写请求,也提供了拆分超过配置大小的 region 的接口。客户端则直接与 region 服务器通信,处理所有数据
相关的操作。


    Apache ZooKeeper
    -------------------------------------------------------------------------------------------------------------------------------------
    ZooKeeper 是 Apache 软件基金会旗下的一个独立开源系统,它是 Google 公司为了解决 BigTable 中问题而提出的 Chubby 算法的开源实现。它提供了
    类似文件系统的访问目录和文件(称为 znode)的功能。通常分布式系统利用它协调所有权、注册服务、监听更新。
    
    每个 region server 在 ZooKeeper 中注册一个自己的临时节点(ephemeral node),主服务器会利用这些临时节点来发现可用服务器,还可以利用临时节
    点来跟踪机器故障和网络分区。
    
    在 ZooKeeper 服务器中,每个临时节点都属于某个会话,这个会话是客户端连接上 ZooKeeper 服务器后自动生成的。每个会话在服务器中有一个唯一的
    id, 并且客户端会以此 id 不断地向 ZooKeeper 服务器发送 "心跳", 一旦发生故障 ZooKeeper 客户端进程死掉, ZooKeeper 服务器会判定该会话超时,
    并自动删除属于它的临时节点。
    
    HBase 可以利用 ZooKeeper 确保只有一个主服务器运行,存储用于发现 region 的引导位置,作为一个 region 服务器的注册表,以及实现其它目的。
    ZooKeeper 是一个关键组成部分,没有它 HBase 就无法运作。 ZooKeeper 使用分布式的一系列服务器和 Zab 协议(确保其状态保持一致)减轻了应用负担
    
    
    

1.4.6 小结
-----------------------------------------------------------------------------------------------------------------------------------------
    "数十亿行 × 数百万列 × 数千个版本 = TB 级或 PB 级存储"
    
    — The HBase Project


表的扫描与时间呈线性关系,行键的查找以及修改操作与时间呈对数关系 ———— 极端情况下是常数关系(使用了布隆过滤器)。
HBase 在设计上完全避免了显示的锁,提供了行原子性操作,这使得系统不会因为读写操作性能而影响系统扩展能力。

当前的列式存储结构允许表在实际存储时不存储 NULL 值,因此表可以看作是个无限的、稀疏的表。表中每行数据只由一台服务器所服务,因此 HBase 具有
强一致性,使用多版本可以避免因并发解耦过程引起的编辑冲突,而且可以保留这一行的历史变化。


可以简单地认为 HBase 完全是 Google 的 BigTable 的开源实现。但这个说法过于简单,因为两者之间还有些差异(大多是细微的)。

HBase 提供了服务器端钩子,可以实施灵活的辅助索引解决方案。此外,它还提供了过滤器功能,减少了网络传输的数据量。



历史 (History)
-----------------------------------------------------------------------------------------------------------------------------------------
    November 2006
    Google releases paper on Bigtable
    February 2007
    Initial HBase prototype created as Hadoop contrib25
    October 2007
    First "usable" HBase (Hadoop 0.15.0)
    January 2008
    Hadoop becomes an Apache top-level project, HBase becomes subproject
    October 2008
    HBase 0.18.1 released
    January 2009
    HBase 0.19.0 released
    September 2009
    HBase 0.20.0 released, the performance release
    May 2010
    HBase becomes an Apache top-level project
    June 2010
    HBase 0.89.20100621, first developer release
    January 2011
    HBase 0.90.0 released, the durability and stability release
    January 2012
    HBase 0.92.0 released, tagged as coprocessor and security release
    May 2012
    HBase 0.94.0 released, tagged as performance release
    October 2013
    HBase 0.96.0 released, tagged as the singularity
    February 2014
    HBase 0.98.0 released
    February 2015
    HBase 1.0.0 released (笔记基于此版本)

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值