大数据面试系列之——Hbase

Hbase是一个分布式的列式存储的数据库

1.说说Hbase的特点
  • 1.分布式架构,Hbase通过集群存储数据,数据最终会落到HDFS上
  • 2.是一种NoSQL的非关系型数据库,不符合关系型数据库的范式
  • 3.面向列存储,底层基于key-value结构
  • 4.适合存储半结构化、非结构化的数据
  • 5.适合存储稀疏的数据,空的数据不占用空间
  • 6.提供实时的增删改查的能力,但是不提供严格的事务机制,只能在行级别提供事务
2.Hbase的架构组成及其作用
  • 1.Zookeeper,作为分布式的协调。RegionServer也会把自己的信息写到ZooKeeper中。
  • 2.HDFS是Hbase运行的底层文件系统
  • 3.RegionServer,理解为数据节点,存储数据的
  • 4.Master RegionServer要实时的向Master报告信息。Master知道全局的RegionServer运行情况,可以控制RegionServer的故障转移和Region的切分
3.说说行存储和列存储的特点
  • 1.行存储在磁盘上的存储是连续的;列存储在磁盘上的存储是不连续的
  • 2.从写入性能上对比,写入次数越少性能越高。因为针对磁盘的每一次写入,都要发生磁头调度,产生寻道时间。因为行存储是只写一次而列存储要写多次,所以行存储在写入性能上更有优势
  • 3.从读取性能上对比:
    a. 如果读取的是整表,则行存储性能较高
    b. 如果是读取指定的列,则行存储会产生冗余列,而冗余列的消除是在内存中发生。而列存储则不会存在冗余列
  • 4.在存储数据的时候,如果基于行存储,由于一行数据的字段类型可能不同,所以会产生频繁的数据类型转换;如果是基于列存储,由于同一列数据的类型一般一致,则可以避免频繁的数据类型转换,同时可以考虑一些更好的压缩算法对一列数据进行压缩
4.Hbase行键列族的概念,物理模型,表的设计原则
  • 行键:是hbase表自带的,每个行键对应一条数据。

  • 列族:是创建表时指定的,为列的集合,每个列族作为一个文件单独存储,存储的数据都是字节数组,其中数据可以有很多,通过时间戳来区分。

  • 物理模型:整个hbase表会拆分成多个region,每个region记录着行键的起始点保存在不同的节点上,查询时就是对各个节点的并行查询,当region很大时使用.META表存储各个region的起始点,-ROOT又可以存储.META的起始点。

  • Rowkey的设计原则:各个列族数据平衡,长度原则、相邻原则,创建表的时候设置表放入regionserver缓存中,避免自动增长和时间,使用字节数组代替string,最大长度64kb,最好16字节以内,按天分表,两个字节散列,四个字节存储时分毫秒。

  • 列族的设计原则:尽可能少(按照列族进行存储,按照region进行读取,不必要的io操作),经常和不经常使用的两类数据放入不同列族中,列族名字尽可能短

5.HBase简单读写流程
  • 读:
    找到要读数据的region所在的RegionServer,然后按照以下顺序进行读取:先去BlockCache读取,若BlockCache没有,则到Memstore读取,若Memstore中没有,则到HFile中去读。
  • 写:
    找到要写数据的region所在的RegionServer,然后先将数据写到WAL(Write-Ahead Logging,预写日志系统)中,然后再将数据写到Memstore等待刷新,回复客户端写入完成。
6.请描述如何解决Hbase中region太小和region太大带来的结果

Region过小会发生多次compaction,将数据读一遍并写一遍到hdfs上,占用io,region过大会造成多次split,region会下线,影响访问服务,调整hbase.heregion.max.filesize为256m。

7.Hbase表的设计原则
  • 1、列族的数量及列族的势
    建议将HBase列族的数量设置的越少越好。当前,对于两个或两个以上的列族HBase并不能处理的很好。这是由于HBase的Flushing和压缩是基于Region的。当一个列族所存储的数据达到Flushing的阈值时,该表中所有列族将同时进行Flushing操作。这将带来不必要的I/O开销,列族越多,该特性带来的影响越大。
    此外,还要考虑到同一个表中不同列族所存储的记录数量的差别,即列族的势(Cardinality)。当两个列族数量差别过大时会使包含记录数量较少列族的数据分散在多个Region上,而Region有可能存储在不同的RegionServer上。这样,当进行查询或scan操作的时候,系统效率将会受到影响。

  • 2、行键(RowKey)的设计
    首先应该避免使用时序或单调(递减/递增)行键。因为当数据到来的时候,HBase首先需要根据记录的行键来确定存储的位置,即Region的位置,如果使用时序或单调行键,那么连续到来的数据将被分配到同一个Region中,而此时系统的其他Region/RegionServer处于空闲状态,这是分布式最不希望看到的状态。

  • 3、尽量最小化行键和列族的大小
    在HBase中,一个具体的值由存储该值的行键、对应的列(列族:列)以及该值的时间戳决定。HBase中索引是为了加速随即访问的速度,索引的创建是基于“行键+列族:列+时间戳+值”的,如果行键和列族的大小过大,甚至超过值本身的大小,那么将会增加索引的大小。并且在HBase中数据记录往往非常之多,重复的行键、列将不但使索引的大小过大,也将加重系统的负担

  • 4、版本的数量
    默认情况下为3个,可以通过HColumnDescriptor进行设置,建议不要设置的过大

8.Hbase如何导入数据

使用 MapReduce Job 方式,根据 Hbase API 编写 java 脚本,将文本文件用文件流的方式截取,然后存储到多个字符串数组中,在 put 方法下,通过对表中的列族进行 for 循环遍历列名,用 if 判断列名后进行 for 循环调用 put.add 的方法对列族下每一个列进行设值,每个列族下有几个列就赋值几次,没有表就先创建表。

9.Hbase的存储结构

Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个 HRegion 超过 256M 就要被分割成两个,由 HRegionServer 管理,管理哪些 HRegion由 Hmaster 分配。 HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例,每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个 HFile, HFile 就是实际的存储文件,因此,一个 HRegion 还拥有一个 MemStore 实例。

10.Hbase 和 hive 有什么区别hive 与 hbase 的底层存储是什么?hive是产生的原因是什么?habase是为了弥补hadoop的什么缺陷?
  • Hive和Hbase都是架构在Hadoop上,底层存储都是HDFS
  • 区别:
    • 1.Hive是建立在Hadoop之上为了减少MapReducejobs编写工作的批处理系统,HBase是为了支持弥补Hadoop对实时操作的缺陷的项目
    • 2.想象你在操作RMDB数据库,如果是全表扫描,就用Hive+Hadoop,如果是索引访问,就用HBase+Hadoop
    • 3.Hive query就是MapReduce jobs可以从5分钟到数小时不止,HBase是非常高效的,肯定比Hive高效的多
    • 4.Hive本身不存储和计算数据,它完全依赖于HDFS和MapReduce,Hive中的表纯逻辑
    • 5.hive借用hadoop的MapReduce来完成一些hive中的命令的执行
    • 6.hbase是物理表,不是逻辑表,提供一个超大的内存hash表,搜索引擎通过它来存储索引,方便查询操作
    • 7.hbase是列存储
    • 8.hdfs作为底层存储,hdfs是存放文件的系统,而Hbase负责组织文件
    • 9.hive需要用到hdfs存储文件,需要用到MapReduce计算框架
11.解释下 hbase 实时查询的原理

实时查询,可以认为是从内存中查询,一般响应时间在 1 秒内。 HBase 的机制是数据先写入到内存中,当数据量达到一定的量(如 128M),再写入磁盘中, 在内存中,是不进行数据的更新或合并操作的,只增加数据,这使得用户的写操作只要进入内存中就可以立即返回,保证了 HBase I/O 的高性能

12.列簇怎么创建比较好

rowKey 最好要创建有规则的 rowKey,即最好是有序的。 HBase 中一张表最好只创建一到两个列族比较好,因为 HBase 不能很好的处理多个列族

13.描述 Hbase 中 scan 和 get 的功能以及实现的异同
  • 1.按指定RowKey 获取唯一一条记录, get方法(org.apache.hadoop.hbase.client.Get)Get 的方法处理分两种 : 设置了 ClosestRowBefore 和没有设置的 rowlock .主要是用来保证行的事务性,即每个 get 是以一个 row 来标记的.一个 row 中可以有很多 family 和 column.

  • 2.按指定的条件获取一批记录, scan 方法(org.apache.Hadoop.hbase.client.Scan)实现条件查询功能使用的就是 scan 方式.1)scan 可以通过 setCaching 与 setBatch 方法提高速度(以空间换时间); 2)scan 可以通过 setStartRow 与 setEndRow 来限定范围([start, end]start 是闭区间, end 是开区间)。范围越小,性能越高。3)scan 可以通过 setFilter 方法添加过滤器,这也是分页、多条件查询的基础。

  • 3.全表扫描,即直接扫描整张表中所有行记录

14.请详细描述 Hbase 中一个 Cell 的结构

HBase 中通过 row 和 columns 确定的为一个存贮单元称为 cell。Cell:由{row key, column(= + ), version}是唯一确定的单元 cell中的数据是没有类型的,全部是字节码形式存储

15.请描述 Hbase 中 scan 对象的 setCache 和 setBatch 方法的使用
  • cache:

    • 在默认情况下,如果你需要从hbase中查询数据,在获取结果ResultScanner时,hbase会在你每次调用ResultScanner.next()操作时对返回的每个Row执行一次RPC操作。即使你使用ResultScanner.next(int nbRows)时也只是在客户端循环调用RsultScanner.next()操作,你可以理解为hbase将执行查询请求以迭代器的模式设计,在执行next()操作时才会真正的执行查询操作,而对每个Row都会执行一次RPC操作。
    • 因此显而易见的就会想如果我对多个Row返回查询结果才执行一次RPC调用,那么就会减少实际的通讯开销。这个就是hbase配置属性“hbase.client.scanner.caching”的由来,设置cache可以在hbase配置文件中显示静态的配置,也可以在程序动态的设置。
    • cache值得设置并不是越大越好,需要做一个平衡。cache的值越大,则查询的性能就越高,但是与此同时,每一次调用next()操作都需要花费更长的时间,因为获取的数据更多并且数据量大了传输到客户端需要的时间就越长,一旦你超过了maximum heap the client process 拥有的值,就会报outofmemoryException异常。当传输rows数据到客户端的时候,如果花费时间过长,则会抛出ScannerTimeOutException异常。
  • batch:

    • 在cache的情况下,我们一般讨论的是相对比较小的row,那么如果一个Row特别大的时候应该怎么处理呢?要知道cache的值增加,那么在client process 占用的内存就会随着row的增大而增大。在hbase中同样为解决这种情况提供了类似的操作:Batch。可以这么理解,cache是面向行的优化处理,batch是面向列的优化处理。它用来控制每次调用next()操作时会返回多少列,比如你设置setBatch(5),那么每一个Result实例就会返回5列,如果你的列数为17的话,那么就会获得四个Result实例,分别含有5,5,5,2个列。
16.简述 HBASE 中 compact 用途是什么,什么时候触发,分为哪两种,有什么区别,有哪些相关配置参数?

在 hbase 中每当有 memstore 数据 flush 到磁盘之后,就形成一个 storefile,当 storeFile 的数量达到一定程度后,就需要将 storefile 文件来进行 compaction 操作。

Compact 的作用:

1>.合并文件

2>.清除过期,多余版本的数据

3>.提高读写数据的效率

HBase 中实现了两种 compaction 的方式:

minor and major. 这两种 compaction 方式的区别是:

  • 1、 Minor 操作只用来做部分文件的合并操作以及包括 minVersion=0 并且设置 ttl 的过期版本清理,不做任何删除数据、多版本数据的清理工作。
  • 2、 Major 操作是对 Region 下的 HStore 下的所有 StoreFile 执行合并操作,最终的结果是整理合并出一个文件。
17.简述 Hbase filter 的实现原理是什么?结合实际项目经验,写出几个使用 filter 的场景

HBase 为筛选数据提供了一组过滤器,通过这个过滤器可以在 HBase 中的数据的多个维度(行,列,数据版本)上进行对数据的筛选操作,也就是说过滤器最终能够筛选的数据能够细化到具体的一个存储单元格上(由行键,列名,时间戳定位)。 RowFilter、 PrefixFilter。。。hbase的filter是通过scan设置的,所以是基于scan的查询结果进行过滤.过滤器的类型很多,但是可以分为两大类——比较过滤器,专用过滤器过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端;如在进行订单开发的时候,我们使用rowkeyfilter过滤出某个用户的所有订单

18.Hbase 内部是什么机制

在 HBase 中无论是增加新行还是修改已有行,其内部流程都是相同的。 HBase 接到命令后存下变化信息,或者写入失败抛出异常。默认情况下,执行写入时会写到两个地方:预写式日志(write-ahead log,也称 HLog)和 MemStore。 HBase 的默认方式是把写入动作记录在这两个地方,以保证数据持久化。只有当这两个地方的变化信息都写入并确认后,才认为写动作完成。MemStore 是内存里的写入缓冲区, HBase 中数据在永久写入硬盘之前在这里累积。当MemStore 填满后,其中的数据会刷写到硬盘,生成一个 HFile。 HFile 是 HBase 使用的底层存储格式。 HFile 对应于列族,一个列族可以有多个 HFile,但一个 HFile 不能存储多个列族的数据。在集群的每个节点上,每个列族有一个 MemStore。大型分布式系统中硬件故障很常见, HBase 也不例外。设想一下,如果 MemStore 还没有刷写,服务器就崩溃了,内存中没有写入硬盘的数据就会丢失。 HBase 的应对办法是在写动作完成之前先写入 WAL。 HBase 集群中每台服务器维护一个 WAL 来记录发生的变化。WAL 是底层文件系统上的一个文件。直到 WAL 新记录成功写入后,写动作才被认为成功完成。这可以保证 HBase 和支撑它的文件系统满足持久性。大多数情况下, HBase 使用Hadoop 分布式文件系统(HDFS)来作为底层文件系统。如果 HBase 服务器宕机,没有从 MemStore 里刷写到 HFile 的数据将可以通过回放WAL 来恢复。你不需要手工执行。 Hbase 的内部机制中有恢复流程部分来处理。每台HBase 服务器有一个 WAL,这台服务器上的所有表(和它们的列族)共享这个 WAL。你可能想到,写入时跳过 WAL 应该会提升写性能。但我们不建议禁用 WAL,除非你愿意在出问题时丢失数据。如果你想测试一下,如下代码可以禁用 WAL: 注意:不写入 WAL 会在 RegionServer 故障时增加丢失数据的风险。关闭 WAL,出现故障时 HBase 可能无法恢复数据,没有刷写到硬盘的所有写入数据都会丢失。

19.HBase 宕机如何处理

宕机分为 HMaster 宕机和 HRegisoner 宕机,如果是 HRegisoner 宕机, HMaster 会将其所管理的 region 重新分布到其他活动的 RegionServer 上,由于数据和日志都持久在 HDFS中,该操作不会导致数据丢失。所以数据的一致性和安全性是有保障的。如果是 HMaster 宕机, HMaster 没有单点问题, HBase 中可以启动多个 HMaster,通过Zookeeper 的 Master Election 机制保证总有一个 Master 运行。即 ZooKeeper 会保证总会有一个 HMaster 在对外提供服务

20.导致Hbase挂掉的场景

导致Hbase挂掉的场景

  • HMaster
    HMaster会出现异常(执行abort())停止的场景如下:
    1.zk异常导致的master停止服务是最常见的场景,涉及操作包含但不限于以下:
    a)Zk链接超时,超时时间通过zookeeper.session.timeout配置,默认为3分钟, 如果fail.fast.expired.active.master配置的值为false(默认为false),则不会立即abort,而是会尝试恢复zk的过期session;
    b)在打开region后,需要从zk中删除opened节点,如果zk有该节点,但是删除失败;
    c)在split region过程中,从zk删除split节点时;
    d)Master节点改变时;
    e)从zk中创建unassigned节点时;
    f)在下线disabled的regoin时,从zk中删除disabled的region如果发生zk异常;
    g)还有很多操作zk的节点时如果出现异常。
    2.在assign时,如果设置region为offlined状态,但是region之前的状态不是closed或者offlined;
    3.在assign时,如果无法从.META.表中读取region信息;
    4.把新的hbase集群加入到正在运行的hbase集群时,如果zk的/hbase/unassigned节点没有数据;
    5.使用线程池批量分配region时,如果出现未被捕获的异常,实现方式如下:
    6.在启动master的服务线程时,出现了异常;
    7.在hdfs中检查hbase日志路径时,发现了dead的server时,需从hdfs中读出log,如果出现io异常需要检查hdfs文件系统,如果fsOk状态为true,但是通过FSUtils工具类进行检查时出现io异常;
    8.在校验并且分配-ROOT-的region时,如果zk异常,或者其它异常(其它异常会重试10次),比如:“-ROOT- is onlined on the dead server”。

  • HRegionServer
    HRegionServer会出现异常停止(执行abort())服务的场景如下:
    1.在读写hdfs时如果出现IOException异常,此时会发起hdfs的文件系统检查(checkFileSystem)1.
    2.Regionserver的服务线程出现了未捕获异常;
    3.在启动HRegionServer时出现异常;
    4.在进行HLog回滚时,出现异常;
    5.在flush memstore时,如果持久化失败,会重启RS,在重启中把hlog的内容重新加载到memstore;
    6.出现zk异常,包括但不限于以下场景:
    a)Zk链接超时,超时时间通过zookeeper.session.timeout配置,默认为3分钟,与master不同,如果zk操作不会重试;
    b)启动HRegionServer时出现KeeperException异常;
    c)在进行split操作时,如果出现异常会进行回滚操作,在回滚过程中需要从zk中删除region的spliting状态,如果删除时出现KeeperException或者回滚的其它操作出现异常;
    d)在打开region时,出现了KeeperException异常;
    e)在进行hbase集群复制时,很多与zk交互的操作出现KeeperException异常时均会导致abort;
    7.在close region时,如果出现异常,比如:不能成功的flush memstore;
    8.Flush memstore时,如果HLog发现该region已经在flush则会强制终止JVM,采用的是Runtime.getRuntime().halt(1)方法,该方法不会执行正常退出的关闭钩子,从而不会flush RS的所有region,也不会迁移region,只有等待ZK的session超时后master才会发现该RS不可用,做迁移工作。

  • 总结
    Hbase挂掉的可能性有很多,主要由zk或者hdfs的问题导致,因此zk、hdfs的可用对于hbase极其重要,关于zk:
    1.zk如果停止了服务则在很多时候会导致master、rs挂掉,hbase集群基本上就失去了服务的能力,因此zk一定要是稳定可靠的,当client已经于rs建立了链接,这时zk挂掉,如果不进行split等小数与zk交互失败会导致触发rs的abort()的操作时rs还是可以提供服务的;
    2.如果rs/master进行了长时间的gc或者改动了服务器时间,导致出现zk的session超时会导致rs/master停止服务,目前已经出现了2次因为服务器时间变化导致hbase停止服务的事故;
    3.别轻易人为改变zk的hbase节点数据,master/rs在进行很多操作时会比较依赖zk的数据,如果发现不符合预期可能会导致master/rs停止服务,尤其是master。
    Master通过ZK知道RS是否可用,一般情况下RS在停止服务时均会正常退出,在正常退出时会从ZK中删除/hbase/rs/$regionserver的节点,Master会监听该节点的被删除,从而较快的(速度取决于所有region关闭时间)对该RS负责的region进行重新分配,如果是强制退出,比如 kill -9或者出现HRegionServer挂掉的第8条时则只有等待ZK的session超时时才会删除RS在ZK的节点(RS在ZK中添加节点时采用的是CreateMode.EPHEMERAL模式,该模式创建的节点会在session关闭时自动删除),那时Master才会进行重新assign。
    Kill RS的进程也是正常退出(不能使用kill -9强制退出),RS使用Runtime的addShutdownHook方法注册了jvm关闭钩子,在关闭钩子中会执行RS的退出逻辑,实际上hbase-daemon.sh的停止RS就是采用kill。

21.Hbase的原理 regionserver挂了 如何恢复数据 ?新的数据从Hlog里读出来是如何恢复的

引起RegionServer宕机的原因各种各样,有因为Full GC导致、网络异常导致、官方Bug导致(close wait端口未关闭)以及DataNode异常导致等等

HBase检测宕机是通过Zookeeper实现的, 正常情况下RegionServer会周期性向Zookeeper发送心跳,一旦发生宕机,心跳就会停止,超过一定时间(SessionTimeout)Zookeeper就会认为RegionServer宕机离线,并将该消息通知给Master

一旦RegionServer发生宕机,HBase都会马上检测到这种宕机,并且在检测到宕机之后会将宕机RegionServer上的所有Region重新分配到集群中其他正常RegionServer上去,再根据HLog进行丢失数据恢复,恢复完成之后就可以对外提供服务,整个过程都是自动完成的,并不需要人工介入.

22.讲一下Hbase,Hbase二级索引用过吗

默认情况下,Hbase只支持rowkey的查询,对于多条件的组合查询的应用场景,不够给力。

如果将多条件组合查询的字段都拼接在RowKey中显然又不太可能

全表扫描再结合过滤器筛选出目标数据(太低效),所以通过设计HBase的二级索引来解决这个问题。

这里所谓的二级索引其实就是创建新的表,并建立各列值(family:column)与行键(rowkey)之间的映射关系。这种方式需要额外的存储空间,属于一种以空间换时间的方式

23.Hbase如何优化的
  • 内存优化

    • Ø 垃圾回收优化:CMS, G1(Region)

    • Ø JVM启动:-Xms(1/64) –Xmx(1/4)

  • Region优化

    • Ø 预分区

    • Ø 禁用major合并,手动合并

  • 客户端优化

    • 批处理
  • Hbase配置优化

    • 设置RPC监听数量
      hbase-site.xml
      属性:hbase.regionserver.handler.count
      解释:默认值为 30,用于指定 RPC 监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。

    • 优化 HStore 文件大小
      hbase-site.xml
      属性:hbase.hregion.max.filesize
      解释:默认值 10737418240(10GB),如果需要运行 HBase 的 MR 任务,可以减小此值, 因为一个 region 对应一个 map 任务,
      如果单个 region 过大,会导致 map 任务执行时间过长。该值的意思就是,如果 HFile 的大小达到这个数值,则这个 region 会被切分为两个 Hfile

    • 优化 hbase 客户端缓存
      hbase-site.xml
      属性:hbase.client.write.buffer
      解释:用于指定 HBase 客户端缓存,增大该值可以减少 RPC 调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少 RPC 次数的目的

    • 指定 scan.next 扫描 HBase 所获取的行数
      hbase-site.xml
      属性:hbase.client.scanner.caching
      解释:用于指定 scan.next 方法获取的默认行数,值越大,消耗内存越大。

    • flush、compact、split 机制
      当 MemStore 达到阈值,将 Memstore 中的数据 Flush 进 Storefile;compact 机制则是把 flush 出来的小文件合并成大的 Storefile 文件。split 则是当 Region 达到阈值,会把过大的 Region 一分为二。
      涉及属性:
      即:128M 就是 Memstore 的默认阈值
      hbase.hregion.memstore.flush.size:134217728
      即:这个参数的作用是当单个 HRegion 内所有的 Memstore 大小总和超过指定值时,flush
      该 HRegion 的所有 memstore。RegionServer 的 flush 是通过将请求添加一个队列,模拟生产消费模型来异步处理的。那这里就有一个问题,当队列来不及消费,产生大量积压请求时,可能会导致内存陡增,最坏的情况是触发 OOM。
      hbase.regionserver.global.memstore.upperLimit:0.4
      hbase.regionserver.global.memstore.lowerLimit:0.38
      即:当 MemStore 使用内存总量达到 hbase.regionserver.global.memstore.upperLimit 指定值时,将会有多个 MemStores flush 到文件中,MemStore flush 顺序是按照大小降序执行的,直到刷新到 MemStore 使用内存略小于 lowerLimit

  • HDFS优化

    • NameNode 元数据备份使用 SSD

    • 定时备份 NameNode 上的元数据

      每小时或者每天备份,如果数据极其重要,可以 5~10 分钟备份一次。备份可以通过定时任务复制元数据目录即可。

    • 为 NameNode 指定多个元数据目录
      使用 dfs.name.dir 或者 dfs.namenode.name.dir 指定。这样可以提供元数据的冗余和健壮性, 以免发生故障。

    • NameNode 的 dir 自恢复
      设置 dfs.namenode.name.dir.restore 为 true,允许尝试恢复之前失败的 dfs.namenode.name.dir
      目录,在创建 checkpoint 时做此尝试,如果设置了多个磁盘,建议允许。

    • HDFS 保证 RPC 调用会有较多的线程数
      属性:dfs.namenode.handler.count
      解释:该属性是 NameNode 服务默认线程数,默认值是 10,根据机器的可用内存可以调整为 50~100
      属性:dfs.datanode.handler.count
      解释:该属性默认值为 10,是 DataNode 的处理线程数,如果 HDFS 客户端程序读写请求比较多,可以调高到 15~20,设置的值越大,内存消耗越多,不要调整的过高,一般业务中,
      5~10 即可。
      hdfs-site.xml

    • HDFS 副本数的调整
      属性:dfs.replication
      解释:如果数据量巨大,且不是非常之重要,可以调整为 2~3,如果数据非常之重要,可以调整为 3~5。

      hdfs-site.xml

    • HDFS 文件块大小的调整

      属性:dfs.blocksize
      解释:块大小定义,该属性应该根据存储的大量的单个文件大小来设置,如果大量的单个文件都小于 100M,
      建议设置成 64M 块大小,对于大于 100M 或者达到 GB 的这种情况,建议设置成 256M,一般设置范围波动在 64M~256M 之间。

      hdfs-site.xml

    • MapReduce Job 任务服务线程数调整

      属性:mapreduce.jobtracker.handler.count
      解释:该属性是 Job 任务线程数,默认值是 10,根据机器的可用内存可以调整为 50~100

      mapred-site.xml

    • Http 服务器工作线程数
      mapred-site.xml

      属性:mapreduce.tasktracker.http.threads
      解释:定义 HTTP 服务器工作线程数,默认值为 40,对于大集群可以调整到 80~100

    • 文件排序合并优化
      mapred-site.xml

      属性:mapreduce.task.io.sort.factor
      解释:文件排序时同时合并的数据流的数量,这也定义了同时打开文件的个数,默认值为
      10,如果调高该参数,可以明显减少磁盘 IO,即减少文件读取的次数。

    • 设置任务并发
      mapred-site.xml

      属性:mapreduce.map.speculative
      解释:该属性可以设置任务是否可以并发执行,如果任务多而小,该属性设置为 true 可以明显加快任务执行效率,但是对于延迟非常高的任务,建议改为 false,这就类似于迅雷下载。

    • MR 输出数据的压缩
      mapred-site.xml
      属性:mapreduce.map.output.compress、mapreduce.output.fileoutputformat.compress
      解释:对于大集群而言,建议设置 Map-Reduce 的输出为压缩的数据,而对于小集群,则不需要。

    • 优化 Mapper 和 Reducer 的个数
      mapred-site.xml
      属性:mapreduce.tasktracker.map.tasks.maximum mapreduce.tasktracker.reduce.tasks.maximum
      解释:以上两个属性分别为一个单独的 Job 任务可以同时运行的 Map 和 Reduce 的数量。
      设置上面两个参数时,需要考虑 CPU 核数、磁盘和内存容量。假设一个 8 核的 CPU,业务内容非常消耗 CPU,那么可以设置 map 数量为 4,如果该业务不是特别消耗 CPU 类型的,
      那么可以设置 map 数量为 40,reduce 数量为 20。这些参数的值修改完成之后,一定要观察是否有较长等待的任务,如果有的话,可以减少数量以加快任务执行,
      如果设置一个很大的值,会引起大量的上下文切换,以及内存与磁盘之间的数据交换,这里没有标准的配置数值,
      需要根据业务和硬件配置以及经验来做出选择。
      在同一时刻,不要同时运行太多的 MapReduce,这样会消耗过多的内存,任务会执行的非常缓慢,我们需要根据 CPU 核数,内存容量设置一个 MR 任务并发的最大值,
      使固定数据量的任务完全加载到内存中,避免频繁的内存和磁盘数据交换,从而降低磁盘 IO,提高性能。
      大概估算公式:
      map = 2 + ⅔cpu_core, reduce = 2 + ⅓cpu_core

    • 优化 DataNode 允许的最大文件打开数
      hdfs-site.xml
      属性:dfs.datanode.max.transfer.threads
      解释:HBase 一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为 4096 或者更高。默认值:4096

    • 优化延迟高的数据操作的等待时间
      hdfs-site.xml
      属性:dfs.image.transfer.timeout
      解释:如果对于某一次数据操作来讲,延迟非常高,socket 需要等待更长的时间,建议把该值设置为更大的值(默认 60000 毫秒),以确保 socket 不会被 timeout 掉。

    • 优化数据的写入效率
      mapred-site.xml
      属性:
      mapreduce.map.output.compress mapreduce.map.output.compress.codec
      解释:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec 或者其他压缩方式

    • 优化 DataNode 存储
      属性:dfs.datanode.failed.volumes.tolerated
      解释:默认为 0,意思是当 DataNode 中有一个磁盘出现故障,则会认为该 DataNode shutdown 了。
      如果修改为 1,则一个磁盘出现故障时,数据会被复制到其他正常的 DataNode 上,当前的 DataNode 继续工作。

你可能感兴趣的:(面经,大数据)