Hadoop HA 基本认知

Hadoop HA(High Available)经过同时配置两个处于Active/Passive模式的Namenode,分别叫Active Namenode和Standby Namenode。 Standby Namenode做为热备份,从而容许在机器发生故障时可以快速进行故障转移,同时在平常维护的时候使用优雅的方式进行Namenode切换。Namenode只能配置一主一备,不能多于两个Namenode。

Hadoop HA基本流程

集群总体上可以分为三部分:NameNode集群、JournalNode集群和Zookeeper集群。NameNode在某一时刻只有一个处于活跃状态,其他的都处于standby状态;JournalNode负责把edits文件传到standby的NameNode上;Zookeeper负责监控NameNode宕机情况,ZKFC(ZookeeperFailoverController)是专门监控NameNode健康的。

为了同步NameNode的元数据一致,有专门的JournalNode来同步元数据文件,活跃的NameNode的edits文件会写入journalnode集群,其他standby的结点会去读取journalnode上的edits文件,以此来同步自身的元数据。

  1. ZKFC的HealthyMonitor是监控NameNode的进程,是专门监控NameNode将康情况的进程。
  2. HealthyMonitor会定时想ZKFC进程报告NameNode情况。
  3. 当HealthyMonitor出现汇报了NameNode,ZKFC就会向AcitveStandbyEloctor报告。
  4. AcitveStandbyEloctor接到NameNode宕机报告就会通知zk集群选举出新的NameNode。
  5. zk集群经过内部选举,返回一个standby的NameNode给AcitveStandbyEloctor。
  6. AcitveStandbyEloctor想ZKFC报告选举结果。
  7. ZKFC为了防止是网络原因导致NameNode假死,就会结束NameNode进程。
  8. zk集群就会通知另一个ZKFC要求它修改它监控的NameNode的进程为活跃节点。

HA技术关键点

HA问题中需要解决的两个问题:

  • 元数据一致性:Standby节点和Active节点的元数据一致性。
  • 主备自动切换:Active节点服务中断时,Standby节点可以立即启动对外提供服务。

为了确保故障转移可以快速完成,Standby Namenode须要维护最新的Block位置信息,即每一个Block副本存放在集群中的哪些节点上。为了达到这一点,Datanode同时配置主备两个Namenode,并同时发送Block报告和心跳到两台Namenode。

确保任什么时候刻只有一个Namenode处于Active状态很是重要,不然可能出现数据丢失或者数据损坏。当两台Namenode都认为本身的Active Namenode时,会同时尝试写入数据(不会再去检测和同步数据)。为了防止这种脑裂现象,Journal Nodes只容许一个Namenode写入数据,内部经过维护epoch数来控制,从而安全地进行故障转移。

HA其本质上就是要保证主备NN元数据是保持一致的,即保证fsimage和editlog在备NN上也是完整的。元数据的同步很大程度取决于EditLog的同步,而这步骤的关键就是共享文件系统

有两种方式能够进行edit log共享:

  1. 使用QJM(Quorum Journal Manager)共享edit log
  2. 使用NFS(Network File System)共享edit log(存储在NAS/SAN)

NFS的方式

all name space edits logged to shared storage;Block reports are sent to both name nodes

显然NFS做为主备Namenode的共享存储。这种方案可能会出现脑裂(split-brain),即两个节点都认为本身是主Namenode并尝试向edit log写入数据,这可能会致使数据损坏。经过配置fencin脚原本解决这个问题,fencing脚本用于:

  • 将以前的Namenode关机
  • 禁止以前的Namenode继续访问共享的edit log文件

使用这种方案,管理员就能够手工触发Namenode切换,而后进行升级维护。但这种方式存在如下问题:

  • 只能手动进行故障转移,每次故障都要求管理员采起措施切换。
  • NAS/SAN设置部署复杂,容易出错,且NAS自己是单点故障。
  • Fencing 很复杂,常常会配置错误。
  • 没法解决意外(unplanned)事故,如硬件或者软件故障。oop
    所以须要另外一种方式来处理这些问题:
  • 自动故障转移(引入ZooKeeper达到自动化)
  • 移除对外界软件硬件的依赖(NAS/SAN)
  • 同时解决意外事故及平常维护致使的不可用

Quorum Journal Manager

QJM(Quorum Journal Manager)是Hadoop专门为Namenode共享存储开发的组件,一般是奇数点结点组成。其集群运行一组Journal Node,每一个Journal 节点暴露一个简单的RPC接口,容许Namenode读取和写入数据,数据存放在Journal节点的本地磁盘。当Namenode写入edit log时,NameNode会同时向所有JournalNode并行写文件,当超过半数节点回复确认成功写入以后,edit log就认为是成功写入。

1、 QJM写过程

NameNode 会把 EditLog 同时写到本地和 JournalNode 中。写本地由配置中的参数dfs.namenode.name.dir来控制,写JN由参数dfs.namenode.shared.edits.dir控制,在写EditLog时会由两个不同的输出流来控制日志的写过程,分别是:

  • EditLogFileOutputStream(本地输出流)
  • QuorumOutputStream(JN输出流)

NameNode在写EditLog时,并不是直接写到磁盘中,为保证高吞吐,NameNode会分别为EditLogFileOutputStream和QuorumOutputStream定义两个同等大小的Buffer,大小大概是512KB,一个写Buffer(buffCurrent),一个同步Buffer(buffReady),这样可以一边写一边同步,所以EditLog是一个异步写过程,同时也是一个批量同步的过程,避免每写一笔就同步一次日志。

这个是怎么实现边写边同步的呢,这中间其实是有一个缓冲区交换的过程,即bufferCurrent和buffReady在达到条件时会触发交换,如bufferCurrent在达到阈值同时bufferReady的数据又同步完时,bufferReady数据会清空,同时会将bufferCurrent指针指向bufferReady以满足继续写,另外会将bufferReady指针指向bufferCurrent以提供继续同步EditLog。

flowchart TD
    A((Client)) --修改--> B(NameNode)
    B-->C(本地 \n EditLogFileOutputStream)
    B-->D(JournalNode \n QuorumOutputStream)
    C-->E(bufferCurrent)
    C-->F(bufferReady)
    D-->H(bufferCurrent)
    D-->I(bufferReady)
    E-->M(本地目录)
    F-->M
    H-->N(JournalNode)
    I-->N

这里有一个问题,既然EditLog是异步写的,怎么保证缓存中的数据不丢呢,其实这里虽然是异步,但实际所有日志都需要通过logSync同步成功后才会给client返回成功码,假设某一时刻NameNode不可用了,其内存中的数据其实是未同步成功的,所以client会认为这部分数据未写成功。

(1)隔离双写

在Active NN每次同步EditLog到JN时,先要保证不会有两个NN同时向JN同步日志。这涉及一个很重要的概念Epoch Numbers,很多分布式系统都会用到。

成为Active结点时,其会被赋予一个EpochNumber,每个EpochNumber是惟一的,不会有相同的EpochNumber出现。EpochNumber有严格顺序保证,每次NN切换后其EpochNumber都会自增1,后面生成的EpochNumber都会大于前面的EpochNumber。QJM是怎么保证上面特性的呢,主要有以下几点:

  1. 在对EditLog作任何修改前,QJM(NameNode上)必须被赋予一个EpochNumber;
  2. QJM把自己的EpochNumber通过newEpoch(N)的方式发送给所有JN结点;
  3. 当JN收到newEpoch请求后,会把QJM的EpochNumber保存到一个lastPromisedEpoch变量中并持久化到本地磁盘;
  4. ANN同步日志到JN的任何RPC请求(如logEdits(),startLogSegment()等),都必须包含ANN的EpochNumber;
  5. JN在收到RPC请求后,会将之与lastPromisedEpoch对比,如果请求的EpochNumber小于lastPromisedEpoch,将会拒绝同步请求,反之,会接受同步请求并将请求的EpochNumber保存在lastPromisedEpoch;

这样就能保证主备NN发生切换时,就算同时向JN同步日志,也能保证日志不会写乱,因为发生切换后,原ANN的EpochNumber肯定是小于新ANN的EpochNumber,所以原ANN向JN的发起的所有同步请求都会拒绝,实现隔离功能,防止了脑裂。

(2)恢复in-process日志

如果在写过程中写失败了,可能各个JN上的EditLog的长度都不一样,需要在开始写之前将不一致的部分恢复。恢复机制如下:

  1. Active NN先向所有JN发送getJournalState请求;
  2. JN会向ANN返回一个Epoch(lastPromisedEpoch);
  3. Active NN收到大多数JN的Epoch后,选择最大的一个并加1作为当前新的Epoch,然后向JN发送新的newEpoch请求,把新的Epoch下发给JN;
  4. JN收到新的Epoch后,和lastPromisedEpoch对比,若更大则更新到本地并返回给Active NN自己本地一个最新EditLogSegment起始事务Id,若小则返回NN错误;
  5. Active NN收到多数JN成功响应后认为Epoch生成成功,开始准备日志恢复;
  6. Active NN会选择一个最大的EditLogSegment事务ID作为恢复依据,然后向JN发送prepareRecovery; RPC请求,对应Paxos协议2p阶段的Phase1a,若多数JN响应prepareRecovery成功,则可认为Phase1a阶段成功;
  7. Active NN选择进行同步的数据源,向JN发送acceptRecovery RPC请求,并将数据源作为参数传给JN。
  8. JN收到acceptRecovery请求后,会从JournalNodeHttpServer下载EditLogSegment并替换到本地保存的EditLogSegment,对应Paxos协议2p阶段的Phase1b,完成后返回Active NN请求成功状态。
  9. Active NN收到多数JN的响应成功请求后,向JN发送finalizeLogSegment请求,表示数据恢复完成,这样之后所有JN上的日志就能保持一致。 数据恢复后,Active NN上会将本地处于in-process状态的日志更名为finalized状态的日志,形式如editsstart-txidstop-txid。

(3)日志同步

  1. 执行logSync过程,将ANN上的日志数据放到缓存队列中
  2. 将缓存中数据同步到JN,JN有相应线程来处理logEdits请求
  3. JN收到数据后,先确认EpochNumber是否合法,再验证日志事务ID是否正常,将日志刷到磁盘,返回ANN成功码
  4. ANN收到JN成功请求后返回client写成功标识,若失败则抛出异常

通过上面一些步骤,日志能保证成功同步到JN,同时保证JN日志的一致性,进而备NN上同步日志时也能保证数据是完整和一致的。

2、QJM读过程

读过程是面向备NN(Standby NN)的,Standby NN定期检查JournalNode上EditLog的变化,然后将EditLog拉回本地。Standby NN上有一个线程StandbyCheckpointer,会定期将Standby NN上FSImage和EditLog合并,并将合并完的FSImage文件传回主NN(Active NN)上,就是所说的Checkpointing过程。下面我们来看下Checkpointing是怎么进行的。

在2.x版本中,已经将原来的由SecondaryNameNode主导的Checkpointing替换成由Standby NN主导的Checkpointing。

  1. 在Standby NN上先检查前置条件,前置条件包括两个方面:距离上次Checkpointing的时间间隔和EditLog中事务条数限制。
  2. 前置条件任何一个满足都会触发Checkpointing,然后SNN会将最新的NameSpace数据即SNN内存中当前状态的元数据保存到一个临时的fsimage文件( fsimage.ckpt)
  3. 然后比对从JN上拉到的最新EditLog的事务ID,将fsimage.ckpt_中没有,EditLog中有的所有元数据修改记录合并一起并重命名成新的fsimage文件,同时生成一个md5文件。
  4. 将最新的fsimage再通过HTTP请求传回ANN。

通过定期合并fsimage有什么好处?

  1. 可以避免EditLog越来越大,合并成新fsimage后可以将老的EditLog删除
  2. 可以避免主NN(ANN)压力过大,合并是在SNN上进行的
  3. 可以保证fsimage保存的是一份最新的元数据,故障恢复时避免数据丢失

三、主备自动切换
Hadoop的主备选举依赖于ZooKeeper。
整个切换过程是由ZKFC来控制的,ZKFC是实现主备切换的组件。每个运行的NameNode上都会有一个ZKFC进程(实际是一个Hadoop进程)。主要的功能如下:

  1. 健康检测:ZKFC会使用健康检测命令定期的ping同节点中的NameNode,只要该NameNode及时的回复健康,则任务当前NameNode是健康的;
  2. Zookeeper会话管理: 当本地NameNode是健康的,ZKFC会保持一个在Zookeeper中打开的会话。如果本地NameNode处于Active状态,ZKFC会保持一个特殊的znode锁,如果回话中断,锁节点讲自动删除;
  3. 基于Zookeeper的选举: 如果本地的NameNode是健康的,且ZKFC发现没有其他的节点持有当前的znode锁,它会为自己获取该锁。如果成功则进行故障切换,并且确保之前的NameNode的进程中断,将本地NameNode切换为Active;

在故障切换期间,ZooKeeper主要是发挥什么作用有以下几点:

  1. 失败保护:集群中每一个NameNode都会在ZooKeeper维护一个持久的session,机器一旦挂掉,session就会过期,故障迁移就会触发;
  2. Active NameNode选择:ZooKeeper有一个选择ActiveNN的机制,一旦现有的ANN宕机,其他NameNode可以向ZooKeeper申请排他成为下一个Active节点;
  3. 防脑裂: ZK本身是强一致和高可用的,可以用它来保证同一时刻只有一个活动节点;

参考链接:
https://blog.csdn.net/weixin_43854618/article/details/108808274

https://blog.csdn.net/shan19920501/article/details/124911283

spark serialization Kryo序列化

Spark默认使用的是Java的序列化机制,也就是ObjectOutputStream/ObjectInputStream API来进行序列化和反序列化。但是Spark同时支持使用Kryo序列化库,Kryo序列化类库的性能比Java序列化类库的性能要高很多

spark 序列化

Spark中,主要有三个涉及到序列化的情况:

  1. 在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输 — 也就是初始化工作是在Driver端进行的,而程序实际运行是在Executor端进行的; 涉及跨进程通信了,所以要进行序列化
  2. 将自定义的类型作为RDD的泛型类型时(比如JavaRDD,Student是自定义类型),所有自定义类型对象,都会进行序列化。因此这种情况下,也要求自定义的类必须实现Serializable接口。
  3. 使用可序列化的持久化策略时(比如MEMORY_ONLY_SER),Spark会将RDD中的每个partition都序列化成一个大的字节数组。

Spark默认使用的是Java的序列化机制,也就是ObjectOutputStream/ObjectInputStream API来进行序列化和反序列化。但是Spark同时支持使用Kryo序列化库,Kryo序列化类库的性能比Java序列化类库的性能要高很多。官方介绍,Kryo序列化机制比Java序列化机制,性能高10倍左右。Spark之所以默认没有使用Kryo作为序列化类库,是因为Kryo要求最好要注册所有需要进行序列化的自定义类型,因此对于开发者来说,这种方式比较麻烦。

Kryo序列化框架

Kryo 是一个快速高效的Java对象图形序列化框架,主要特点是性能、高效和易用。该项目用来序列化对象到文件、数据库或者网 络。
但是,它也有一个致命的弱点:生成的byte数据中部包含field数据,对类升级的兼容性很差!所以,若用kryo序列化对象用于C/S架构的话,两边的Class结构要保持一致。

Spark出于性能的考虑,Spark2.0开始支持另外一种Kryo序列化机制。

  • Kryo速度是Serializable的10倍。
  • 当RDD在Shuffle数据的时候,简单数据类型、数组和字符串类型已经在Spark内部使用kryo来序列化
  • 即使使用kryo序列化,也要继承Serializable接口
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession

/*
* Kryo 序列化 效率是Java序列化的10倍,但不支持全部类型
* */
case class Dog(name:String)
case class Cat(age:Int)
case class Animal(dog: Dog,cat: Cat)

object TestKyroDemo {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[*]").setAppName("TestKryo")
      .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
      .registerKryoClasses(Array(classOf[Animal], classOf[Cat], classOf[Dog])) 
      //当序列化的类中包含其他引用类型,最好把其他类型也加入进来,没加入进来的类会以全类名方式进行存储
      val spark = SparkSession.builder().config(conf).getOrCreate()
    val fr = spark.createDataFrame(Seq(new Animal(new Dog("he"),new Cat(22))))
    fr.cache().collect()
  }
}

参考链接:
https://blog.csdn.net/qq_43288259/article/details/116749301
https://blog.csdn.net/qq_43192537/article/details/110389236

数据治理 Data Governance 基础概念

数据架构、数据标准、数据质量、主数据管理、元数据管理、数据安全、数据生命周期、数据基础平台、数据应用、数据需求与规划 、外部数据采购、数据运维等;数据治理的6个基本原则:职责、策略、采购、绩效、符合和人员行为;数据管理组织的构成分为三个层次,自上而下划分为决策层、管理协调层以及执行层。

数据治理涉及到哪些方面?

数据架构、数据标准、数据质量、主数据管理、元数据管理、数据安全、数据生命周期、数据基础平台、数据应用、数据需求与规划 、外部数据采购、数据运维等

数据治理的6个基本原则:职责、策略、采购、绩效、符合和人员行为

数据管理组织的构成分为三个层次,自上而下划分为决策层、管理协调层以及执行层。

企业数据架构管理应该遵循 可信数据源原则;数据分布减法原则;数据完整性原则

数据治理过程中用到的工具

  1. 数据生命周期管理相关工具
  2. 数据安全相关工具
  3. 主数据管理工具
  4. 数据清洗工具
  5. 数据资产管理工具
  6. 数据共享交换平台或工具
  7. 数据质量管理工具
  8. 元数据管理工具
  9. 数据标准化工具

数据治理参考标注或方法论

SMART的:Specific(具体的)、Measurable(可衡量的)、Actionable(可操作的)、Relevant(相关的)、Timely(及时的)。

  1. GB/T36073-2018《数据管理能力成熟度评估模型》 —- 《数据管理能力成熟度评估模型》DCMM
    • DCMM按照组织、制度、流程、技术对数据管理能力进行了分析和总结, 提炼出组织数据管理的8个过程域,即数据战略、数据治理、数据架构、数据应 用、数据安全、数据质量、数据标准、数据生存周期
  2. GB/T 34960《信息技术服务治理 数据治理规范》
  3. DAMA DMBOK — DAMA数据管理知识体系指南(原书第2版)
  4. DGI
  5. COBIT 5
  6. TOGAF 9

DAMA数据管理知识体系、DCMM数据管理能力成熟度评估、DGI数据治理框架

DMBOK 简述

  • 数据治理(Data Governance):通过建立一个能够满足企业需求的数据决策体系,为数据管理提供指导和监督。这些权限和责任的建立应该考虑到组织的整体需求。(参见第3章)
  • 数据架构(Data Architecture):定义了与组织战略协调的管理数据资产的“蓝图”,指导基于组织的战略目标,指定符合战略需求的数据架构。(参见第4章)
  • 数据建模和设计(Data Modeling and Design):以数据模型(data model.)的精确形式,进行发现、分析、展示和沟通数据需求的过程。(参见第5章)
  • 数据存储和操作(Data Storage and Operations):以数据价值最大化为目标,包括存储数据的设计、实现和支持活动,以及在整个数据生命周期中,从计划到销毁的各种操作活动。(参见第6章)
  • 数据安全(Data Security):这一活动确保数据隐私和安全,数据的获得和使用必须要有安全的保障。(参见第7章)
  • 数据集成和互操作(Data Integration and Interoperability):包括与数据存储、应用程序和组织之间的数据移动和整合相关的过程。(参见第8章)
  • 文档和内容管理(Document and Content Management):用于管理非结构化媒体的数据和信息的生命周期过程,包括计划、实施和控制活动,尤其是指支持法律法规遵从性要求所需的文档。(参见第9章)
  • 参考数据和主数据管理(Reference and Master Data Management):包括核心共享数据的持续协调和维护,使关键业务实体的真实信息,以准确、及时和相关联的方式在各系统间得到一致使用。(参见第10章)
  • 数据仓库和商务智能(Data Warehousing and Business Intelligence):包括计划、实施和控制流程,来管理决策支持数据,并使知识工作者通过分析报告从数据中获得价值。(参见第11章)
  • 元数据管理(Metadata Management):包括规划、实施和控制活动,以便能够访问高质量的集成元数据,包括定义、模型、数据流和其他至关重要的信息(对理解数据及其创建、维护和访问系统有帮助)。(参见第12章)
  • 数据质量管理(Data Quality Management):包括规划和实施质量管理技术,以测量、评估和提高数据在组织内的适用性。(参见第13章)

除了有关知识领域的章节外DAMA-DMBOK,车轮图以外的内容,包含以下主题章节:

  • 数据处理伦理(Data Handling Ethics):描述了关于数据及其应用过程中,数据伦理规范在促进信息透明、社会责任决策中的核心作用。数据采集、分析和使用过程中的伦理意识对所有数据管理专业人士有指导作用。(参见第2章)
  • 大数据和数据科学(Big Data and Data Science):描述了针对大型的、多样化数据集收集和分析能力的提高而出现的技术和业务流程。(参见第14章)
  • 数据管理成熟度评估(Data Management Maturity Assessment):概述了评估和改进组织数据管理能力的方法。(参见第15章)
  • 数据管理组织和角色期望(Data Management Organization and Role Expectations):为组建数据管理团队、实现成功的数据管理活动提供了实践提供和参考因素。(第16章)
  • 数据管理和组织变革管理(Data Management and Organizational Change Management ):描述了如何计划和成功地推动企业文化变革,文化的变革是将数据管理实践有效地嵌入组织中必然结果。(第17章)

DGI数据治理项目通用10个组成部分

分类 具体内容
与过程相关 ① 最终目标与愿景
② 短期目标、治理标准、评估标准、资金筹集策略
③ 数据规则与定义
④ 决策权
⑤ 问责制度
⑥ 控制措施
与员工与企业部门相关 ⑦ 数据利益相关方
⑧ 数据治理办公室
⑨ 数据管理小组
与过程相关 ⑩ 主动型、应对型与持续性的数据治理过程(项目)

DGI框架的5W1H法则

WHY,为什么需要数据治理?

DGI框架中的第1-2组件,数据治理愿景使命、数据治理目标。用这两个组件来定义企业为什么需要数据治理。它为企业数据治理指明了方向,是其他数据治理活动的总体策略。

WHAT,数据治理治什么?

DGI框架中的3-6个组件,数据规则与定义、数据的决策权、数据问责制、数据管控,DGI框架这4个组件定义出了数据治理到底治什么。

  • 数据规则与定义,侧重业务规则的定义,例如:相关的策略、数据标准、合规性要求等;
  • 数据的决策权,侧重数据的确权,明确数据归口和产权为数据标准的定义、数据管理制度、数据管理流程的制度奠定基础。
  • 数据问责制,侧重数据治理职责和分工的定义,明确谁应该在什么时候做什么。
  • 数据管控,侧重采用什么样的措施来保障数据的质量和安全,以及数据的合规使用。

WHO,谁参与数据治理?

DGI框架中的7-9组件,定义数据治理的利益干系人,主要包括:数据利益相关者、数据治理办公室和数据专员。DGI框架对数据治理的主导、参与的职责分工定义给出了相关参考。

WHEN,什么时候开展数据治理?

DGI框架中的第10个组件,用来定义数据治理的实施路径、行动计划。

HOW,如何开展数据治理?

DGI框架中的第10组件,数据治理流程,描述了数据管理的重要活动和方法。

WHERE,数据治理位于何处?

DGI框架外的组件,虽然没有含在10大组件之列但却十分重要,强调明确当前企业数据治理的成熟度级别,找到企业与先进标杆的差距,是定义数据治理内容和策略的基础。

参考链接:https://blog.csdn.net/m0_56143415/article/details/122706095