精华内容
下载资源
问答
  • 包含以下内容 一列存储的原理 什么是列存储 列存储技术的主要特征 ...二、列存储的应用范围 列存储索引的种类 为什么使用列存储 何时应使用列存储 三、列存储的应用 如何创建列存储索引 与行存储的性能对比
  • 一、定义行式存储把一行中数据值串在一起存储起来,然后再存储下一行数据,以此类推存储把一数据值串在一起存储起来,然后再存储下一列的数据,以此类推二、例子1数据库以行、列的二维表形式表示...

    一、定义

    • 行式存储把一行中的数据值串在一起存储起来,然后再存储下一行的数据,以此类推
    • 列式存储把一列中的数据值串在一起存储起来,然后再存储下一列的数据,以此类推

    二、例子1

    数据库以行、列的二维表的形式表示数据,但是却以一维字符串的方式存储,举个例子

    上面的表包括 Empid,Lastname、Firstname,Salary 四个字段。

    数据库会把这个表存储在一系列的一维字节中,由操作系统将这一系列的字节写到磁盘中。

    行式数据库把一行中的数据串在一起存储起来,然后再存储下一行的数据,以此类推,如下:

    ```

    1,Smith,Joe,40000;2,Jones,Mary,50000;3,Johnson,Cathy,44000;

    ```


    列式数据库把一列中的数据串在一起存储起来,然后再存储下一列的数据,依次类推,如下:

    ```

    1,2,3;Smith,Jones,Johnson;Joe,Mary,Cathy;40000,50000,44000;

    ```

    上面是简化的说法,只是为了便于表达意思。


    三、例子2
    在行式数据库中,每一行数据都看做一个整体,可以被认为是一小块数据,这样每一块数据都是紧挨着另一块数据存放在硬盘中。一般情况下,可以认为每一行存储的数据就是硬盘中的一组连续的字节。

    为了方便讨论,有如下表,假设每一行都包含一个用户的信息,每个用户的所有属性都整块的存储在硬盘上


    在硬盘上,大量的页面用来存储所有的数据。现在假设数据库中的每行信息都存储在同一页上,也就是说,每一页只能保存一个用户的所有信息。在上面的例子中,Alice 的所有信息都被存储到一个页面中,如果需要获取或者更新 Alice 的信息,那么某一时刻在内存中仅需存储关于 Alice 的单一页面。如所示:

    好了,现在目光转向列式存储。如果是基于列的数据库,所有的数据都是以列的形式存储的。同样,我们假设每一列的存储只对应一个页面,那么用户的每个属性信息都会被单独存储在一个页面,如下:

    那么,现在考虑如下场景。如果使用的是行式数据库,你正好需要对一行数据进行操作时,数据库的性能是最好的,因为仅一个页面被放到了内存中(这只是个示例,实际上操作系统会带来不止一个页面的数据)。

    但是,如果你只是想对表中所有数据的某一列的数据做一些操作,这意味着你将花费时间去访问每一行,可你用到的仅是一行中的小部分数据。此时使用的若是列式数据库,就可以方便快捷的访问数据,因为每一列的信息都是存储在一起的。

    蛋疼的时候来了,假如现在使用的是列式存储,你又想获取 Alice 的所有信息,那你又必须去读取大量的列(页面)来获取所有的数据。

    正因为如此,才有了行式存储和列式存储的使用场景的区别。


    当你的核心业务是 OLTP 时,一个行式数据库,再加上优化操作,可能是个最好的选择。
    当你的核心业务是 OLAP 时,一个列式数据库,绝对是更好的选择

    展开全文
  • 2012以后提供了一种不同于传统B树结构索引类型,就是内存列存储索引。这种索引应用了一种基于列存储模式,也是一种新查询执行批处理模式,并且为特定负载提供了巨大性能提升。它是如何构建?如何工作?...

    2012以后提供了一种不同于传统B树结构的索引类型,就是内存列存储索引。这种索引应用了一种基于列的存储模式,也是一种新的查询执行的批处理模式,并且为特定的负载提供了巨大的性能提升。它是如何构建?如何工作?又是为什么能对性能有如此大的提升,接下来我们用简明的描述和详尽的示例来解释说明。

    那么列存储索引究竟是什么?大多数时候,列存储索引被描述作为一种数据仓库和数据报表的功能。事实上,你最有可能就是在这种情况下利用这种索引。然而,即使在OLTP数据库中,你也会遇到一些要从大量数据表中获取数据的报表,它们是非常缓慢的。在合适的计划和谨慎的使用下,甚至这些报表也能利用列存储索引得到性能的提高。一个重要的前提是数据非常大,列存储索引是用来与大数据表一起使用的。虽然没有明确的最小要求,但是作为经验,我建议至少要有一千万的行数据在一个单表中才能受益于列存储索引。

    对于这个系列中的例子,将使用 ContosoRetailDW 作为演示 数据库,下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=18279,这是一个626MB的数据库备份,大概1.2GB大小的数据库,对于列存储索引而言有点小,但是对于演示功能来说足够大了。这个数据库本身不包含任何列存储索引,事实上不是一个坏事,为了能更好的体现列存储索引的优点,我们将对同一查询对比带和不带列存储索引的性能。下面的例子是一个典型的来自于BI信息工作人员的查询。

    WITH ContosoProducts

    AS (SELECT *

    FROM dbo.DimProduct

    WHERE BrandName = 'Contoso')

    SELECT cp.ProductName,

    dd.CalendarQuarter,

    COUNT(fos.SalesOrderNumber) AS NumOrders,

    SUM(fos.SalesQuantity) AS QuantitySold

    FROM dbo.FactOnlineSales AS fos

    INNER JOIN dbo.DimDate AS dd

    ON dd.Datekey = fos.DateKey

    INNER JOIN ContosoProducts AS cp

    ON cp.ProductKey = fos.ProductKey

    GROUP BY cp.ProductName,

    dd.CalendarQuarter

    ORDER BY cp.ProductName,

    dd.CalendarQuarter;

    Listing 1: 典型的BI查询

    在我的笔记本上,这个查询平均花费了6.27秒来读取已经在缓存中的数据,假如数据被直接从硬盘上读取这个执行将花费8.11秒。由于FactOnlineSales 表中有超过12500000行的数据,这个查询必须扫描整个聚集索引,其实这样还不错,但是假如你整天面对这样的查询,这样的迟缓的响应将变成一个非常恶心的事情,同时也能联想到如果数据库是十倍甚至百倍大小时回事什么样的性能表现?

    注意这些执行时间是基于硬件设备的使用,假如重复执行这些测试在一个高端设备上,这些查询可能会非常迅速。当然如果在一个三年前的廉价笔记本上,将更缓慢的执行。不过,即使如此,我们也将看到在创建列存储索引后将会极大的提升执行效率。

    创建列存储索引

    列存储索引有两个类型:聚集和非聚集。有很多相似之处两者之间,也有很多不同。其中一个不同是在2012中只有非聚集列存储索引。2014中才加入了聚集的版本。我们将创建一个非聚集列存储索引,以便读者能在没SQLServer2014的情况下实现。

    CREATE NONCLUSTERED COLUMNSTORE INDEX NCI_FactOnlineSales

    ON dbo.FactOnlineSales

    (OnlineSalesKey,

    DateKey,

    StoreKey,

    ProductKey,

    PromotionKey,

    CurrencyKey,

    CustomerKey,

    SalesOrderNumber,

    SalesOrderLineNumber,

    SalesQuantity,

    SalesAmount,

    ReturnQuantity,

    ReturnAmount,

    DiscountQuantity,

    DiscountAmount,

    TotalCost,

    UnitCost,

    UnitPrice,

    ETLLoadID,

    LoadDate,

    UpdateDate);

    Listing 2: 创建非聚集存储索引

    执行这个创建将花费一些时间(我必须要等待接近43秒),但是这是一个一次性的操作,在真实的数据仓库中会在夜间完成这一典型的操作。一旦索引被创建,它会提高SQLServer 中很多查询的效率。

    我们获得了什么?(优点)

    当我们再次运行listing 1的代码,结果和以前的一样,但是这个结果几乎是即刻返回的。整个查询只用了0.34秒,是之前没有加入列存储索引速度的18倍多。当然如果从硬盘上读取的话,即使是列存储索引也会变慢,大约需要1.54秒,不过这仍然要比之前的8.11秒快了5倍多。

    缺点

    这个由非聚集列存储索引获得的性能提升令人印象深刻的,但是也需要在书写查询的时候非常小心。几乎每个带有列存储索引的表查询都能提高效率,但是你必须带着许多限制来书写代码从而获得更大的性能潜力。比如其中一个这样限制是有关于外部连接的。

    假如编写 listing 1代码的编程人员打算将BrandName为“Contoso ”的所有产品,即使没有卖出去过的,都包含在结果中,那么就需要将Inner Join 变为Right Outer Join,如下listing3 中所示:

    WITH ContosoProducts

    AS (SELECT *

    FROM   dbo.DimProduct

    WHERE  BrandName                    = 'Contoso')

    SELECT     cp.ProductName,

    dd.CalendarQuarter,

    COUNT(fos.SalesOrderNumber) AS NumOrders,

    SUM(fos.SalesQuantity)      AS QuantitySold

    FROM       dbo.FactOnlineSales         AS fos

    INNER JOIN dbo.DimDate                 AS dd

    ON   dd.Datekey                   = fos.DateKey

    RIGHT JOIN ContosoProducts             AS cp

    ON   cp.ProductKey                = fos.ProductKey

    GROUP BY   cp.ProductName,

    dd.CalendarQuarter

    ORDER BY   cp.ProductName,

    dd.CalendarQuarter;

    Listing 3: 引入一个外链接

    在没有列存储索引的情况下(或者带有暗示模仿忽视列存储索引的情况),当数据已经在缓存中时,这个查询运行了6.71秒。包含了变化造成的在执行计划中的额外消耗,这部分大概花费了0.44秒在,耗时增加了接近百分之7。

    当在我的SQLServer2012中不带提示的去运行这个查询时,优化器将立即选择一个带有列存储索引的执行计划,结果正如期望是更快的,接近4.24秒。当然这依然是要比6.71秒那种不含列存储索引的效率高的,但是与之前0.34秒的情况比较起来没有明显变化,那到底是为什么在同时都应用了列存储索引的情况下,仅仅从inner改为了outer 就产生了如此大的性能变化呢?

    批处理模式

    列存储索引是由于使用了一种叫做“批处理执行模式”的模式,用一种完全不同的方式来执行查询,但是在2012中这一模式是有很多限制的,仅有少量操作符可以用来使用这一模式,只要使用了不再这些操作符中的操作符,这个查询将返回到原来的查询模式中。比如Outer Join就是这样的操作符,将会引起查询返回到行模式中,虽然也能获取一部分性能提升,但是不能从批处理模式中得到显著提升。

    最快速的方式去核实这个模式就是通过执行计划来查看该查询在SSMS 中的图像。检查两个属性“Estimated Execution Mode” 和“Actual Execution Mode”,下图极为在批处理模式下查询执行计划的示例,两个属性都为batch。

    Figure 1-1: 执行计划显示为Batch

    当然在2014中批处理模式的操作符增加很多,其中outer join 也是其中之一,总之在性能和限制上,2014都有显著的提高,这一点是毋庸置疑的。

    对比效果.

    没有一种简单的方式去预测当你创建列存储索引后性能的提升。目前只有通过在真实环境下比较查询性能或者在一个尽可能真实的测试环境下来测试比较,它带来的好处。

    对于能够运行在批处理模式下的查询而言,我们已经能看到在添加列存储索引后性能提升了5到70倍,相比较于行模式的查询,性能的提升永远是更小的,一般为50%到20倍的提升。

    总结

    通过使用列存储索引通过两个因素来提升性能。一个是通过新的索引架构来节省I/O,另一个是批处理模式。很不幸的是,在SQLServer2012中仅有少量操作符可以使用列存储索引,造成许多查询被迫采用行模式执行,丧失了批处理模式的性能获得。不过好消息是,绝大多数的限制在SQLServer 2014 中得到了完善。

    翻译自StairWay

    展开全文
  • 行存储和列存储--大数据应用选择

    千次阅读 2015-05-23 21:28:27
    目前大数据存储有两种方案可供选择:行存储和列存储。...在已知几种大数据处理软件中,HadoopHBase采用列存储,MongoDB是文档型行存储,Lexst是二进制型行存储。在这里,我不讨论这些软件技术和优缺点,只围

    HBase使用的是列存储,MongoDB使用的是行存储,对于行存储和列存储各有各的优缺点,对于大数据而言,进行快速的数据处理,列存储是必须的,但是就列存储而言,对于数据的完整性和对硬件的要求较高,然而,行存储的数据冗余是大数据处理的弊端,不优化,无法适应快速数据处理的要求。

    PS:增加一些Hadoop和MongoDB的对比。

    Hadoop强于分布式存储及运算,分布式存储及运算,分布式存储及运算,主要用来处理非结构化数据,半结构化数据,GOOGLE分布计算架构的克隆版,列存储,编程语言JAVA,加速代码用CJNI调用。

    MongoDB是一个数据库,仅是单机多核运算,个较为简单NOSQL,是分布数据库,存储格式JSON变体,行存储,自己解释数据,编程语言C++

    相同之处:都可以使用Map-Reduce

    目前大数据存储有两种方案可供选择:行存储和列存储。业界对两种存储方案有很多争持,集中焦点是:谁能够更有效地处理海量数据,且兼顾安全、可靠、完整性。从目前发展情况看,关系数据库已经不适应这种巨大的存储量和计算要求,基本是淘汰出局。在已知的几种大数据处理软件中,Hadoop的HBase采用列存储,MongoDB是文档型的行存储,Lexst是二进制型的行存储。在这里,我不讨论这些软件的技术和优缺点,只围绕机械磁盘的物理特质,分析行存储和列存储的存储特点,以及由此产生的一些问题和解决办法。

    一.结构布局

    行存储数据排列

    列存储数据排列
     

    表格的灰色背景部分表示行列结构,白色背景部分表示数据的物理分布,两种存储的数据都是从上至下,从左向右的排列。行是列的组合,行存储以一行记录为单位,列存储以列数据集合单位,或称列族(column family)。行存储的读写过程是一致的,都是从第一列开始,到最后一列结束。列存储的读取是列数据集中的一段或者全部数据,写入时,一行记录被拆分为多列,每一列数据追加到对应列的末尾处。

    二. 对比

    从上面表格可以看出,行存储的写入是一次完成。如果这种写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确定。列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储在写入上占有很大的优势。

    还有数据修改,这实际也是一次写入过程。不同的是,数据修改是对磁盘上的记录做删除标记。行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入,这个过程仍是行存储的列数倍。所以,数据修改也是以行存储占优。 数据读取时,行存储通常将一行数据完全读出,如果只需要其中几列数据的情况,就会存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的。列存储每次读取的数据是集合的一段或者全部,如果读取多列时,就需要移动磁头,再次定位到下一列的位置继续读取。 再谈两种存储的数据分布。由于列存储的每一列数据类型是同质的,不存在二义性问题。比如说某列数据类型为整型(int),那么它的数据集合一定是整型数据。这种情况使数据解析变得十分容易。相比之下,行存储则要复杂得多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换,这个操作很消耗CPU,增加了解析的时间。所以,列存储的解析过程更有利于分析大数据。

    三. 优化

    显而易见,两种存储格式都有各自的优缺点:行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率。列存储在写入效率、保证数据完整性上都不如行存储,它的优势是在读取过程,不会产生冗余数据,这对数据完整性要求不高的大数据处理领域,比如互联网,犹为重要。

    改进集中在两方面:行存储读取过程中避免产生冗余数据,列存储提高读写效率。

    如何改进它们的缺点,并保证优点呢?

    行存储的改进:减少冗余数据首先是用户在定义数据时避免冗余列的产生;其次是优化数据存储记录结构,保证从磁盘读出的数据进入内存后,能够被快速分解,消除冗余列。要知道,目前市场上即使最低端CPU和内存的速度也比机械磁盘快上100-1000倍。如果用上高端的硬件配置,这个处理过程还要更快。

    列存储的两点改进:1.在计算机上安装多块硬盘,以多线程并行的方式读写它们。多块硬盘并行工作可以减少磁盘读写竞用,这种方式对提高处理效率优势十分明显。缺点是需要更多的硬盘,这会增加投入成本,在大规模数据处理应用中是不小的数目,运营商需要认真考虑这个问题。2.对写过程中的数据完整性问题,可考虑在写入过程中加入类似关系数据库的“回滚”机制,当某一列发生写入失败时,此前写入的数据全部失效,同时加入散列码校验,进一步保证数据完整性。

    这两种存储方案还有一个共同改进的地方:频繁的小量的数据写入对磁盘影响很大,更好的解决办法是将数据在内存中暂时保存并整理,达到一定数量后,一次性写入磁盘,这样消耗时间更少一些。目前机械磁盘的写入速度在20M-50M/秒之间,能够以批量的方式写入磁盘,效果也是不错的。

    四. 总结

    两种存储格式各自的特性都决定了它们不可能是完美的解决方案。 如果首要考虑是数据的完整性和可靠性,那么行存储是不二选择,列存储只有在增加磁盘并改进软件设计后才能接近这样的目标。如果以保存数据为主,行存储的写入性能比列存储高很多。在需要频繁读取单列集合数据的应用中,列存储是最合适的。如果每次读取多列,两个方案可酌情选择:采用行存储时,设计中应考虑减少或避免冗余列;若采用列存储方案,为保证读写入效率,每列数据尽可能分别保存到不同的磁盘上,多个线程并行读写各自的数据,这样避免了磁盘竞用的同时也提高了处理效率。 无论选择哪种方案,将同内容数据聚凑在一起都是必须的,这是减少磁头在磁盘上的移动,提高数据读取时间的有效办法。

      

    展开全文
  • Hbase能做什么? 1、海量数据的存储(P级别...负责管理HBase元数据,即表的结构、表存储的Region等元信息(-ROOT-表和.META.表是hbase的元数据表)。 负责表的创建,删除和修改(因为这些操作会导致HBase元数据的...

    一、Hbase架构

    Hbase能做什么?

    1、海量数据的存储(P级别)

    2、海量数据的查询(毫秒级)

    一个表:30字段,60亿条数据

    根据rowkey查询:1k条,几十毫秒,2w条数据,几百毫秒。RPC通信机制

    Zookeeper

    • 保证任何时候,集群中只有一个master(负责多HMaster的选举)
    • 存贮所有Region的寻址入口,meta表
    • 实时监控RegionServer的状态、将RegionServer的上线和下线信息实时通知给Master(服务器之间状态同步)
    • 存储Hbase的schema(元数据信息)。包括有哪些table、每个table有哪些column family等

    HMaster
    (主要负责table和region的管理工作)

    • 监听zk,负责RegionServer的负载均衡,调整region的分配
    • 基于zookeeper感应RegionServer的上下线,发现失效的regionserver并重新分配其上的region,在一个RegionServer死机后,负责失效节点的Region的迁移,
    • Region分裂后,为RegionServer分配新的Region
    • 基于zookeeper来保证HA
    • 管理用户对表table的增、删、改、查操作
    • 处理schema更新请求 (管理用户对表的增删修改)
    • 不参与对表的读写访问

    RegionServer
    (主要负责响应用户对其上region的I/O请求,向HDFS读写数据,HbasHBase核心模块)

    • 一个HRegionServer会有多个HRegion和一个HLog。
    • HRegionSserver维护Master分配给它的region,维护Region,处理region的flush、compact、split分裂,StoreFileCompaction合并,写入到HDFS中。
    • 处理Client端的读写请求(根据从HMaster返回的元数据找到对应的Region来读写数据)。数据的添加、删除、修改、查询等操作。

    Region
    (图中为Hregion,也就是指一个Table的分区)

    • HRegion是分布式存储和负载的最小单元。表中的数据存储在Region中,每个Region都由RegionServer进行管理。对hbase数据表的表数据维护。
    • 每一个HRegion又由很多的Store组成,每一个Store存储的实际上是一个列簇(ColumnFamily)下所有的数据。此外,在每一个Store(又名HStore)中有包含一块MemStore。MemStore驻留在内存中,数据到来时首先更新到MemStore中,当到达阈值之后再flush(默认64M)到对应的StoreFile(又名HFile)中,所以每一个Store包含多个StoreFile,StoreFile负责的是实际数据存储,为HBase中最小的存储单元。
    • 达到某个阈值时,分裂(默认256M)。所以一个HRegionServer管理多个表,一个表下有多个Region,一个HRegion有多少个列族就有多少个Store,Store下有多个StoreFile文件,是HBase中最小的存储单元
    • 以Region为单位管理, region(startKey,endKey);【默认情况下,刚创建一个表时,并不知道startkey和endkey】
    • 每个Column Family单独存储:storeFile;( storefile的数量一多(到达阀值),就合并(同时合并版本以及删除之前要删除的数据);合并后大小到达阀值就split)
    • 当某个Column Family累积的大小(具体的数据量) > 某阈值时,自动分裂成两个Region;合并之后,旧数据也不是立即删除,而是复制一份并同内存中的数据一起写到磁盘,在之后,LSM-Tree会提供一些机制来回收这些空间。[4]
    • 如何找到某行属于哪个region呢?两张特殊的表:-NAMESPACE- 和.META.

    StoreFile
    (底层存储格式是HFile,HBase中最小的存储单元)

    memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。 

    HFile
    (HFile基于Hadoop的TFile类实现,模仿Google的BIgTable论文中的SSTable格式。)

    • HBase中KeyValue数据的存储格式,是hadoop的二进制格式文件。
    • HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。
    • Trailer中有指针指向其他数据块的起始点,FileInfo记录了文件的一些meta信息。 - Data Block是hbase io的基本单元,为了提高效率,HRegionServer中有基于LRU的block cache机制。
    • 每个Data块的大小可以在创建一个Table的时候通过参数指定(默认块大小64KB),大号的Block有利于顺序Scan,小号的Block利于随机查询。
    • 每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成
    • Magic内容就是一些随机数字,目的是防止数据损坏
      这里写图片描述

    HLog(WAL log)
    (HLog是WAL的核心实现类)

    • WAL意为write ahead log,HBase中的预写日志,用来做灾难恢复使用,底层实现是HLog,HLog记录数据的所有变更。使用WAL的原因:因为MemStore存储的数据是驻留在内存中的,是不稳定的(比如宕机时),所以采用了WAL预写日志来解决这个问题。(运行MApReduce作业时,可以通过关闭WAL功能来获得性能的提升——setWriteToWAL(boolean))
    • 其实HLog文件就是一个普通的Hadoop Sequence File, Sequence File的value是key时HLogKey对象,其中记录了写入数据的归属信息,除了table和region名字外,还同时包括sequence number和timestamp,timestamp是写入时间,sequence number的起始值为0,或者是最近一次存入文件系统中的sequence number。 Sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue。[1]

    4、-ROOT-,.META.的作用

    我们先来看.META.表,假设HBase中只有两张用户表:Table1和Table2,Table1非常大,被划分成了很多Region,因此在.META.表中有很多条Row用来记录这些Region。而Table2很小,只是被划分成了两个Region,因此在.META.中只有两条Row用来记录。这个表的内容看上去是这个样子的: 

    .META.行记录结构

    现在假设我们要从Table2里面插寻一条RowKey是RK10000的数据。那么我们应该遵循以下步骤:

    1. 从.META.表里面查询哪个Region包含这条数据。

    2. 获取管理这个Region的RegionServer地址。

    3. 连接这个RegionServer, 查到这条数据。

    问题是.META.也是一张普通的表,我们需要先知道哪个RegionServer管理了.META.表,怎么办?有一个方法,我们把管理.META.表的RegionServer的地址放到ZooKeeper上面,这样大家都知道了谁在管理.META.。

    貌似问题解决了,但对于这个例子我们遇到了一个新问题。因为Table1实在太大了,它的Region实在太多了,.META.为了存储这些Region信息,花费了大量的空间,自己也需要划分成多个Region。这就意味着可能有多个RegionServer在管理.META(每个RegionServer都有自己的.META)怎么办?在ZooKeeper里面存储所有管理.META.的RegionServer地址让Client自己去遍历?HBase并不是这么做的。

    HBase的做法是用另外一个表来记录.META.的Region信息,就和.META.记录用户表的Region信息一模一样。这个表就是-ROOT-表。这也解释了为什么-ROOT-和.META.拥有相同的表结构,因为他们的原理是一模一样的。

    假设.META.表被分成了两个Region,那么-ROOT-的内容看上去大概是这个样子的:

    -ROOT-行记录结构

    这么一来Client端就需要先去访问-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。这个地址被存在ZooKeeper中。默认的路径是:/hbase/root-region-server 。-ROOT-只会有一个Region,这个Region的信息也是被存在HBase内部的。 

    关于Region的查找,早期的设计(0.96)之前是被称之为三层查询架构,如下图所示:

    从ZooKeeper得到-ROOT-的RegionServer => 
    从-ROOT-表中查到RowKey最接近(小于).META.,Table2,RK10000,99999999999999的一条Row,并得到.META.的RegionServer => 
    从.META.表中查到RowKey最接近(小于)Table2,RK10000, 99999999999999的一条Row,并得到Table2的RegionServer => 
    从Table2中查到RK10000的Row  
    

    步骤:

    (1)用户通过查找zk(zookeeper)的/hbase/root-region-server节点来知道-ROOT-表在什么RegionServer上。

    (2)访问-ROOT-表,查看需要的数据在哪个.META.表上,这个.META.表在什么RegionServer上。

    (3)访问.META.表查看查询的rowkey在什么Region范围里面。,并得到Table2的RegionServer 

    (4)连接具体的数据所在的RegionServer,这回就真的开始用Scan来遍历row了。 

     

    Client访问ZK,根据ROOT表获取meta表所在Region的位置信息,并将该位置信息写入Client Cache。 
    (注:为了加快数据访问速度,我们将元数据、Region位置等信息缓存在Client Cache中。)

     

    为了让客户端找到包含特定主键的region,Hbase0.96之前提供了两张特殊的目录表-ROOT-和.META表

    root表用来查询所有meta表中热region的位置。meta表则是用来查找所有table的region的位置。Hbase原来的设计中只有一个root region,则root从不拆分,从而保证类似于B+树结构的三层查找结构:第一层是zookeeper中包含root region位置信息的节点,第二层是从root表中查找对应meta表的region的位置,第三层是从meta表中查找用户表对应region的位置。

    既然0.96之前是这么做的,那为什么就舍弃了呢?

    1、BigTable的论文论述了meta的region大小为128M时,可以定位2^34个region,这是怎么计算的呢?

    .META.表每行保存一个region的位置信息,row key 采用表名+表的最后一样编码而成。

    为了加快访问,.META.表的全部region都保存在内存中。

    假设,.META.表的一行在内存中大约占用1KB。并且每个region限制为128MB。

    那么上面的三层结构可以保存的region数目为:一个region的root和一个region的meta

    (128MB/1KB) * (128MB/1KB) = = 2^32个region

    2、除了三层架构定位的数据过多之外,还有网络请求的原因。

    虽然客户端缓存了region的地址,但是初始化需求的时候需要重新查找region(client上的缓存全部失效),例如:当缓存过期了,并发生了region的拆分、合并或者移动。客户端使用递归查找的方式从目录中重新定位当前region的位置,它从对应的meta表region中查找对应行键的地址。如果对应的meta的region地址无效,它就向root请求当前对应meta表的位,最后,如果连root都没有用了,就回向zookeeper节点查询root表的新地址。在最坏的情况下,客户端需要6次网络往返请求(其中三次用来发现缓存失效,另外三次用来获取位置信息)。来定位一个用户region,这也是三层架构的一个弊端之一。

     在0.96之后,将root表去接去掉了 

    没有了root表,直接从meta查询,和上面条件一个,假设一个region有128M,一行地址数据1KB,那么就可以定位128M/1kB个region,有2^24的大小,有16T,因为meta表肯定不止一个region,一个region肯定不止128M,所以,从meta来定位的数据大小远大于16T,对于一个Hbase集群来说,完全够了。

    而且,少了一层root,网络请求次数肯定会减少,这也是优势之一。

    二层架构的定位步骤如下:

    (1)用户通过查找zk(zookeeper)的/hbase/meta-region-server节点查询哪台RegionServer上有hbase:meta表。

    (2)客户端连接含有hbase:meta表的RegionServer。Hbase:meta表存储了所有Region的行健范围信息,通过这个表就可以查询出你要存取的rowkey属于哪个Region的范围里面,以及这个Region又是属于哪个RegionServer。

    (3)获取这些信息后,客户端就可以直连其中一台拥有你要存取的rowkey的RegionServer,并直接对其操作。

    (4)客户端会把meta信息缓存起来,下次操作就不需要进行以上加载HBase:meta的步骤了。 

     

    一、读数据的流程(参考下图):

    1)Client先访问zookeeper,从meta表所处位置(ip,找到对应的HRegionServer)

    2)访问meta表,然后读取meta表中的数据。根据namespace、tablename、rowkey信息,在meta表中找到该Row数据对应的region信息;获取管理这个Region的RegionServer地址。

    3)找到这个region对应的regionserver,查找对应的region;

    4)先从MemStore找数据,如果没有,再到BlockCache里面读;

    5)BlockCache还没有,再到StoreFile上读(为了读取的效率);

    6)如果是从StoreFile里面读取的数据,不是直接返回给客户端,而是先写入BlockCache,再返回给客户端。 

     

    二、写数据的流程:Put

    1)Client先访问zookeeper,从meta表所处位置(ip),zookeeper中存储了meta表的region信息,从meta表获取相应region信息,然后找到meta表的数据

    2)访问meta表,然后读取meta表中的数据。meta中又存储了用户表的region信息;根据namespace、TableName、rowkey在meta表中找到对应的region信息;通过一定算法计算出要写入的Region。

    3)找到该Region对应的RegionServer并进行连接。客户端向HRegionServer请求写数据 

    4)HregionServer将数据分别写到HLog和MemoryStore中。为了数据的持久化和恢复;

    8)反馈Client写成功。

    5)每当MemoryStore中的大小达到阈值时(内存中的数据128M,时间),会生成一个StoreFile。将数据Flush到硬盘中,并同时删除内存和hlog中的历史数据。若MemStore中的数据有丢失,则可以总HLog上恢复

    6.当StoreFile的数量超过一定时,会进行StoreFile的合并(Compact),将多个StoreFile文件合并成一个StoreFile,当HDFS中的数据块达到4块的时候,Hmaster将数据加载到本地进行一个合并

    6)当StoreFile的文件大小超过一定阈值时(256M),会进行Region的切分(Split),由Master将新Region分配到相应不同的RegionServer中,实现负载均衡。使得原先1个Region的压力得以分流到2个Region上

    7)当HRegionServer宕机后,将HRegionServer上的hlog重新分配给不同的HRegionServer进行加载(修改.META文件中关于数据所在server的信息)。注意:hlog会同步到HDFS中。

    8)HBase只是增加数据,有所得更新和删除操作,都是在Compact阶段做的,所以,用户写操作只需要进入到内存即可立即返回,从而保证I/O高性能。

    补充1:HStore存储是HBase存储的核心,其中由两部分组成,一部分是MemStore,一部分是StoreFiles。

    2、HLog的功能:

    在分布式系统环境中,无法避免系统出错或者宕机,一旦HRegionServer意外退出,MemStore中的内存数据就会丢失,引入HLog就是防止这种情况。

    工作机制:每个HRegionServer中都会有一个HLog对象,HLog是一个实现Write Ahead Log的类,每次用户操作写入Memstore的同时,也会写一份数据到HLog文件,HLog文件定期会滚动出新,并删除旧的文件(已持久化到 StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知,HMaster首先处理遗留的 HLog文件,将不同region的log数据拆分,分别放到相应region目录下,然后再将失效的region(带有刚刚拆分的log)重新分配,领取到这些region的 HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。

    补充3:Region就是StoreFiles,StoreFiles里由HFile构成,Hfile里由hbase的data块构成,一个data块里面又有很多keyvalue对,每个keyvalue里存了我们需要的值。

    3、数据Flush过程

    当MemStore数据达到阈值(默认是128M,老版本是64M),将数据刷到硬盘,将内存中的数据删除,同时删除HLog中的历史数据;

    有 3 个条件满足任意一个都可以触发 flush:

    1. 当一个 RegionServer 中的所有 MemStore 的大小只和超过了堆内存的 40%. 则这个 RegionServer 中所有的 MemStore 一起刷到 HFile 中,由于 HBase 底层依靠 HDFS,因此 HFile 都存储在 HDFS 之中
    2. 当有任何一个 MemStore 的存活时间超过了 1h, 则这个 RegionServer 中所有的 MemStore 一起刷到 HFile 中.
    3. 单个region里多个memstore的缓存大小,超过那么整个HRegion就会flush,默认128M

    4、StoreFile合并(Compaction)

    目的:减少StoreFile数量,提升数据读取效率。由于前面的刷写过程的存在, 有可能会导致磁盘上有比较多的 HFile 小文件, 而 HDFS 并不适合存储小文件, 所以就存在了一个小文件合并的过程.

    Compaction分为两种:有 2 种合并:

    1. 小合并(Minor Compaction): 当一个store里面允许存的HFile的个数,超过这个个数会被写到一个新的HFile里面,也就是每个region的每个列族对应的memstore在flush为HFile的时候,默认情况下当超过3个HFile的时候就会对这些文件进行合并重写为一个新文件,设置个数越大key减少触发合并的时间,但是每次合并的时间就会越长
    2. 大合并(Major Compaction): Major compaction 指一个 region 下的所有 HFile 做归并排序, 最后形成一个大的HFile. 这可以提高读性能.  major compaction重写所有的Hfile, 占用大量硬盘IO和网络带宽. 这也被称为写放大现象(write amplification)

    默认7天执行一次,将多个storefile合并,会将过期的,超出版本数量的、标记为删除的数据都进行删除(一般要在系统空闲的时候去做,因为需要大量的磁盘IO)

    Major compaction 可以被调度成自动运行的模式, 但是由于写放大的问题(write amplification), major compaction通常在一周执行一次或者只在凌晨运行.

    此外, major compaction的过程中, 如果发现region server负责的数据不在本地的HDFS datanode上, major compaction除了合并文件外, 还会把其中一份数据转存到本地的data node上.

    5、Region 拆分(Split)

    目的:实现数据访问的负载均衡。

    做法:利用Middle Key将当前Region划分为两个等分的子Region。

    需要指出的是:Split会产生大量的I/O操作,Split开始前和Split完成后,HRegionServer都会通知HMaster。Split完成后,由于Region映射关系已变更,故HRegionServer会更新meta表。 

    按固定长度分割region,固定长度取值优先获取table的“MAX_FILESIZE” 值,若没有设定该属性,则采用在hbase-site.xml中配置的hbase.hregion.max.filesize值,在0.94版本中这个值的缺省值已经被调整为:10 * 1024 * 1024 * 1024L 也就是10G,网上很多关于 hbase.hregion.max.filesize 默认值 1G的文章应该都是基于0.92的hbase的。

    最初, 每张表只有一个 region, 当一个 region 变得太大时, 它就分裂成 2 个子region。2个子 region, 各占原始 region 的一半数据, 仍然被相同的 region server管理。然后Region server向HBase master节点汇报拆分完成.

    如果集群内还有其他 region server, master 节点倾向于做负载均衡, 所以master节点有可能调度新的 region 到其他 region server, 由其他 region 管理新的分裂出的region.

    7、HRegionServer宕机如何处理?

    1)ZooKeeper会监控HRegionServer的上下线情况,当ZK发现某个HRegionServer宕机之后会通知HMaster进行失效备援;
    2)该HRegionServer会停止对外提供服务,就是它所负责的region暂时停止对外提供服务
    3)HMaster会将该HRegionServer所负责的region转移到其他HRegionServer上,并且会对HRegionServer上存在memstore中还未持久化到磁盘中的数据进行恢复
    4)这个恢复的工作是由WAL重播来完成,这个过程如下:

    • wal实际上就是一个文件,存在/hbase/WAL/对应RegionServer路径下
    • 宕机发生时,读取该RegionServer所对应的路径下的wal文件,然后根据不同的region切分成不同的临时文件recover.edits
    • 当region被分配到新的RegionServer中,RegionServer读取region时会进行是否存在recover.edits,如果有则进行恢复

    三、Zookeeper在HBase中的作用

    bin/zkcli.sh (进入zookeeper)

     

    查看hbase集群在zookeeper记录的信息,比如:regionserver1-slave-1,regionserver2-slave-2

    ls2 /hbase/rs
    [slave-2,16020,1511853261863, slave-1,16020,1511853261718]
    cZxid = 0x100000004
    ctime = Mon Nov 27 18:08:47 CST 2017
    mZxid = 0x100000004
    mtime = Mon Nov 27 18:08:47 CST 2017
    pZxid = 0x200000426
    cversion = 22
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 0
    numChildren = 2
    

    查看所有表

    [zk: localhost:2181(CONNECTED) 11] ls2 /hbase/table
    [aa,hbase:meta, hbase:namespace]
    cZxid = 0x100000006
    ctime = Mon Nov 27 18:08:47 CST 2017
    mZxid = 0x100000006
    mtime = Mon Nov 27 18:08:47 CST 2017
    pZxid = 0x200000478
    cversion = 56
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 0
    numChildren = 24
    

    查看hbase的meta表信息,内涵server信息。

    [zk: localhost:2181(CONNECTED) 14] get /hbase/table/hbase:meta
    �master:16000�S�!��X�PBUF
    cZxid = 0x200000034
    ctime = Mon Nov 27 18:16:58 CST 2017
    mZxid = 0x200000035
    mtime = Mon Nov 27 18:16:58 CST 2017
    pZxid = 0x200000034
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 31
    numChildren = 0

    1.保证Master的高可用性,确保整个集群只有一个HMaster,当状态为Active的Master无法提供服务时,会立刻将状态为StandBy的Master切换为Active状态。

    2.实时监控RegionServer集群,当某个RegionServer节点无法提供服务时将会通知Master,由Master进行RegionServer上的Region转移以及重新进行负载均衡。

    3.当HBase集群启动后,Master和RegionServer会分别向Zookeeper进行注册,会将hbase 系统表-ROOT- 加载到 zookeeper,会在Zookeeper中存放HBase的META表数据:Region与RegionServer的关系、以及RegionServer的信息(地址等 

    通过zookeeper可以获取当前系统表.META.的存储所对应的regionserver信息。进行管理

    *META表中维护着TableName、RowKey和Region的关联关系。

    这里面数据分区(region)存储是为了查询方便(即因为是集群所以能充分利用磁盘的IO性)。添加数据时,数据先进入Hlog–预写日志(数据只能追加不能修改)<防止数据丢失>,数据在Hlog写完后再写到内存中。 
    HFile:认为是将数据进行序列化。 
    StoreFile:认为是一个文件。 
    HDFS:调用HDFS的客户端API来将数据传到HDFS。 

    HBase采用LSM树型结构,而不是B或B+树  LSM树(Log Structured Merge Tree,结构化合并树)

    关于磁盘IO

    磁盘读写时涉及到磁盘上数据查找,地址一般由柱面号、盘面号和块号三者构成。也就是说移动臂先根据柱面号移动到指定柱面,然后根据盘面号确定盘面的磁道,最后根据块号将指定的磁道段移动到磁头下,便可开始读写。

    整个过程主要有三部分时间消耗,查找时间(seek time) +等待时间(latency time)+传输时间(transmission time) 。分别表示定位柱面的耗时、将块号指定磁道段移到磁头的耗时、将数据传到内存的耗时。整个磁盘IO最耗时的地方在查找时间,所以减少查找时间能大幅提升性能。

    四、索引、LSM树原理(一棵LSM树就是一个个B+树合起来。)

    1、插入步骤

       LSM-tree是通过将很多小文件的存取转换为连续的大批量传输,使得对于文件系统的大多数存取都是顺序性的,从而提高磁盘带宽利用率;故障恢复速度快。它对数据写入主要分以下三个阶段: 
        1、数据的写入,append形式插入,以log追加的方式进行按顺序被保存到logfile文件,具有索引; 
        2、一旦数据被保存到了logfile文件,会被立即保存到一块儿叫的内存缓冲区的memsotre——缓存的数据也是就说排序的
        3、当内存中的memsotre大到一个阀值的时候,缓存数据会被以key -> record对的形式刷新到磁盘,生成一个新的存储文件持久化数据。

    LSM树由两个或以上的存储结构组成,比如在论文中为了方便说明使用了最简单的两个存储结构。一个存储结构常驻内存中,称为C0 tree,具体可以是任何方便健值查找的数据结构,比如红黑树、map之类,B-树。另外一个存储结构常驻在硬盘中,称为C1 tree,具体结构类似B树。C1所有节点都是100%满的,节点的大小为磁盘块大小。 

    将C0中记录滚动合并到磁盘C1中;对于多个存储结构的情况,当C1体量越来越大就向C2合并,以此类推,一直往上合并Ck。
    由于memstore中的数据每刷新一次生成一个store文件,store文件会随着时间的推移越来越多,系统对这些文件采用一种叫rolliong merge即滚动合并的模式,由后台线程将这些文件合并成一个大的store文件——文件中的数据总是按key排序存储的,这样只需经过很少的磁盘查找就可以查到结果。 


        在查找数据时,首先会在memstore中的数据中查找,如果查找到则直接返回结构,否则接下来回查找保存在磁盘上的store文件中的数据,返回将结果返回——查的到或查不到。 

     但是读取时,由于不知道数据在哪棵小树上,因此必须遍历所有小树(所以才说LSM牺牲了部分读的性能),每棵小树内部数据是有序的。查询是先查内存中的部分,再去查磁盘上的部分。
        删除是一个特殊的更新操作,执行一个delete操作时,这个要删除的数据会被标记为delete marker被保存起来;当查询时会过滤掉标记为“删除”的key的数据。只有在后台线程异步的重写的数据页数据时,标记为“删除”的数据才会被删除。

    2、合并步骤

    合并过程中会使用两个块:emptying block和filling block。

    从C1中读取未合并叶子节点,放置内存中的emptying block中。从小到大找C0中的节点,与emptying block进行合并排序,合并结果保存到filling block中,并将C0对应的节点删除。不断执行第2步操作,合并排序结果不断填入filling block中,当其满了则将其追加到磁盘的新位置上,注意是追加而不是改变原来的节点。合并期间如故宫emptying block使用完了则再从C1中读取未合并的叶子节点。C0和C1所有叶子节点都按以上合并完成后即完成一次合并。

    三、HBase的表结构

    HBase中的表由RowKey、ColumnFamily、Column、Timestamp组成。

    RowKey

    记录的唯一标识,相当于关系型数据库中的主键。

    *RowKey最大长度为64KB且按字典顺序进行排序存储。

    *HBase会自动为RowKey加上索引,当按RowKey查询时速度很快。

    ColumnFamily

    列簇相当于特定的一个类别,每个列簇下可以有任意数量个列,并且列是动态进行添加的,只在插入数据后存在,HBase在创建表时只需要指定表名和列簇即可。

    *一个列簇下的成员有着相同的前缀,使用冒号来对列簇和列名进行分隔。

    *一张表中的列簇最好不超过5个。

    Column

    列只有在插入数据后才存在,且列在列簇中是有序的。

    *每个列簇下的列数没有限制。

    Timestamp

    HBase中的每个键值对都有一个时间戳,在进行插入时由HBase进行自动赋值。

    三、传统的行存储和(HBase)列存储的区别

    从上图可以很清楚地看到,行式存储下一张表的数据都是放在一起的,但列式存储下都被分开保存了。所以它们就有了如下这些优缺点:

                                 

    行式存储

    列式存储

    优点

    Ø  数据被保存在一起

    Ø  INSERT/UPDATE容易

    Ø  查询时只有涉及到的列会被读取

    Ø  投影(projection)很高效

    Ø  任何列都能作为索引

    缺点

    Ø  选择(Selection)时即使只涉及某几列,所有数据也都会被读取

    Ø  选择完成时,被选择的列要重新组装

    Ø  INSERT/UPDATE比较麻烦

    注:关系型数据库理论回顾 - 选择(Selection)和投影(Projection)

    2、数据压缩

     通过字典表压缩数据。

    下面才是那张表本来的样子。经过字典表进行数据压缩后,表中的字符串才都变成数字了。正因为每个字符串在字典表里只出现一次了,所以达到了压缩的目的(有点像规范化和非规范化Normalize和Denomalize)

    3、查询执行性能

    下面就是最牛的图了,根据列值进行条件查询(过滤)

    通过一条查询的执行过程说明列式存储(以及数据压缩)的优点:

    关键步骤如下:

    1.     去字典表里找到字符串对应数字(只进行一次字符串比较)。

    2.     用数字去列表里匹配,匹配上的位置设为1。

    3.     把不同列的匹配结果进行位运算得到符合所有条件的记录下标。

    4.     使用这个下标组装出最终的结果集。

     

    四、应用场景

    • 对象存储:我们知道不少的头条类、新闻类的的新闻、网页、图片存储在HBase之中,一些病毒公司的病毒库也是存储在HBase之中

    • 时序数据:HBase之上有OpenTSDB模块,可以满足时序类场景的需求

    • 推荐画像:特别是用户的画像,是一个比较大的稀疏矩阵,蚂蚁的风控就是构建在HBase之上

    • 时空数据:主要是轨迹、气象网格之类,滴滴打车的轨迹数据主要存在HBase之中,另外在技术所有大一点的数据量的车联网企业,数据都是存在HBase之中

    • CubeDB OLAP:Kylin一个cube分析工具,底层的数据就是存储在HBase之中,不少客户自己基于离线计算构建cube存储在hbase之中,满足在线报表查询的需求

    • 消息/订单:在电信领域、银行领域,不少的订单查询底层的存储,另外不少通信、消息同步的应用构建在HBase之上

    • Feeds流:典型的应用就是xx朋友圈类似的应用

    • NewSQL:之上有Phoenix的插件,可以满足二级索引、SQL的需求,对接传统数据需要SQL非事务的需求

    五、HBase问题解决:

    1、HBase一对多关系的表结构设计

    最终的解决方案是这个表(按照官方资料): 

    Table Row Key Family Attributes(ColumnKeys/Qualifiers)
    BlogTable ID info: Author, Title, URL
        text: No ColumnKey,3version
        comment title: Column keys are written like YYYMMDDHHmmss. Should be IN-MEMORY and have a 1 version
        comment text: Same keys. 1 Version

    其实了解以下两个知识点就可以了: 

    1.HBase的二维表结构:三个重要概念是Column Family(以下简称为CF)和Column Key/Qualifier(以下简称为CK)还有RowKey。一个CF可以包含若干个CK。相当于CF是个合并单元格;CK才是具体的列标示,并且可以为空。Rowkey就是行标示,可以理解为主键。

    2.Hbase中,对于某个Column Family中的Column Key是可以动态增加的 

    存储于关系型数据库中的数据如下,简单起见某些字段删减了: 

    表头 

    ID Author Title Body
    1 张三 消息头 这是内容Hello World!

    明细表: 

    ID HeadID CommentAuthor Title Body
    1 1 李四 回复头1 这是回复内容1
    2 1 王五 回复头2 这是回复内容2

    转移到Hbase中存储,需要把以前的明细“纵向延伸”(对于同一表头,明细表一条一条向下加数据),转变为HBase的“横向延伸”(对同一RowKey,添加明细的ColumnKey),Hbase中存储的数据如下,iteye的表不会弄合并单元格,所以用excel截图来展示吧: 

    结论:从图中可以看出,HBase是把以前关系数据库明细表的字段作为ColumnFamily,而明细表的主键作为ColumnKey的这种结构来达到一对多的效果的。关系型数据库,明细增多时是纵向添加数据;对于Hbase,则是通过ColumnKey的增加来添加数据 


    由此可能产生的问题: 

    • 1.HBase官方不推荐多Column Family,超过3个是妥妥儿不推荐的 可是一对多的这种关系是必须用多Column Family的,这点矛盾让我到现在还很不解。。 
    • 2.RowKey的存储问题,传统数据库主键一般都是递增的方式生成的一批证书值,但是Hbase采用这种方式做为RowKey的话会导致regionserver负载过高的问题,所以RowKey的生成方式需要再讨论。
    • 3.这种一对多的方式,如果回复很多很多,比如贴吧随便一个帖子就是上W回复的,会导致ColumnKey变得很多,也就是说Hbase表会变得很宽=。= 

    尽管看过帖子说HBase并不是传统意义的二维结构,就是不会单独为某个Cell为空的区域留出空间存储数据(这里我可能理解和描述的都不太贴切), 总之这种“宽”的表结构,是对传统数据库表结构意识形态的一种冲击,不知道会不会有问题。。
     

    2、hbase扩容(增加节点)

    二、hbase扩容

    1、登陆master1,修改配置文件

    $ cd /data1/usr/hbase-1.2.4/conf

    $ vi regionservers 

    添加新节点主机

    slave4

    slave5

    $ for ip in 2 3 4 5;

    do

    scp /data1/usr/hbase-1.2.4/conf/regionservers       192.168.11.13$ip:/data1/usr/hbase-1.2.4/etc/hadoop/;

    done

    登陆新节点,创建目录,修改权限

    2、拷贝hbase文件到新节点

    登陆master1节点

    $ scp -rpq /data1/usr/hbase-1.2.4  hduser@192.168.11.136:/data 

    $ scp -rpq /data1/usr/hbase-1.2.4  hduser@192.168.11.137:/data

    清理日志

    $ cd /data1/usr/hbase-1.2.4/logs

    $ rm *.out.*

    3、登陆新节点,启动服务

    $ cd /data1/usr/hbase-1.2.4/bin

    $ ./hbase-daemon.sh start regionserver

    $ ./hbase shell
     

    3、HBase 宕机如何处理

    答:宕机分为 HMaster 宕机和 HRegisoner 宕机,

    如果是 HMaster 宕机, HMaster 没有单点问题, HBase 中可以启动多个 HMaster,通过Zookeeper 的 Master Election 机制保证总有一个 Master 运行。即 ZooKeeper 会保证总会有一个 HMaster 在对外提供服务。

    如果是 HRegisoner 宕机, HMaster 会将其所管理的 region 重新分布到其他活动的 RegionServer 上,由于数据和日志都持久在 HDFS中,该操作不会导致数据丢失。所以数据的一致性和安全性是有保障的。

    4、HRegionServer宕机如何处理?

    1)ZooKeeper会监控HRegionServer的上下线情况,当ZK发现某个HRegionServer宕机之后会通知HMaster进行失效备援;
    2)该HRegionServer会停止对外提供服务,就是它所负责的region暂时停止对外提供服务
    3)HMaster会将该HRegionServer所负责的region转移到其他HRegionServer上,并且会对HRegionServer上存在memstore中还未持久化到磁盘中的数据进行恢复
    4)这个恢复的工作是由WAL重播来完成,这个过程如下:

    • wal实际上就是一个文件,存在/hbase/WAL/对应RegionServer路径下
    • 宕机发生时,读取该RegionServer所对应的路径下的wal文件,然后根据不同的region切分成不同的临时文件recover.edits
    • 当region被分配到新的RegionServer中,RegionServer读取region时会进行是否存在recover.edits,如果有则进行恢复

     

    展开全文
  • 2012以后提供了一种不同于传统B树结构索引类型,就是内存列存储索引。这种索引应用了一种基于列存储模式,也是一种新查询执行批处理模式,并且为特定负载提供了巨大性能提升。它是如何构建?如何工作?...
  • 列存储、行存储

    2016-04-25 16:41:03
    Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析、数据挖掘等查询密集型应用。列存储,缩写为DSM,相对于NSM(N-ary storage model),其主要区别在于: DSM将所有记录中相同字段的数据...
  • 列存储索引

    2018-04-19 14:46:00
    2012以后提供了一种不同于传统B树结构索引类型,就是内存列存储索引。这种索引应用了一种基于列存储模式,也是一种新查询执行批处理模式,并且为特定负载提供了巨大性能提升。它是如何构建?如何工作?...
  • 在这篇博文中,我们将讨论行存储和列存储数据库之间区别。 客户经常问我们他们是否应该或者可以使用柱状数据库。 对于某些应用程序,柱状数据库是一个很好选择;对于其他人来说,您应该坚持尝试真正基于行...
  • 行存储与列存储

    2015-08-10 18:23:11
    列存储适合OLAP,数据仓库,数据挖掘等查询密集型应用,不适合dml很多OLTP系统 1) 每个字段数据聚集存储,在查询只需要少数几个字段时候,能大大减少读取数据量 2) 既然是一个字段数据聚集存储,那就更...
  • 点击上方“蓝字”可以关注我们哦卞昊穹中国人民大学博士嘉宾简介:中国人民大学博士研究生,研究方向为数据库系统和实时数据分析,从事SQL-on-Hadoop系统测试和开发。在HDFS列存储优...
  • 针对确定的可复用数据,提出了基于列存储的复用实现策略,分别给出了原始数据列、压缩数据列及索引数据列的复用实现方法.最后提出了基于复用数据的查询实现技术.在大规模数据仓库基准数据集上的实验结果验证了数据复用...
  • Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析、数据挖掘等查询密集型应用。列存储,缩写为DSM,相对于NSM(N-ary storage model),其主要区别在于: DSM将所有记录中相同字段的数据聚合...
  • 因此HBase被广泛使用在大数据存储的解决方案中。为何使用HBase呢?科多大数据带你们来看看。HBase的优点:1.可以动态增加,并且列为空就不存储数据,节省存储空间。2.Hbase自动切分数据,使得数据存储自动具有水平...
  • apache druid(孵化)是用于事件驱动数据高性能分析数据存储
  • 针对不断增长的配电网按行存储数据的模式造成数据体量持续增大、压缩率难以提高的问题,利用按列存储的数据包架构和扩展区间编码的正规化处理技巧,提出了一种大体量配电网监测信息的压缩处理新方法。以列数据包为...
  • {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云数据库专家保驾护航,为用户数据库应用系统进行性能和风险评估,参与配合进行...
  • 在日常网站运维工作中,我们需要对网站客户端访问情况做统计、汇总、分析和报表展示,以数据来全面掌控网站运营和访问情况。当不可预知意外情况发生时,我们可以快速发现问题以及采取相应措施。比如:当网站受...
  • 存储

    2018-01-19 12:34:08
    在大数据HBase中与Hive中都有用到(族)式存储存储被广泛应用,有关于HBase讲解,请访问我 https://yq.aliyun.com/articles/376750?spm=a2c4e.11155435.0.0.62bc19c8kgVjfV。 今天来说一下什么是式...
  • 对性能具有很大提升,同时对SQL基本不做索引优化,查询时直接可以按照列存DB2 10.5引入列式存储表技术,作为DW数据应用的特性,对性能具有很大提升,同时对SQL基本不做索引优化,查询时直接可以按照列存储格式...
  • 然而由于列存储的处理对象是列,此时传统的基于规则的查询优化方法并不完全适用.文中首先比较了列存储系统中查询优化与行存储系统的不同,在此基础上提出适合于列存储的启发式查询优化机制,其中包括启发式优化策略、...
  • 近些年来, 一种新的数据存储理念, 即基于列存储的关系型数据库( 简称列数据库, 下同)应运而生。列数据库能够快速发展, 主要原因是其复杂查询效率高, 读磁盘少, 存储空间少, 以及由此带来的技术、管理和应用优势。对...
  • HUABASE:基于列存储的关系型数据库系统 HUABASE是基于列存储的关系型数据库系统。列存储技术的特点是数据查询效率高,读磁盘少,存储空间少,是构建数据仓库的理想架构。HUABASE实现了多种数据压缩机制、查询优化...
  • 摘要:DB2V10.5正是在这一背景下应运而生,这也使得构建基于列存储的数据仓库成为可能。这篇文章将介绍使用DB2WarehouseV10.5时,构建列存储数据仓库的一系列最佳实践,并且穿插阐述了数据仓库数据流设计时的一些细.....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,250
精华内容 2,100
关键字:

列存储的应用