1、请简述 Hbase 的数据结构和存储架构
数据结构:hbase数据结构包括:命名空间,行键,列簇,列,时间戳,数据ceil。
命名空间:类似于关系型的数据库,存放表的空间行键:也就是rowkey,唯一标识列簇:也就是一个大的类,一个数据集,数量是固定的列:列就是通俗的一列,一个列簇可以拥有多个列,列可以增加
时间戳:每次的数据更新都会跟新时间戳,可以通过时间戳获取最新的数据,也解决了hdfs不能随时间修改的弊端数据ceil:也就是hbase中的数据全是字符串类型
存储架构:Client(客户端)、Master(主节点)、HRegionServer(维护HRegion)、HLog(日志)、HRegion(维护若干个Store)、Store(具体数据存放)、StoreFile(持久化到HDFS)、MemStore(内存存储)、Zookeeper(监控集群和存放root映射信息)
2、请简述 Hbase 查询数据的流程
首先访问zookeeper,获取meta文件所在HRegionServer的位置,获取meta文件加载之内存,获取rowkey对应HRegion的位置由于存在多个HRegion中,故此创建多个HRegionScanner,StoreScanner扫描器,先扫描MemStore是否存储在,再扫描StoreFile,最后返回结果
3、请简述 Hbase 写询数据的流程
首先建立连接,将写入操作追加到HLog日志中,在获取zookeeper中meta文件的位置信息,获取meta中指定的rowkey映射的HRegion信息后,进行数据写入,写到MemStore,默认达到128MB时,进行一个刷写到硬盘,变成StoreFile,随着不断的StoreFile变多,StoreFile会进行一个数据的的合并
4、请阐述 Spark 中的缓存机制 cache 和 persist 与 checkpoint 的区别与联系
cache:控制算子之一,cache() = persist() = persist(StorageLevel.Memory_Only),相当于persist的一种情况,属于惰性加载,第一次不会使用缓存只有二次运算才会使用(代码实现如下)persist:控制算子之一:支持持久化,常用的模式有Memory_Only和Memory_and_Diskcheckpoint:主要用于持久化RDD,将结果持久化到具体的文件中,也是惰性加载(代码实现如下)三者都是控制算子,对数据的不同形式的一种控制和持久化,其中cache基于内存,checkpoints基于硬盘,而persist则是最全面的多种模式皆可实现
object CtrlCache { def main(args: Array[String]): Unit = { //创建连接 val context = new SparkContext(new SparkConf().setMaster("local").setAppName("cache" + System.currentTimeMillis())) //获取数据元 val value: RDD[String] = context.textFile("src/main/resources/user.log") //启动缓存 value.cache() //记录时间 val start: Long = System.currentTimeMillis() //统计数据行数 val count: Long = value.count() //记录结束时间 val end: Long = System.currentTimeMillis() //输出结果 println("数据共"+count+"行,耗时:"+(end-start)+"s") //记录时间 val start1: Long = System.currentTimeMillis() //统计数据行数 val count1: Long = value.count() //记录结束时间 val end1: Long = System.currentTimeMillis() //输出结果 println("数据共"+count1+"行,耗时:"+(end1-start1)+"s") }}
object CheckPoint { def main(args: Array[String]): Unit = { //创建连接 val context = new SparkContext(new SparkConf().setMaster("local").setAppName("cache" + System.currentTimeMillis())) //获取数据元 val value: RDD[String] = context.textFile("src/main/resources/user.log") //设置检查点路径 context.setCheckpointDir("./point") //对数据进行分区 val partiton: RDD[String] = value.flatMap(_.split(" ")) //获取分区数 println("分区数:"+partiton.getNumPartitions) //持久化 value.checkpoint() //持久化数量 value.count() context.stop() }}
5、RDD 的五大属性?请列举出常用的 RDD 算子及作用?
五大属性:
① RDD由一组partition分区组成
② RDD之间相互依赖
③ RDD计算出最佳的计算位置
④ 分区器用于key -value的RDD上
⑤ 函数作用在每一个分片上RDD常用算子以及作用:
– 转换算子:
map:进一出一,对数据进行切分等处理
flatMap:与map类似先map后flat,多用于分区
sortByKey:用于k-vRDD上,排序
reduceByKey:将相同的Key的数据进行处理
– 行动算子:
count:返回数据集中的元素个数
foreach:循环遍历数据集中每个元素
collect:将计算结果回收到Driver端
– 控制算子:cache ,persist,checkpoint(略)
6、Spark 宽窄依赖的作用是什么?
宽依赖:意味着父RDD与子RDD之间的partition分区关系是一对多,这样会导致shuffle洗牌的产生
窄依赖:意味着父RDD与子RDD之间的partition分区之间的关系是一对一或者是多对一的关系,不会产生shuffle洗牌操作
作用:spark通过宽窄依赖来划分stage