数据框架部分总结

spark的优化

1.	开发调优:
    1)	避免创建重复的RDD
    2)	尽可能复用同一个RDD
    3)	对多次使用的RDD进行持久化
    4)	尽量避免使用shuffle类算子
    5)	使用map-side 的预聚合的shuffle
    6)	使用高性能的算子
    7)	广播大变量
    8)	使用Kryo优化序列化性能
    9)	优化数据结构
2.	资源调优
    1)	资源参数调优
        Num-executors 
        excutor-memory 
        executor-cores
        Driver-memory
        Spark.default.parallelsm
        spark.storage.memoryFraction
        spark.shuffle.memoryFraction
3.	数据倾斜调优
    1)	Hive ETL 预处理
    2)	过滤少数导致倾斜的Key
    3)	提高shuffle操作的并行度
    4)	两阶段的聚合(局部聚合+全局聚合)
    5)	将 reduce join转为 map join
    6)	采样倾斜Key 并拆分join操作
    7)	使用随机前缀和扩容RDD进行join
    8)	多种方案组合使用
4.	Shuffle调优
    Spark.shuffle.file.buffer
 	spark.reducer.maxSizeInFlight
 	spark.shuffle.io.maxRetries
 	spark.shuffle.io.retryWait
    spark.shuffle.memoryFraction
    spark.shuffle.manager 

 spark中的partition,task,stage等关系

1. 在HDFS上存储的文件File一般有多个块,成为block。大小一般128M
2. Task 与 partition是对等的。 一个partition 对应(=) 一个task。输入的文件被划分成多个partition进行计算。
3. 一个executor有几个core,则有几个task被并行执行。一个core在一个时间内只能执行一个task任务。
4. 一个物理节点可以有多个worker;一个worker可以开启多个 executor。
5. Task被执行的并发度 = Executor数目 * 每个Executor核数。
6. stage 是以 shuffle为界限划分。一次shuffle是一次stage,所以stage次数 = shuffle次数 + 1。
7. 一个job 由多组task组成,每组任务被称为一个stage

Spark stream 的batch duration,window duration, slide duration

1. Batch Duration: 批处理间隔, 是指Spark streaming以多少时间间隔为单位提交任务逻辑
2. Window Duration:当前一个窗口处理数据的时间跨度。控制每次计算最近的多少个批次的数据。
3. Slide window:控制着计算的频率。用来控制对新的 DStream 进行计算的间隔。

Sql 中的几种join 操作含义

1.  Inner join: 如果表中有至少一个匹配,则返回行          --  并集返回
2.  Left join: 即使右表中没有匹配,也从左表返回所有的行   --  左侧全返回,右侧不存在用null代替
3.  RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行 -- 右侧全返回,左侧不存在用null代替
4.  FULL JOIN: 只要其中一个表中存在匹配,就返回行       -- 左右都返回,不匹配用null表示。

Kafka关于数据流,手动处理offset的问题来处理数据流的问题

1. 有且仅有一次:基于数据库事务将offset保存到第三方数据库,可以实现有且仅有一次。
2. 至少一次:业务处理完成后,再将offset异步提交到kafka上。
3. 至多一次:在业务处理之前,先将offset提交到kafka上。

 Kafka  Producer 三种发送消息的方式

1. Fire-and-forget --- 此方法用来发送消息到broker,不关注消息是否成功到达。大部分情况下,消息会成功到达broker,
因为kafka是高可用的,producer会自动重试发送。但是,还是会有消息丢失的情况;
2. Synchronous Send(同步发送) --- 发送一个消息,send()方法返回一个Future对象,使用此对象的get()阻塞方法可以查看send()方法是否执行成功。
3. Asynchronous Send(异步发送) --- 以回调函数的形式调用send()方法,当收到broker的响应,会触发回调函数执行(Callback)。
 

Kafka  acks参数的含义

acks=0:Producer不会等待broker的回复,Producer会假定消息已成功发送,立即返回。因此可以使用此设置来实现非常高的吞吐量。
acks=1:当leader副本收到消息时,Producer将从Broker接收到成功响应。acks=1时的吞吐量,取决于消息是同步发送还是异步发送。
acks=all/-1:一旦所有处于同步状态的副本收到消息,producer将收到来自broker的成功响应,此种情况,消息延迟会更高。

Kafka key的作用

可以用于存储消息的额外信息
用来决定消息将被写到哪个topic分区中

 kafka相关术语

Broker : 一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
Topic : 一类消息,可以包括多个partition。
Producer : 消息生产者,就是向kafka broker推送消息的客户端。
Consumer : 消息消费者,向kafka broker拉取消息的客户端
Consumer Group (CG): 一组 Consumer 组成的,用来消费 一个 Topic 上不同的 partition。
Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。 kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
Offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息。

Kafka 常见动态参数配置

unclean.leader.election.enable:不严格的leader选举,有助于集群健壮,但是存在数据丢失风险。
min.insync.replicas:如果同步状态的副本小于该值,服务器将不再接受request.required.acks为-1或all的写入请求。
max.message.bytes:单条消息的最大长度。如果修改了该值,那么replica.fetch.max.bytes和消费者的fetch.message.max.bytes也要跟着修改。
cleanup.policy:生命周期终结数据的处理,默认删除。
flush.messages:强制刷新写入的最大缓存消息数。
flush.ms:强制刷新写入的最大等待时长。

Kafka的负载均衡的实现

由于Leader的主要角色是执行分区的所有读和写请求的任务,而Follower则是被动地复制Leader。因此,当Leader失败的时候,一个Follower接管了Leader的角色。整个过程确保了服务器的负载平衡。

Replicas和ISR的作用是什么

在创建Topic时,可以指定分区的副本Replicas个数。用于保证消息不丢失。Replica的个数需要小于等于Broker的个数,所有Partition的Replica默认情况会均匀分布到Broker上。
ISR是指处于同步状态的副本,是一组同步到leader的消息副本。用于保证消息的一致性。

消息传递方法有哪些类型?

队列:在这种方法中,一组用户可以从服务器顺序读取消息。
(传统的队列系统——它通常在处理完成后从队列的末尾删除消息。
Apache Kafka——但是在Kafka中,消息在被处理后仍然存在。这意味着kafka中的信息不会在消费者收到时被删除。)
发布-订阅:消息是向所有消费者广播的。

Kafka调优

Kafka调优可以从三方面考虑:
    Kafka Producer调优(消息压缩、批次大小、同步或异步发送),结合Producer配置项一起学习。
    Kafka Brokers 调优(设置合适的topic partition个数和副本个数,一般情况下,分区个数和副本个数与kafka集群节点个数相同。同时要考虑消费者的个数以及物理磁盘个数。)
    Kafka Consumers调优(为消费组中增加消费者,但是不能大于分区数。选择合适的消费语义。)
 

HBase组件概念

Regionserver: 是存储Hbase的数据的单位
Hmaster: 进行负载均衡的功能, 决定 region 放在哪里.
HRegion:存放hbase中数据的一个概念,可以简单的理解为表,存放一张表中的一部分数据。
HFile:  在hdfs上存放数据之前的一个物理结构,用于接收从客户端提交过来的数据。

Hbase表设计关键点

1. RowKey长度原则:最大长度为64KB,实际应用中一般为10~100bytes,一般设计成定长。建议是越短越好
2. RowKey散列原则:数据存储是按照rowkey字符串的字典顺序,rowkey过于连续会造成存储热点,需要离散存储,就需要把rowkey打散。可以通过对rowkey做reverse操作。
3. RowKey唯一原则:必须在设计上保证其唯一性。

CAP是啥

一致性:所有节点在同一时间数据相同
可用性:有请求有响应,但是不保障每次请求获取的数据正确
分区容错性:系统在任意时刻的数据丢失不能影响整个分布式系统的继续运作。

牺牲一致性保证可用性。

HBASE 读流程

1. 首先从 zk 中找到 meta 表 region 的位置, 然后从 meta 表中获取用户表的region信息
2. 根据 namespace, 表名和 rowkey 在 meta 表中找到对应的 region 信息, 找到对应的regionserver.
3. 定位 region
4. 从 Memstore 找到数据, 如果没有, 再到 storefile 上读取 (为了读取的效率)

HABSE 写流程

1.  通过 zookeeper 找到 meata表的region    
2.  根据相关信息找到 regionserver 
3.  把数据分别写到 HLog 和 memstore 中.

HBase 避免热点问题

某一段时间内,Hbase读写集中在少部分Region上,负载明显过大,其他RegionServer闲置,叫做热点现象.

方案:RowKey设计,预分区,列簇设计,索引表

HBase 性能调优

预分区:对应数据需要写到对应的region中,这个也解决了数据倾斜
Rowkey优化:(QA:Hbase表设计关键点)
Column优化:列族的名称和列的描述名字要短,同一张的ColumnFamilly不要超过3个
Schema优化:宽表和高表(业务场景平衡)事务性、查询性能 、损耗资源等等

Storm处理三种消息的处理模式

at most once:若不实现ack和fail方法,无论后续处理结果如何,消息只会发送一次,必定不能满足高准确性;
at least once:若实现了ack和fail方法,只有调用了ack方法才会任务处理成功,否则会重试。可能会出现消息重复,在并发场景下重复又意味着可能出现乱序;
exactly once:trident每个micro batch作为整体只成功处理一次,但也是无法保证消息真的只正确的处理一次,比如数据已经处理完毕并持久化,但向数据源ack时失败,就可能会有重试。

SparkSQL程序执行过程

1、 先写Dataset API  SQL代码
2、 如果代码没有编译错误,Spark会将代码转换为逻辑计划
3、 Spark会将逻辑计划转换为物理计划,会对代码进行优化(catalyst优化器)
4、 Spark会执行物理计划( RDD )

MapReduce 的操作

Map 任务执行结果输出写入到本地操盘,而不是HDFS。因为:一旦任务完成,映射输出可以扔掉了。所以,复制并将其存储在HDFS变得大材小用。
HDFS:一次写入,多次读取。

storm 的Executor 与Task的关系

1. setNumWorker(2) => setBolt(**,**,4) => setNumberTask(8);  
   2: 两个work进程;4:四个Executor线程,8个Task。
2. 一个Executork可以有多个或等于Task,一个Task对应一个topology。
3. Work属于进程级别;Executork是线程级别;task是topology级别。
4. Work孵化出Executork进程,一个work可以对应多个Executork。
4. Executork,task是可以动态调节的。
5. Executor的数目 = 组件数 + 隐含的ACK数量。

RDD (Resilient Distributed Dataset)的特点

内存计算、 延迟计算、 容错性、 不可变性、 分区、 持久化、 数据本地性

Spark 分区

1. 在集群环境中,读取本地文件/HDFS数据,spark的partition由数据的block个数决定,最小为2
2. 每个partition会运行一个task来处理其中的数据元素
3. Partition(分区)亦是并行度,所有work执行的一次执行task的数量

如果spark-default.conf或SparkConf中设置了spark.default.parallelism参数值,
那么spark.default.parallelism=设置值。

如果未设置,在yarn与standalone模式中:spark.default.parallelism =  max(所有executor使用的core总数, 2)。

即可以RDD的分区数:sc.defaultParallelism = spark.default.parallelism

Spark.default.parallelism 属性值设置为: 单个work节点计算线程 * work节点个数 * 3

Spark 分区的选择

分区太少:  1. 减少并发性; 
           2. 数据倾斜和不恰当的资源利用

分区太多:  1. 任务调度可能比实际执行时间花费更多的时间


RDD 分区数的选择: 可用core数量(单个work节点core线程个数 * work节点个数)的2-3倍。
                                   单个分区的数据量大小最终取决于执行程序的可用内存。
Tips:WebUI上查看任务执行,至少需要100+ ms时间。如果所用时间少于100ms,那么应用程序可能会花更多的时间来调度任务。此时就要减少partition的数量。
 

Spark 应用程序的调度

Driver会向master申请资源,master收到请求之后,会向worker进行资源调度,启动Executor,然后,Executor向Driver进行注册。此时Spark 应用程序就会知道哪些worker上面的executor已经就绪。

接着开始执行spark任务:遇到action操作创建一个job—提交给DAGScheduler, DAGScheduler会把job分为多个stages(shuffle:最后一个stage里面的task叫ResultTask,前面stage里面的task叫shuffleMapTask。),为每个stage创建一个taskset集合,集合中的task计算逻辑完全相同,只是处理的数据不同。然后DAGScheduler会把taskset交给TaskScheduler,TaskScheduler会把taskset里面的task发送给Executor。Executor接收到task,会启动一个线程池TaskRunner,在里面运行task。

实例化SparkContext是在Driver端完成的,后续的代码操作都是在work端进行完成的。

文件收集框架Flume

实时收集数据,经常与storm/spark集成进行使用

Flume只有一个角色的节点Agent,其三大组件为:

收集collecting                  source

聚合aggregating              channel

移动moving                      sink

Event是Flume数据传输的基本单元,Flume以event 的形式将数据从源头传送到最终的目的

Flume提供了三种方式处理此种错误

End-to-end:收到数据agent首先会把数据写到磁盘,等待传输成功后再删除,如果传输失败,再次发送

Store on failure:若接收方crash,再把数据写到本地,等待对方恢复之后继续发送

Besteffort:等待数据发送到接收方之后,不会进行确认

HDFS分布式文件系统对数据 写入过程

1. DFSClient发消息给NameNode,表示将数据文件(需要计算的文件)写入

2. NameNode发消息给DFSClient,让DFSClient写到DataNodeA、B和D,并直接联系DataNodeB

3. DFSClient发消息给DataNodeB,让它保存一份数据文件. (同机架或不同机架)

4. DataNodeB在保存数据文件时,并将数据文件发送个DataNodeA和DataNodeD,进行备份

6. DataNodeB发确认消息给DFSClient与NameNode,表示写入完成

HDFS分布式文件系统对数据 读取过程

1. DFSClient询问NameNode应该从哪里读取文件.

2. NameNode发送 “数据块”的信息给DFSClient。

3. DFSClient检查数据块信息,联系相关的DataNode,请求数据块

4. DataNode返回文件内容给DFSClient,然后关闭连接,完成读操作

yarn 主要组件

ResourceManager: 主节点,处理客户端的请求、调度应用管理者、集群整体资源分配

NodeManager:从节点,单节点的资源管理、处理主节点/应用管理者的命令

ApplicationMaster: 应用管理者,数据切分、应用程序资源的申请,分配资源给内部任务任务监控与容错

Container: 容器,任务运行环境的抽象, 封装了任务所需的所有资源、资源隔离的效果

yarn 的业务流程

1.客户端向ResourceManager提交一个作业,ResourceManager则会为这个作业分配一个Container.

2.所以ResourceManager会与NodeManager进行通信,要求这个NodeManager启动一个Container.

3.而这个Container是用来启动ApplicationMaster的,ApplicationMaster启动完之后会与ResourceManager进行一个注册.

4.这时候客户端就可以通过ResourceManager查询作业的运行情况了.

5.然后ApplicationMaster还会到ResourceManager上申请作业所需要的资源,申请到以后就会到对应的

NodeManager之上运行客户端所提交的作业.

6.最后NodeManager就会把task运行在启动的Container里

Hive 表分类

内部表:删除内部表会直接删除元数据 (metadata) 及存储文件数据

外部表:被 external 修饰的表,删除外部表仅仅删除元数据, 文件不会被删除

分区表:把数据分类放在不同的目录下面, 加快查询速度

SQL 的执行顺序

第一步:执行FROM

第二步:WHERE条件过滤

第三步:GROUP BY分组

第四步:执行SELECT投影列

第五步:HAVING条件过滤

第六步:执行ORDER BY 排序

Hive中出现数据倾斜如何处理

1. 调节参数(在map中会做部分聚集操作 hive.map.aggr=true)

2. SQL 语句调节

3. 表的设计

Hive 调优

表拆分、MR优化配置、并行计算、JVM重用、本地计算、推测执行

HBase,Redis, MongDB 的应用场景

MongoDB是高性能、无模式的文档型数据库,支持二级索引,非常适合文档化格式的存储及查询。MongoDB的官方定位是通用数据库,确实和MySQL有些像,现在也很流行,但它还是有事务、join等短板,在事务、复杂查询应用下无法取代关系型数据库。

Redis是内存型Key/Value系统,读写性能非常好,支持操作原子性,很适合用来做高速缓存。

HBase存储容量大,一个表可以容纳上亿行、上百万列,可应对超大数据量要求扩展简单的需求。Hadoop的无缝集成,让HBase的数据可靠性和海量数据分析性能(MapReduce)值得期待。

Redis 主从同步步骤

1. slave 服务器连接 master 服务器, 并发送 psync 同步码.

2. master 服务器收到 psync 同步码, 执行 bgsave 生成snapshot(内存中,rdb), 并在缓存区记录从当前开始执行的所有写命令.

3. master 服务器在 bgsave 命令执行完成后, 将 snapshot 发送到 slave 服务器, slave 载入快照.

4. slave 服务器收到快照, 载入到内存中. 将自己的数据库状态更新至主服务器执行 BGSAVE 命令时的数据库状态. (rdb属于内存性的文件, 所以每次都会丢弃旧 rdb)

5. master 服务器发送完成 snapshot 后, 向 slave 服务器发送缓存区的写命令.(注意时间点)

6. salve 服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

Redis 单线程模型每秒万级别处理能力的原因

1. 纯内存访问。数据存放在内存中,内存的响应时间大约是100纳秒,这是 Redis 每秒万亿级别访问的重要基础。

2. 非阻塞 I/O,Redis 采用 epoll 做为 I/O 多路复用技术的实现,再加上 Redis 自身的事件处理模型将 epoll 中的连接,读写,关闭都转换为了时间,不在 I/O 上浪费过多的时间。

3. 单线程避免了线程切换和竞态产生的消耗。

4. Redis 采用单线程模型,每条命令执行如果占用大量时间,会造成其他线程阻塞,对于 Redis 这种高性能服务是致命的,所以 Redis 是面向高速执行的数据库。

分布式锁机制: 悲观锁, 乐观锁

悲观锁

乐观锁

悲观锁采用相对保守的策略,在资源争用比较严重的时候比较合适。悲观锁在事务开始之前就去尝试获得写权限,事务结束后释放锁;也就是说对于同一行记录,只有一个写事务可以并行(加锁,只有我能操作).

乐观锁是在提交事务之前,大家可以各自修改数据,但是在提交事务的时候,如果发现在这个过程中,数据发生了改变,那么直接拒绝此次事务提交。(允许大家都操作,只是在提交事务中检测)乐观锁适合在资源争用不激烈的时候使用。

当前只能有写权限的用户可以操作, 而其他用户此时被拒绝. 如 synchronized (不允许写, 更不会执行)

当前所有用户都可以操作, 但是在提交时会被拒绝. 如watch - multi - exec (允许写, 但不一定可以执行.)

MongoDB的分片

  分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。 通过一个名为mongos的路由进程进行操作,mongos知道数据和片的对应关系(通过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差(+++里面的说明+++),查询则尽量避免跨分片查询。使用分片的时机:

1. 机器的磁盘不够用了。使用分片解决磁盘空间的问题。

2. 单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。

3. 想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。

你可能感兴趣的:(Bigdata)