大数据技术的一些题目

1. kafka相关

1.1 怎么解决kafka的数据丢失

producer端: 宏观上看保证数据的可靠安全性,肯定是依据分区数做好数据备份,设立副本数。

broker端: topic设置多分区,分区自适应所在机器,为了让各分区均匀分布在所在的broker中,分区数要大于broker数。 分区是kafka进行并行读写的单位,是提升kafka速度的关键。

Consumer端: consumer端丢失消息的情形比较简单:如果在消息处理完成前就提交了offset,那么就有可能造成数据的丢失。由于Kafka consumer默认是自动提交位移的,所以在后台提交位移前一定要保证消息被正常处理了,因此不建议采用很重的处理逻辑,如果处理耗时很长,则建议把逻辑放到另一个线程中去做。为了避免数据丢失,现给出两点建议: enable.auto.commit=false 关闭自动提交位移 在消息被完整处理之后再手动提交位移。

1.2 Kafka中的ISRAR是什么?

ISR: In-Sync Replicas 副本同步队列, 由leader维护, 当follower与leader之间的延迟超过阈值时, follower会被从ISR中踢出, 进入OSR

AR: Assigned Replicas 所有副本

1.3 Kafkamessage包括哪些信息

一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成 header部分由一个字节的magic(文件格式)和四个字节的CRC32(用于判断body消息体是否正常)构成。当magic的值为1的时候,会在magic和crc32之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果magic的值为0,那么不存在attributes属性 body是由N个字节构成的一个消息体,包含了具体的key/value消息

1.4 为什么使用Kafka还需要zookeeper?

Kafka通过zookeeper进行集群管理, 并在集群中存储节点, offset等元信息. 早期版本的kafka在客户端连接时亦需要直接与zookeeper建立连接, 新的kafka客户端使用了自己的通信协议, 不需要客户端直接与zookeeper简历连接. 但是kafka所有的节点依然需要和zookeeper建立连接.

1.5 Kafka是如何存储数据的, 它为什么要这样做

Kafka最核心的思想是使用磁盘,而不是使用内存,可能所有人都会认为,内存的速度一定比磁盘快,我也不例外。在看了Kafka的设计思想,查阅了相应资料再加上自己的测试后,发现磁盘的顺序读写速度和内存持平。 而且Linux对于磁盘的读写优化也比较多,包括read-ahead和write-behind,磁盘缓存等。如果在内存做这些操作的时候,一个是JAVA对象的内存开销很大,另一个是随着堆内存数据的增多,JAVA的GC时间会变得很长,使用磁盘操作有以下几个好处: 磁盘缓存由Linux系统维护,减少了程序员的不少工作。 磁盘顺序读写速度超过内存随机读写。 JVM的GC效率低,内存占用大。使用磁盘可以避免这一问题。 系统冷启动后,磁盘缓存依然可用。

1.6 Kafkaconsumer group 是什么概念

对于kafka同一个topic中的一条消息, 会广播给不同的group, 二同一个group中的worker只有一个能得到这条消息.

2. Spark相关

2.1 Spark RDD 什么情况下会产生宽依赖, 什么情况产生窄依赖?

宽依赖 -> 父RDD的分区被子RDD的多个分区使用 例如 groupByKey、reduceByKey、sortByKey等操作会产生宽依赖,会产生shuffle

窄依赖 -> 父RDD的每个分区都只被子RDD的一个分区使用 例如map、filter、union等操作会产生窄依赖

2.2  Spark中的cachepersist缓存方式有何区别?

cache内部还是会调用persist的, 只是缓存的方式会直接使用内存来存储缓存的数据

而persist时则可以选择缓存级别, 分别有:

  1. MEMORY_ONLY存储于内存
  2. MEMORY_AND_DISK 优先内存存储, 空间不足则使用磁盘
  3. DISK_ONLY 存储在磁盘上

2.3 Spark streaming 读取kafka数据的方式有哪几种, 分别是如何做到的

  1. 通过receiver读取
    使用Kafka的高层次Consumer API来实现。receiver从Kafka中获取的数据都存储在Spark Executor的内存中,然后Spark Streaming启动的job会去处理那些数据。然而,在默认的配置下,这种方式可能会因为底层的失败而丢失数据。如果要启用高可靠机制,让数据零丢失,就必须启用Spark Streaming的预写日志机制(Write Ahead Log,WAL)。该机制会同步地将接收到的Kafka数据写入分布式文件系统(比如HDFS)上的预写日志中。所以,即使底层节点出现了失败,也可以使用预写日志中的数据进行恢复。
  2. 通过Direct方式读取(spark 1.3+)
    这种方式会周期性地查询Kafka,获得每个topic+partition的最新的offset,从而定义每个batch的offset的范围。当处理数据的job启动时,就会使用Kafka的简单consumer api来获取Kafka指定offset范围的数据。

2.4 RDD: {(1,2),(3,4),(5,6)}执行.mapValues(x=>x*2)的结果?

{(1,4),(3,8),(5,12)}

2.5 datanode 首次加入 cluster 的时候,如果 log 报告不兼容文件版本. 是否需要namenode执行格式化操作,这样处理的原因是?

不需要进行namenode格式化操作,namenode 格式化时会清空 dfs/name 下空两个目录下的所有文件,之后,会在目录 dfs.name.dir 下创建文件, 这样会导致原有数据丢失.

文件版本不兼容,有可能时 namenode 与 datanode 的 数据里的 namespaceID、clusterID 不一致,找到两个 ID 位置,修改为一样即可解决。

3. haoop 相关

3.1 介绍一下Hadoop MapReduce计算框架中的shuffle过程

Map端的shuffle:

Map端会处理输入数据并产生中间结果,这个中间结果会写到本地磁盘,而不是HDFS。每个Map的输出会先写到内存缓冲区中,当写入的数据达到设定的阈值时,系统将会启动一个线程将缓冲区的数据写到磁盘,这个过程叫做spill。   在spill写入之前,会先进行二次排序,首先根据数据所属的partition进行排序,然后每个partition中的数据再按key来排序。partition的目是将记录划分到不同的Reducer上去,以期望能够达到负载均衡,以后的Reducer就会根据partition来读取自己对应的数据。接着运行combiner(如果设置了的话),combiner的本质也是一个Reducer,其目的是对将要写入到磁盘上的文件先进行一次处理,这样,写入到磁盘的数据量就会减少。最后将数据写到本地磁盘产生spill文件(spill文件保存在{mapred.local.dir}指定的目录中,Map任务结束后就会被删除)。最后,每个Map任务可能产生多个spill文件,在每个Map任务完成前,会通过多路归并算法将这些spill文件归并成一个文件。至此,Map的shuffle过程就结束了。

Reduce端的shuffle:

Reduce端的shuffle主要包括三个阶段,copy、sort(merge)和reduce。首先要将Map端产生的输出文件拷贝到Reduce端,但每个Reducer如何知道自己应该处理哪些数据呢?因为Map端进行partition的时候,实际上就相当于指定了每个Reducer要处理的数据(partition就对应了Reducer),所以Reducer在拷贝数据的时候只需拷贝与自己对应的partition中的数据即可。每个Reducer会处理一个或者多个partition,但需要先将自己对应的partition中的数据从每个Map的输出结果中拷贝过来。   接下来就是sort阶段,也成为merge阶段,因为这个阶段的主要工作是执行了归并排序。从Map端拷贝到Reduce端的数据都是有序的,所以很适合归并排序。最终在Reduce端生成一个较大的文件作为Reduce的输入。

3.2 MapReduce中如何进行全排序?

多数情况下会使用单个reduce进行排序, 如果存在性能瓶颈, 可以使用terasort, hadoop自带了teragen和terasort, 分别用于主数据生成和排序.

3.3 如何应对MapReduce计算中出现的倾斜?

  1. 参数调优(如增加reduce端内存)
  2. 自定义分区策略
  3. 在map端进行数据关联
  4. 在不损害业务的情形下, 剔除那些产生倾斜的key

4. HDFS相关

4.1 请描述HDFSfsimage文件和edits log的区别

大家都知道namenode与secondary namenode 的关系,当他们要进行数据同步时叫做checkpoint时就用到了fsimage与edit,fsimage是保存最新的元数据的信息,当fsimage数据到一定的大小事会去生成一个新的文件来保存元数据的信息,这个新的文件就是edit,edit会回滚最新的数据。

5. Hbase相关

5.1 请介绍一下HBase适用的场景

半结构化或非结构化数据 - 由于hbase可以动态添加列, 因此对于不确定的数据结构, 非常适合使用hbase

数据在不同列上的量很稀疏 - 行存储的列数是是固定的, 这样导致null的字段浪费存储空间。由于hbase按列存储, null字段不占用空间, 因此这种方式非常适合hbase

多版本数据 - 由于Hbase能够在Value上存储多个版本的数据, 因此对于须要存储变动历史记录的数据, Hbase非常适合.

高并发的写入场景 - HBase采用WAL方式写入, 提供高可用,高并发数据写入

数据处理逻辑相对固定 - 由于HBase不像关系型数据库能灵活支持关联查询, 它更适用于简单的业务场景.

5.2 描述 Hbase scan get 的功能以及实现的异同.

Get按指定RowKey获取唯一一条记录 ,get方法方法处理分两种: 设置了ClosestRowBefore 和没有设置的 rowlock .

主要是用来保证行的事务性,即每个get 是以一个 row 来标记的.一个 row 中可以有很多 family 和 column.

5.3 描述Hbase设计rowKey时的原则

rowkey 长度原则

rowkey 是一个二进制码流,可以是任意字符串,最大长度 64kb,实际应用中一般为 10-100bytes,以 byte[]形式保存,一般设计成定长。建议越短越好,不要超过 16 个字节, 原因如下:

数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 rowkey 过长会极大影响 HFile 的存储效率 MemStore 将缓存部分数据到内存,如果 rowkey 字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率。

rowkey 散列原则

如果 rowkey 按照时间戳的方式递增,不要将时间放在二进制码的前面,建议将 rowkey 的高位作为散列字段,由程序随机生成,低位放时间字段,这样将提高数据均衡分布在每个 RegionServer,以实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息,所有的数据都会集中在一个 RegionServer 上,这样在数据检索的时候负载会集中在个别的 RegionServer 上,造成热点问题,会降低查询效率。

rowkey 唯一性原则

必须在设计上保证其唯一性,rowkey 是按照字典顺序排序存储的,因此, 设计 rowkey 的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

5.4 HBase是如何处理RegionServer崩溃的问题的?

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

6. ES相关

6.1 详细描述一下ES索引文档的过程?

这里的索引文档应该理解为文档写入ES,创建索引的过程。

  1. 客户端向集群某节点写入数据,发送请求。(如果没有指定路由/协调节点,请求的节点扮演协调节点的角色。)
  2. 协调节点接受到请求后,默认使用文档ID参与计算(也支持通过routing),得到该文档属于哪个分片。随后请求会被转到另外的节点。
  3. 当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒)写入到Filesystem Cache,这个从Momery Buffer到Filesystem Cache的过程就叫做refresh;
  4. 当然在某些情况下,存在Memery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;
  5. 在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。
  6. flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时。

补充:关于Lucene的Segement

Lucene索引是由多个段组成,段本身是一个功能齐全的倒排索引。段是不可变的,允许Lucene将新的文档增量地添加到索引中,而不用从头重建索引。对于每一个搜索请求而言,索引中的所有段都会被搜索,并且每个段会消耗CPU的时钟周、文件句柄和内存。这意味着段的数量越多,搜索性能会越低。为了解决这个问题,Elasticsearch会合并小段到一个较大的段,提交新的合并段到磁盘,并删除那些旧的小段。(段合并)

6.2 ES中的倒排索引是什么?

倒排索引,是通过分词策略,形成了词和文章的映射关系表,也称倒排表,这种词典+映射表即为倒排索引。其中词典中存储词元,倒排表中存储该词元在哪些文中出现的位置。

有了倒排索引,就能实现O(1)时间复杂度的效率检索文章了,极大的提高了检索效率。

加分项:

倒排索引的底层实现是基于:FST(Finite State Transducer)数据结构。Lucene从4+版本后开始大量使用的数据结构是FST。FST有两个优点:

  1. 空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;
  2. 查询速度快。O(len(str))的查询时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值