ITPub博客

首页 > 大数据 > > 大数据面试荟萃(一)

大数据面试荟萃(一)

作者:浪花小雨滴 时间:2020-05-09 10:51:35 0 删除 编辑

1 一句话概括HBase

HBase 是一个分布式的、可伸缩的数据存储,其支持行级别的数据更新,快速查询和行级事务(不支持多行事务)。相比 Hive,Hive 是不支持单行事务的。

怎么理解支持行级事务,但是不支持多行事务呢?参考以下博客。

HBase 数据会首先写入 WAL,再写入 Memstore。写入 Memstore 异常很容易可以回滚,因此保证写入/更新原子性只需要保证写入 WAL 的原子性即可。

2 HBase和Hadoop之间是什么关系

HBase 使用 HDFS(或其他某种分布式文件系统,如 S3等等)来持久化存储数据。为了可以提供行级别的数据更新和快速查询,HBase 也使用了内存缓存技术对数据和本地文件进行追加数据更新操作日志。持久化文件将定期地使用附加日志更新进行更新等操作。

3 Hive 中分区表是怎么回事

对数据分区,也许最重要的原因就是为了更快的查询速度。注意分区表实际上是将数据存储到不同的分区目录里,并且可以控制每次查询扫描指定的文件目录,而非全局扫描。这就是分区的意义所在。

4 HBase 查询的整个过程

From: hbasefly.com/2016/12/21

和写流程相比,HBase 读数据是一个更加复杂的操作流程,这主要基于两个方面的原因:

  1. 因为整个 HBase 存储引擎基于 LSM-Like 树实现,因此一次范围查询可能会涉及多个分片、多块缓存甚至多个数据存储文件
  2. 其二是因为 HBase 中更新操作以及删除操作实现都很简单,更新操作并没有更新原有数据,而是使用时间戳属性实现了多版本。删除操作也并没有真正删除原有数据,只是插入了一条打上”deleted”标签的数据,而真正的数据删除发生在系统异步执行 Major_Compact 的时候。

很显然,这种实现套路大大简化了数据更新、删除流程,但是对于数据读取来说却意味着套上了层层枷锁,读取过程需要根据版本进行过滤,同时对已经标记删除的数据也要进行过滤。所以本质上,删除是一种写的操作。

总结一句话,HBase 就是写(删)友好,读相对不友好。



HBase读取流程 客户端首先会根据配置文件中 zookeeper 地址连接 zk,并读取 /<hbase-rootdir>/meta-region-server 节点信息,该节点信息存储 HBase 元数据(hbase:meta)表所在的 RegionServer 地址以及访问端口等信息。用户可以通过 zk 命令 get /<hbase-rootdir>/meta-region-server 查看该节点信息。

根据 hbase:meta 所在 RegionServer 的访问信息,客户端会将该元数据表加载到本地并进行缓存。然后在表中确定待检索 rowkey 所在的 RegionServer 信息。

根据数据所在 RegionServer 的访问信息,客户端会向该 RegionServer 发送真正的数据读取请求。服务器端接收到该请求之后需要进行复杂的处理。

通过上述对客户端以及 HBase 系统的交互分析,可以基本明确两点:

  1. 客户端只需要配置 zookeeper 的访问地址以及根目录,就可以进行正常的读写请求。不需要配置集群的 RegionServer 地址列表(这个是 HBase 内部协调即可)。
  2. 客户端会将 hbase:meta 元数据表缓存在本地,因此上述步骤中前两步只会在客户端第一次请求的时候发生,之后所有请求都直接从缓存中加载元数据。如果集群发生某些变化导致 hbase:meta 元数据更改,客户端再根据本地元数据表请求的时候就会发生异常,此时客户端需要重新加载一份最新的元数据表到本地。(比如 region 到达上限进行 split,那么元数据就会产生变化吗,此时客户端会重新进行加载)

5 Kafka broker到底是不是无状态的?

From: cnblogs.com/huxi2b/p/84 From: blog.csdn.net/m0_380031

正常情况下 consumer 会在消费完一条消息后线性增加这个 offset。当然,consumer 也可以将 offset 设成一个较小的值,重新消费一些消息。因为 offset 由 consumer 控制,所以 Kafka broker 是无状态的

我猜想作者的意思应该是: broker 不保存消费者 consumer 的状态。如果从这个角度来说,broker 无状态的说法倒也没有什么问题。不过实际上,broker 是有状态的服务: 每台 broker 在内存中都维护了集群上所有节点和 topic 分区的状态信息——Kafka 称这部分状态信息为元数据缓存(metadata cache)。

1 cache里面存了什么? 首先 cache 里面都存了什么,以 Kafka 1.0.0版本作为分析对象。Metadata cache 中保存的信息十分丰富,几乎囊括了 Kafka 集群的各个方面,它包含了: 1.1 controller 所在的 broker ID,即保存了当前集群中 controller 是哪台 broker。 1.2 集群中所有 broker 的信息。比如每台 broker 的 ID、机架信息以及配置的若干组连接信息(比如配置了 PLAINTEXT 和 SASL 监听器就有两套连接信息,分别使用不同的安全协议和端口,甚至主机名都可能不同)。 1.3 集群中所有节点的信息。严格来说,它和上一个有些重复,不过此项是按照 broker ID 和监听器类型进行分组的。对于超大集群来说,使用这一项缓存可以快速地定位和查找给定节点信息,而无需遍历上一项中的内容。 1.4 集群中所有分区的信息。所谓分区信息指的是分区的 leader、ISR 和 AR 信息以及当前处于 offline 状态的副本集合。这部分数据按照 topic 和分区 ID 进行分组,可以快速地查找到每个分区的当前状态。(注:AR表示assigned replicas,即创建topic时为该分区分配的副本集合)

2 每台 broker 都保存相同的 cache 吗? 是的,至少 Kafka 在设计时的确是这样的愿景:每台 Kafka broker 都要维护相同的缓存,这样客户端程序(clients)随意地给任何一个 broker 发送请求都能够获取相同的数据,这也是为什么任何一个 broker 都能处理 clients 发来的 Metadata 请求的原因: 因为每个 broker 上都有这些数据!要知道目前 Kafka 共有38种请求类型,能做到这一点的可谓少之又少。每个 broker 都能处理的能力可以缩短请求被处理的延时从而提高整体 clients 端的吞吐,因此用空间去换一些时间的做法是值得的。

3 cache 是怎么更新的? 如前所述,用空间去换时间,好处是降低了延时,提升了吞吐,但劣势就在于你需要处理 cache 的更新并且维护一致性。目前 Kafka 是怎么更新 cache 的?简单来说,就是通过发送异步更新请求(UpdateMetadata request)来维护一致性的。既然是异步的,那么在某一个时间点集群上所有 broker 的 cache 信息就未必是严格相同的。 只不过在实际使用场景中,这种弱一致性似乎并没有太大的问题。原因如下:

  1. clients 并不是时刻都需要去请求元数据的,且会缓存到本地;
  2. 即使获取的元数据无效或者过期了,clients 通常都有重试机制,可以去其他 broker 上再次获取元数据;
  3. cache 更新是很轻量级的,仅仅是更新一些内存中的数据结构,不会有太大的成本。因此我们还是可以安全地认为每台 broker 上都有相同的 cache 信息。具体的更新操作实际上是由 controller 来完成的。controller 会在一定场景下向特定 broker 发送 UpdateMetadata 请求令这些 broker 去更新它们各自的 cache,这些 broker 一旦接收到请求便开始全量更新——即清空当前所有 cache 信息,使用 UpdateMetadata 请求中的数据来重新填充 cache。

4 cache什么时候更新? 实际上这个问题等同于: controller 何时向特定 broker 发送 UpdateMetadata 请求? 如果从源码开始分析,那么涉及到的场景太多了,比如 controller 启动时、新 broker 启动时、更新 broker 时、副本重分配时等等。 我们只需要记住: 只要集群中有 broker 或分区数据发生了变更就需要更新这些 cache。 举个经常有人问的例子,集群中新增加的 broker 是如何获取这些 cache,并且其他 broker 是如何知晓它的?当有新 broker 启动时,它会在 Zookeeper 中进行注册,此时监听 Zookeeper 的 controller 就会立即感知这台新 broker 的加入,此时 controller 会更新它自己的缓存(注意:这是 controller 自己的缓存,不是本文讨论的 metadata cache)把这台 broker 加入到当前 broker 列表中,之后它会发送 UpdateMetadata 请求给集群中所有的 broker (也包括那台新加入的 broker)让它们去更新 metadata cache。一旦这些 broker 更新 cache 完成,它们就知道了这台新 broker 的存在,同时由于新 broker 也更新了 cache,故现在它也有了集群所有的状态信息。

5 目前的问题? 前面说过了,现在更新 cache 完全由 controller 来驱动,故 controller 所在 broker 的负载会极大地影响这部分操作(实际上,它会影响所有的 controller 操作)。根据目前的设计,controller 所在 broker 依然作为一个普通 broker 执行其他的clients请求处理逻辑,所以如果 controller broker 一旦忙于各种 clients 请求(比如生产消息或消费消息),那么这种更新操作的请求就会积压起来(backlog),造成了更新操作的延缓甚至是被取消。究其根本原因在于当前 controller 对待数据类请求和控制类请求并无任何优先级化处理——controller一视同仁地对待这些请求,而实际上我们更希望 controller 能否赋予控制类请求更高的优先级。社区目前已经开始着手改造当前的设计,相信在未来的版本中此问题可以得到解决。

6 说说Hive视图的作用

视图可以允许保存一个查询,并可以像对待表一样对这个查询进行操作。这是一个逻辑结构,因为它不像一个表会存储数据。换句话说,Hive 目前不支持物化视图。当一个查询引用一个视图时候,这个视图所定义的查询语句将和用户的查询语句组合在一起,然后供 Hive 制定查询计划。从逻辑上讲,可以想象为 Hive 先执行这个视图,然后使用这个结果进行余下后续的查询。

7 关于Hive的索引功能

Hive 的索引功能有限,但是还是可以对一些字段建立索引来加速某些操作的。一张表的索引数据存储在另外一张表。当逻辑分区实际上太多太细而几乎无法使用的时候,建立索引也就成为分区的另一个选择。

建立索引可以帮助裁剪掉一张表的一些数据块,这样能够减少 MapReduce 的输入数据量。并非所有的查询都可以通过建立索引获得好处,通过 Explain 命令可以查看某个查询语句是否用到了索引。

Hive 中的索引和那些关系型数据库的一样,需要仔细评估才可以使用,维护索引是需要额外的存储空间 的,同时创建索引也需要消耗计算资源。

关于 Hive 的索引构建过程可以参考这篇文章。

8 Hive表中的压缩,I/O和CPU怎么取舍

MapReduce 任务往往是 I/O 密集型的(反复的读写磁盘),因此 CPU 开销通常不是问题。不过对于工作流 Pipeline,这样的 CPU 密集型场景,例如一些机器学习算法。压缩实际上肯能会从更多必要的操作中获取宝贵的 CPU 资源,从而降低性能。所以这个表是否需要压缩,取决于其业务类型,机器学习的,肯定不建议压缩的,因为解压缩是需要耗费 CPU 资源的,因为本来属于计算密集型的作业,CPU 资源比较重要,如果是 ETL 作业,那就还好,经过压缩的数据集会更小,更利于网络传输,而且 MR 本来属于 IO 密集型,可以提供一些 CPU 资源来做这个工作。

9 HBase是列式存储的数据库吗,或者说是传统的那种列式数据库吗

有点冷门,因为从典型的关系型数据库来看,他并不是一个列式存储的数据库(但实际会认为他是列式存储数据库),但是因为 HBase 利用了磁盘上的列式存储格式,这也是关系型数据库和 HBase 最大的相似之处,因为 HBase 以列式存储的格式在磁盘上存储数据。但它与传统的列式数据库有很大的不同,传统的列式数据库比较适合实时存储数据的场景,HBase 比较适合键值对的存取,或有序的数据存取。

10 说说数据库的一致性

数据库必须保证每一步操作都是从一个一致的状态到下一个一致的状态。一致性可以按照严格程度由强到弱划分,或者是按照对客户端保证程度分类。

  1. 严格一致性: 数据的变化是原子的,一经改变即时生效,这是一致性的最高形式
  2. 顺序一致性: 每个客户端看到的数据依照他们操作执行的顺序而变化
  3. 因果一致性: 客户端以因果关系顺序观察到数据的改变
  4. 最终一致性: 在没有更新数据的一段时间里,系统将通过广播保证副本之间的数据一致性
  5. 弱一致性: 没有做出保证的

11 什么是HBase的Region

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

12 说说Region分区的过程

一张表初始只有一个 region,用户开始向表中插入数据的时候,系统会检查这个 region 的大小,确保其不超过配置的最大值,如果超过限制,系统会在中间键将这个 region 分成大致相等的子 region。每一个 region 只能由一台 region 服务器 RegionServer 加载,每一台 region 服务器(RegionServer)可以同时加载多个 region。一个表实际上是一个由很多 region 服务器加载的 region 集合的逻辑视图。

13 简单说说HBase是怎么写的

每次更新数据的时候,都会先把数据记录在提交日志(commit log)中,在 HBase 中,这叫做预写日志(WAL),然后才会把这些数据写入内存的 Memstore 中。一旦内存保存的写入数据的累计大小超过了一个给定的最大值,系统就会把这些数据移出内存,作为 HFile 文件刷写到磁盘中。数据移出内存后,系统会丢弃对应的提交日志,大小有限,只保留未持久化到磁盘的提交日志。



14 从HBase读取的数据又是怎样的

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

15 说说HFile合并

随着 Memstore 的数据不断被刷写到磁盘中,会产生越来越多的 HFile 文件(磁盘上),HBase 内部有一个节俭空间的管家机制,即合并将多个文件合并成一个较大的文件。合并有两种类型,minor 合并和 major 压缩合并。

  1. minor 合并: 是一个多路归并的过程,把多个小文件重写为数量较少的大文件,减少存储文件的数量,合并速度很快,只受到磁盘 I/O 的影响。
  2. major 合并: 将一个 region 中的一个列族的若干个 HFile 重写为一个新的 HFile,能够扫描所有的 kv 对,顺序重写全部数据,重写数据的过程中略过做了删除标记的数据,断言删除此时生效(删除数据在此时会进行物理删除),对于那些超过版本号限制或者生存时间到期的数据,在重写数据的时候就不会刷入磁盘了。

需要注意的是 major 合并的时候,只会对一个列族的 HFile 进行合并。

16 HBase Master的作用

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

17 介绍几个常用的Hbase Shell的命令

# 查看 master 数量和 regionServer 数量
hbase(main):002:0> status
1 active master, 1 backup masters, 6 servers, 0 dead, 153.5000 average load

18 HBase安装有什么要求

一般为了能够像 MapReduce 一样有效地利用 HDFS,HBase 大多是与 Hadoop 安装在一起,这样能够很大程度减少对网络 I/O 的需求,同时加快处理速度。当在一台服务器上运行 Hadoop 和 HBase,将最少会有3个 Java 进程,DataNode, TaskTracker 和 RegionServer 在运行,而且当执行 MapReduce 操作的时候,进程数还会激增。

master 服务器其实不需要太多的存储空间,不需要挂载过多的硬盘,master 重要性显然要优于 slave,所以需要通过冗余来提高硬件使用率。

19 关于HBase的原子性

HBase 的所有修改数据的操作都保证了行级别的原子性(能支持行级事务,Hive 不行),这会影响到这一行数据所有的并发读写操作。换句话说,其他客户端或者线程对同一行的读写操作都不会影响该行的数据的原子性,要么读到最新的修改,要么等待系统允许写入该行的操作(强一致性)。

通常正常负载和常规操作,客户端操作不会受到其他修改数据的客户端的影响,因为他们之间的冲突可以忽略不计。但是当许多客户端需要同时修改同一行数据的时候就会有问题,因此建议用户尽量使用批量处理更新,来减少单独操作做同一行数据的次数(同时)。

20 HBase rowlock 有什么用

在初始化 Put 对象的时候,如果需要频繁地重复修改某些行(加锁),用户有必要创建一个 RowLock 实例来防止其他客户端访问这些行。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3128025/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39960