大数据之重点概念及原理

一、大数据

(一)概念:

指的是传统数据处理应用软件不足以处理(存储和计算)它们大而复杂的数据集。

(二)数据级别:

MB:普通用户数据级别
PB:企业级数据级别
ZB:全球数据总量级别

(三)特点:

容量大,种类多,速度快,价值高

(四)Hadoop

1.概念:Apache旗下的一套开源软件平台
	
2.功能:利用服务式集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理
	
3.核心组件:
	
	Common(基础功能组件)(工具包,RPC框架)JNDI 和 RPC
	HDFS(Hadoop Distribute File System分布式文件系统)
	YARN(Yet another Resouces Negotiator运算资源调度系统)
	MapReduce(Map 和 Reduce 分布式运算编程框架)
		
4.重点组件:
	
	HDFS:Hadoop 的分布式文件存储系统
	MapReduce:Hadoop 的分布式程序运算框架,也可以叫做一种编程模型
	Hive:基于 Hadoop 的类 SQL 数据仓库工具
	HBase:基于 Hadoop 的列式分布式 NoSQL 数据库
	ZooKeeper:分布式协调服务组件
	Mahout:基于 MapReduce/Flink/Spark 等分布式运算框架的机器学习算法库
	Oozie/Azkaban:工作流调度引擎
	Sqoop:数据迁入迁出工具
	Flume:日志采集工具
	
5.分布式系统:
	
	利用多个节点共同协作完成一项或多项具体业务功能的系统

(五)HDFS原理剖析

1.HDFS工作机制:
	
	(1)概述:
		
		1)HDFS 集群分为两大主要角色:namenode、datanode (secondarynamenode 和 client)
		2)namenode 负责管理整个文件系统的元数据,并且负责响应客户端的请求
		3)datanode 负责管理用户的文件数据块,并且通过心跳机制汇报给 namenode
		4)文件会按照固定的大小(dfs.blocksize)切成若干块后分布式存储在若干台 datanode 上
		5)每一个文件块可以有多个副本,并存放在不同的 datanode 上
		6)datanode 会定期向 namenode 汇报自身所保存的文件 block 信息,而
	namenode 则会负责保持文件的副本数量
		7)HDFS 的内部工作机制对客户端保持透明,客户端请求访问 HDFS 都是通过向
	namenode 申请来进行
				
	(2)写流程:
		
		1)客户端向namenode发送上传请求
		2)namenode会进行一系列的检查,包括:文件是否已经上传,父目录是否已经存在,权限等等。
		3)客户端上传真正的文件请求,包含文件大小或长度信息
		4)namenode向客户端返回文件上传的节点,节点数根据文件大小来计算
		5)客户端开始准备上传文件
		6)客户端对数据开始进行逻辑切块
		7)开始上传第一个切块
		8)构建第一个块的pipline
		9)客户端开始进行真正的数据上传,上传成功后,向客户端响应
		10)关闭pipline
		11)上传第二个块,重复(8)(9)(10)
		12)所有的块都上传成功后,向namenode响应
			
	(3)读流程:
		
		1)客户端向namenode发送下载请求
		2)namenode会进行一系列的检查,包括:文件是否已经存在,权限等等。
	如果检查没有问题,查询元数据库,返回数据对应的块和存储位置给客户端
		3)客户端拿到第一个块的数据,开始第一个块的下载
		4)第一个块下载完成之后,会进行crc检验,检验通过,则认为下载成功
		5)第二个块的下载,重复(4),追加到文件
		6)全部块下载完成之后,客户端向namenode响应
			
2.NameNode工作机制:
	
	(1)NameNode职责:
		
		1)负责客户端请求(读写数据请求)的响应
		2)维护目录树结构(元数据的管理:查询,修改)
		3)配置和应用副本存放策略
		4)管理集群数据块负载均衡问题
			
	(2)NameNode元数据管理:
		
		元数据:抽象目录树,数据与块的映射,块的存储位置
		两种存储方式:
		1)内存:内存元数据 metadata	
			时刻保存着最新的元数据
			比磁盘中元数据多了块的存储位置
		2)磁盘:磁盘元数据镜像文件 fsimage_0000000000000000555
			fsimage_0000000000000000555.md5   加密文件
			等价于	edits_0000000000000000001-0000000000000000018
			……
			edits_0000000000000000444-0000000000000000555
			合并之和
			数据历史操作日志文件 edits_0000000000000000001-0000000000000000018
			数据预写操作日志文件 edits_inprogress_0000000000000000556
			seen_txid:合并点  记录的下次需要合并的edits文件的编号
			metadata = 最新 fsimage_0000000000000000555 + edits_inprogress_0000000000000000556
			metadata = 所有的 edits 之和(edits_001_002 + …… + edits_444_555 + edits_inprogress_556)
			
	(3)VERSION(存放 hdfs 集群的版本信息)文件解析:
		
			#Sun Jan 06 20:12:30 CST 2017 ## 集群启动时间
			namespaceID=844434736 ## 文件系统唯一标识符
			clusterID=CID-5b7b7321-e43f-456e-bf41-18e77c5e5a40 ## 集群唯一标识符
			cTime=0 ## fsimage 创建的时间,初始为 0,随 layoutVersion 更新
			storageType=NAME_NODE ##节点类型
			blockpoolID=BP-265332847-192.168.123.202-1483581570658 ## 数据块池 ID,可以有多个
			layoutVersion=-60 ## hdfs 持久化数据结构的版本号
		
	(4)查看文件:
		
			查看 edits 文件信息:
			hdfs oev -i edits_0000000000000000482-0000000000000000483 -o edits.xml
			cat edits.xml
			查看 fsimage 镜像文件信息:
			hdfs oiv -i fsimage_0000000000000000348 -p XML -o fsimage.xml
			cat fsimage.xml
	
3.DataNode工作机制:
		
	(1)DataNode 作用:
		1)真正的存储数据
		2)处理客户端的读、写的请求
		3)向namenode发送心跳报告
	(2)Datanode 掉线判断时限参数
		datanode 进程死亡或者网络故障造成 datanode 无法与 namenode 通信,
	namenode 不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。		
	HDFS 默认的超时时长为 2*5 分钟 + 10*3 秒。
	
4.SecondaryNameNode工作机制:
		
	(1)secondarynamenode作用:
		1)备份元数据
		2)帮助namenode进行checkpoint,分担namenode的压力
	(2)checkpoint---元数据的合并流程
		checkpoint:每隔一段时间,会由 secondary namenode 将 namenode 上
	积累的所有 edits 和一个最新的fsimage 下载到本地,并加载到内存进行 merge 的过程。
		1)secondarynamenode 向 namenode 发送请求,询问有没有需要合并的文件
		2)namenode 对 secondarynamenode 响应,需要进行合并
		3)secondarynamenode 开启 checkpoint
		4)namenode 将正在编辑的文件进行回滚,提交,将编辑状态变为历史状态,同时
	会生成一个新的编辑日志文件来接收当前的请求日志
		5)secondarynamenode 会将历史日志文件和 fsimage 文件拉取过来
		6)secondarynamenode 会把edits文件和fsimage文件合并
		7)形成新的fsimage文件
		8)secondarynamenode将合并完成的fsimage文件发送给namenode
	(3)合并点:触发合并的条件
		1)时间节点  3600s=1h
		2)元数据条数节点    1000000万条数据
		两个条件只要满足一个就会触发checkpoint过程
	
5.心跳机制:
		
	(1)Hadoop是Master/Slave结构,Master中有NameNode和ResourceManager,
Slave中有Datanode和NodeManager
	(2)Master启动的时候会启动一个IPC(inter-Process Comunication,进程间
通信)server服务,等待slave的链接
	(3)Slave启动时,会主动连接master的ipc server服务,并且每隔3秒链接一次
master,这个时间间隔时间是可以调整的,参数为dfs.heartbeat.interval,这个每隔
一段时间去连接一次的机制,我们形象的称为心跳。Slave通过心跳汇报自己的信息给
master,master也通过心跳给slave下达命令
	(4)NameNode通过心跳得知Datanode的状态,RescourceManager通过心跳得知NodeManager的状态
	(5)如果master长时间都没有收到slave的心跳,就认为该slave挂掉了

(六)MapReduce:

1.概念:
	
	MapReduce 是一个分布式运算程序的编程框架,是用户开发"基于 Hadoop 的数据
分析应用"的核心框架
	MapReduce 核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的
分布式运算程序,并发运行在一个Hadoop集群上 
	
2.整体结构:
		
	MRAppMaster:MapReduce Application Master,分配任务,协调任务的运行
	MapTask:阶段并发任务,负责 mapper 阶段的任务处理 YARNChild
	ReduceTask:阶段汇总任务,负责 reducer 阶段的任务处理 YARNChild
	jobtracker:主节点,既需要负责每个程序的运行协调,又需要负责资源调度
	tasktracker:从节点,跑任务的。maptask固定分配mapslot,reducetask固定分配reduceslot。
	jobtracker压力过大,没有合理利用资源
	
3.shuffle过程:
		
	(1)将文件按照文件大小计算分成多个块,每个块随机放入datenode中,一般为一个datanode放一个块
	(2)按照默认的分片,每个块分一个切片
	(3)每一个切片对应着每一个maptask,maptask里面有继承Mapper的自定义类,然后
将数据写入到收集器中(context.write(k,v))
	(4)收集器再将数据写入到环形缓冲区中
	(5)环形缓冲区有赤道,在赤道的两边一边进行元数据存储,一边进行原始数据存储,当
环形缓冲区(默认是100M)达到阈值80%时,开始往磁盘中溢写,剩下的20%继续接收数据,
当20%也满了之后,进入阻塞状态,直到溢写结束
	(6)文件溢写之前先进行排序,先按分区排再按key排
	(7)溢写完成之后,可能会产生多个溢写文件,将多个溢写文件进行归并排序,合成一个
溢写文件spill_finish
	(8)marppmatster获取到maptask的进度完成后,返回给reduce
	(9)reduce会开启5个线程池,用来抓取数据
	(10)将map中分好区的溢写文件按区号分别抓取,然后进行归并排序合成一个分好区分好
key的文件,将这些数据进行默认或者自定义分组
	(11)reducetask读取分组的数据,有几个区就有几个reducetask,reducetask里
面有继承Reduce的自定义类,然后将数据写出到hdfs中(context.write(k,v)),通过
FileOutputFormat设置的路径,文件格式是part-r(reduce)-00000,part-r(reduce)-00001,
有几个区就有几个文件,map输出的文件是part-m(map)-00000。
	
4.常用三大组件:
		
	(1)Combiner局部汇总:
			
		1)什么是Combiner
			Combiner是 MapReduce 程序中 Mapper 和 Reducer 之外的一种组件,
		它的作用是在 maptask之后给 maptask 的结果进行局部汇总,以减轻 reducetask
		的计算负载,减少网络传输
		2)如何使用Combiner
			编写一个类,然后继承Reducer,reduce方法中写具体的Combiner逻辑,
		然后在job中设置Combiner组件:job.setCombinerClass(类.class)
		3)使用Combiner注意事项
			1、Combiner 和 Reducer 的区别在于运行的位置:
				Combiner 是在每一个 MapTask 所在的节点运行
				Reducer 是接收全局所有 Mapper 的输出结果
			2、Combiner 的输出 kv 类型应该跟 Reducer 的输入 kv 类型对应起来
				Combiner 的输入 kv 类型应该跟 Mapper 的输出 kv 类型对应起来
			3、Combiner 的使用要非常谨慎,因为 Combiner 在 MapReduce 过程
			中可能调用也可能不调用,可能调一次也可能调多次,所以:
			Combiner 使用的原则是:有或没有都不能影响业务逻辑,都不能影响最终结果
		
	(2)Sort排序:
			
		基本思路:
			实现自定义的bean来封装流量信息,并将bean作为map输出的key来传输MR
		程序在处理数据的过程汇总会对数据排序(map输出的kv对传输到reduce之前,会排序)
			排序是依据map输出的key,所以我们如果要实现自己需要的排序规则,则可
		以考虑排序因素放到key中,让key实现接口:WritableComparable,然后重写key的compareTo方法。
		
	(3)Partitioner分区:
			
		基本思路:
			MapReduce中会将map输出的kv对,按照相同key分组,然后分发给不同的
		reducetask默认的分发规则为:根据key的hashcode%reducetask数来分发,
		所以:如果要是按照我们自己的需求分组,则需要改写数据分发(分组)组件Partitioner。
		自定义一个类,然后继承Partitioner,然后再job对象中,设置自定义Partitioner:
		job.setPartitionerClass(类.class);
		
	(4)自定义对象实现MapReduce框架的序列化:
				
		如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为
	MapReduce框架中的shuffle过程一定会对key进行排序,此时,自定义的bean实现的
	接口应该是:public class FlowBean implements WritableComparable<FlowBean>
	序列化框架在反序列化操作创建对象实例时会调用无参构造
	
5.典型编程场景:
		
	(1)多job串联:
			
		一个稍复杂点的处理逻辑往往需要多个 MapReduce 程序串联处理,多 job 的
	串联可以借助MapReduce 框架的 JobControl 实现
		有两个 MapReduce 任务,分别是 Flow 的 SumMR 和 SortMR,其中有依赖
	关系:SumMR的输出是 SortMR 的输入,所以 SortMR 的启动得在 SumMR 完成之后
	实现:
		ControlledJob sumcj = new ControlledJob(jobsum.getConfiguration());
		ControlledJob sortcj = new ControlledJob(jobsort.getConfiguration());
		sumcj.setJob(jobsum);
		sortcj.setJob(jobsort);
		//  设置作业依赖关系
		sortcj.addDependingJob(sumcj);
		JobControl jc = new JobControl("flow sum and sort");
		jc.addJob(sumcj);
		jc.addJob(sortcj);
		Thread jobThread = new Thread(jc);
		jobThread.start();
		
	(2)自定义GroupComparator:
			
		实现:
		第一步:先把分组和排序字段都综合到一个自定义对象里
		第二步:编写排序之后的 ClazzScore 数据传入 ReduceTask 的分组规则
		第三步:编写 MapReduce 程序
		// 设置传入 reducer 的数据分组规则
		job.setGroupingComparatorClass(ClazzScoreGroupComparator.class);
		
	(3)全局计数器:
			
		计数器是用来记录 job 的执行进度和状态的。它的作用可以理解为日志。我们可
	以在程序的某个位置插入计数器,记录数据或者进度的变化情况。
		
	(4)MapJoin-DistributedCashe
			
		MapReduce 的 Join 操作主要分两类:MapJoin 和 ReduceJoin
		先看 ReduceJoin:
		1) map 阶段,两份数据 data1 和 data2 会被 map 分别读入,解析成以链接
	字段为 key 以查询字段为 value 的 key-value 对,并标明数据来源是 data1
	还是 data2。
		2) reduce 阶段,reducetask 会接收来自 data1 和 data2 的相同 key 的
	数据,在 reduce 端进行乘积链接,最直接的影响是很消耗内存,导致 OOM
		再看 MapJoin:
		MapJoin 适用于有一份数据较小的连接情况。做法是直接把该小份数据直接全部
	加载到内存当中,按链接关键字建立索引。然后大份数据就作为 MapTask 的输入,
	对 map()方法的每次输入都去内存当中直接去匹配连接。然后把连接结果按 key 输出,
	这种方法要使用 hadoop中的 DistributedCache 把小份数据分布到各个计算节点,
	每个 maptask 执行任务的节点都需要加载该数据到内存,并且按连接关键字建立索引
		实现:
		第一步:封装 MovieRate,方便数据的排序和序列化
		第二步:编写 MapReduce 程序
		
	(5)自定义 OutputFormat-- 数据分类输出
			
		现有一些原始日志需要做增强解析处理
		流程:
			1、 从原始日志文件中读取数据
			2、 根据业务获取业务数据库的数据
			3、 根据某个连接条件获取相应的连接结果
		典型业务场景如:爬虫 URL 管理,移动号码管理
		实现要点:
			1、 在 MapReduce 中访问外部资源
			2、 自定义 OutputFormat,改写其中的 RecordWriter,改写具体输出数据的方法 write()
		
	(6)自定义 InputFormat-- 小文件合并
			
		小文件的优化无非以下几种方式:
			1、 在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS
			2、 在业务处理之前,在 HDFS 上使用 MapReduce 程序对小文件进行合并
			3、 在 MapReduce 处理时,可采用 CombineFileInputFormat 提高效率
		核心实现思路:
			1、编写自定义的 InputFormat
			2、改写 RecordReader,实现一次 maptask 读取一个小文件的完整内容封装了一个 KV 对
				3、在 Driver 类中一定要设置使用自定义的 InputFormat:
				job.setInputFormatClass(WholeFileInputFormat.class)
	
6.框架不足:
		
	(1)扩展性差
	(2)可靠性低
	(3)资源利用率低
	(4)不支持多种计算框架

(七)YARN

	1.概念:
	
		YARN 是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操
	作系统平台,而 MapReduce 等运算程序则相当于运行于操作系统之上的应用程序
	
	2.特点:
		
		(1)YARN 并不清楚用户提交的程序的运行机制
		(2)YARN 只提供运算资源的调度(用户程序向 YARN 申请资源,YARN 就负责分配资源)
		(3)YARN 中的主管角色叫 ResourceManager
		(4)YARN 中具体提供运算资源的角色叫 NodeManager
		(5)这样一来,YARN 其实就与运行的用户程序完全解耦,就意味着 YARN 上可以运行各种类
			型的分布式运算程序(MapReduce 只是其中的一种),比如 MapReduce、Storm 程序,Spark
			程序,Tez ……
		(6)所以,Spark、Storm 等运算框架都可以整合在 YARN 上运行,只要他们各自的框架中有
			符合 YARN 规范的资源请求机制即可
		(7)yarn 就成为一个通用的资源调度平台,从此,企业中以前存在的各种运算集群都可以整
			合在一个物理集群上,提高资源利用率,方便数据共享
	
	3.主节点ResourceManager:
		
		(1)YARN 集群的主节点 ResourceManager 的职责:
			1)处理客户端请求
			2)启动或监控 MRAppMaster
			3)监控 NodeManager
			4)资源的分配与调度
		(2)两个组件:
			1)应用程序管理器ApplicationsManager(ASM):
				负责管理所有的application----mr计算程序----wordcount程序				
				负责管理application的状态,分配application的运行的资源				
			2)调度器Scheduler:
				负责每一个application任务的资源调度
				负责application的调度
				FIFO(单一队列调度器):FIRST IN FIRST out
					先提交的任务先执行  后提交的任务后执行
				FAIR(公平调度器):
					第一个任务来了: 所有的资源全部跑
					第二个任务来了:两个任务平均分配资源,各占用一半的资源
					第三个任务来了:各占1/3
				CAPACITY(计算能力调度器):
					多个队列,每个队列都是先进先出模式
					手动设置
					任务1:1T   任务2:9T
					根据实际的任务量进行资源配置
					10%         90%
					根据不同的业务部门:
					报表:60%     其他:40%
	
	4.从节点NodeManager:
		
		(1)YARN 集群的从节点 NodeManager 的职责:
			1)管理单个节点上的资源
			2)处理来自 ResourceManager 的命令
			3)处理来自 MRAppMaster 的命令
		(2)虚拟资源容器的方式(Container):
			Container 容器是一个抽象出来的逻辑资源单位。容器是由 ResourceManager Scheduler 服务
		动态分配的资源构成,它包括了(封装)该节点上的一定量 CPU,内存,磁盘,网络等信息,MapReduce
		程序的所有 Task 都是在一个容器里执行完成的,容器的大小是可以动态调整的
			Container----1个maptask任务/1个reducetask任务
				小文件执行的时候:
					container的启动和销毁过程的时间大于计算的时间  不划算
					大量小文件的时候:
						uber:false/true
						拼车模式运行-----一个container中可以运行10个maptask的小任务
	
	5.yarn的资源调度:
		
		(1)客户端进行应用程序提交的时候,先提交给resourcemanager
		(2)resourcemanager会给客户端返回一个节点,用于启动MRAppmaster
		(3)rm(ASM)在对应的节点上先启动Container,并在Container中启动MRAppmaster(在nodemanager上)
		(4)MRAppmaster向resourcemanager申请程序运行资源,包括maptask和reducetask的资源
		(5)resourcemanager会给MRAppmaster返回maptask和reducetask运行的资源节点,其中会优先返回
			需要计算数据本地化存在的节点
		(6)MRAppmaster到对应的节点上启动Container,在container中启动maptask和reducetask任务
		(7)maptask、reducetask向MRAppmaster进行汇报---进度---状态
		(8)当所有的maptask和reducetask任务都执行完毕的时候MRAppmaster向resourcemanager进行汇报,回收资源
	
	6.job提交:
		
		(1)客户端向resourcemanager发送提交job的请求
		(2)resourcemanager会进行检查,检查通过,则会返回一个applicationID(全局唯一的,任务提交先后的标识)
			和一个共享资源路径(hdfs上的路径:jar)
		(3)客户端将共享资源提交到共享资源路径下:job.xml,job.split,job.jar
		(4)客户端向resourcemanager返回提交完毕并真正的提交这个任务
		(5)resourcemanager会给客户端返回一个节点,用于启动MRAppmaster
		(6)到对应的节点上启动container并启动MRAppmaster
		(7)MRAppmaster首先初始化job并生成一个作业簿,去共享资源路径下访问共享资源获取切片信息以及配置文件信息等
		(8)MRAppmaster向resourcemanager申请程序运行资源,包括maptask和reducetask的资源
		(9)resourcemanager会给MRAppmaster返回maptask和reducetask运行的资源节点,其中会优先返回
			需要计算数据本地化存在的节点
		(10)到共享资源路径下下载jar包和切片信息等资源
		(11)MRAppmaster到对应的节点上启动Container,在container中启动maptask任务
		(12)maptask向MRAppmaster汇报自己的状态和进度,存储在作业簿中
		(13)MRAppmaster监控到有一个maptask执行完毕,启动reducetask
		(14)reducetask向MRAppmaster进行汇报自己的进度和状态
		(15)当所有的maptask和reducetask任务都执行完毕的时候就会向MRAppmaster进行汇报,并注销和关闭资源
		(16)MRAppmaster向resourcemanager注销并关闭自己

(八)hive

	1.概念:
		
		Hive 由 Facebook 实现并开源,是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据
	映射为一张数据库表,并提供 HQL(Hive SQL)查询功能,底层数据是存储在 HDFS 上。Hive
	的本质是将 SQL 语句转换为 MapReduce 任务运行,使不熟悉 MapReduce 的用户很方便地利
	用 HQL 处理和计算 HDFS 上的结构化的数据,适用于离线的批量数据计算。
		数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、
	反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。
	
	2.特点:
		
		(1)优点:
			1、可扩展性, 横向扩展,Hive 可以自由的扩展集群的规模,一般情况下不需要重启服务
				横向扩展:通过分担压力的方式扩展集群的规模
				纵向扩展: 一台服务器cpu i7-6700k 4核心8线程,8核心16线程,内存64G => 128G
			2、延展性,Hive 支持自定义函数,用户可以根据自己的需求来实现自己的函数
			3、良好的容错性,可以保障即使有节点出现问题,SQL 语句仍可完成执行
		(2)缺点 :
			1、Hive 不支持记录级别的增删改操作,但是用户可以通过查询生成新表或者将查询结
				果导入到文件中(当前选择的 hive-2.3.2 的版本支持记录级别的插入操作)
			2、Hive 的查询延时很严重,因为 MapReduce Job 的启动过程消耗很长时间,所以不能
				用在交互查询系统中。
			3、Hive  不支持事务(因为不没有增删改,所以主要用来做 OLAP(联机分析处理),而
				不是 OLTP(联机事务处理),这就是数据处理的两大级别)。
	
	3.架构:
		
		(1)用户接口层:
		
			1、CLI,Shell 终端命令行(Command Line Interface),采用交互形式使用 Hive 命令行与 Hive进行交互,最常用(学习,调试,生产)
			2、JDBC/ODBC,是 Hive 的基于 JDBC 操作提供的客户端,用户(开发员,运维人员)通过这连接至 Hive server 服务
			3、Web UI,通过浏览器访问 Hive
			
		(2)Thrift Server
			
			Thrift 是 Facebook 开发的一个软件框架,可以用来进行可扩展且跨语言的服务的开发,
		Hive 集成了该服务,能让不同的编程语言调用 Hive 的接口
		
		(3)元数据存储
			
			元数据,通俗的讲,就是存储在 Hive 中的数据的描述信息。
			Hive 中的 元数据通常包括:表的名字,表的列和分区及其属性,表的属性(内部表和外部表),表的数据所在目录
			Metastore 默认存在自带的 Derby 数据库中。缺点就是不适合多用户操作,并且数据存储目录不固定。数据库跟着 Hive 走,极度不方便管理
			解决方案:通常存我们自己创建的 MySQL 库(本地或远程)
			Hive 和 MySQL 之间通过 MetaStore 服务交互
		
		(4)Driver : 编译器 (Compiler),优化器 (Optimizer),执行器 (Executor)
			
			Driver 组件完成 HQL 查询语句从词法分析,语法分析,编译,优化,以及生成逻辑执行计划的生成。
			生成的逻辑执行计划存储在 HDFS 中,并随后由 MapReduce 调用执行
			Hive 的核心是驱动引擎, 驱动引擎由四部分组成:
				1、解释器:解释器的作用是将 HiveSQL 语句转换为抽象语法树(AST)
				2、编译器:编译器是将语法树编译为逻辑执行计划
				3、优化器:优化器是对逻辑执行计划进行优化
				4、执行器:执行器是调用底层的运行框架执行逻辑执行计划
		
		(5)执行流程
			
			HiveQL 通过命令行或者客户端提交,经过 Compiler 编译器,运用 MetaStore 中的元数
		据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过的优化处理,产生
		一个 MapReduce 任务。
	
	4.数据存储:
		
		(1)Hive 的存储结构包括 数据库 、表、 视图 、分区 和表 数据等。数据库,表,分区等等都对
			应 HDFS 上的一个目录。表数据对应 HDFS 对应目录下的文件。
		(2)Hive 中所有的数据都存储在 HDFS 中,没有专门的数据存储格式,因为 Hive 是 读模式
			(Schema On Read),可支持 TextFile,SequenceFile,RCFile 或者自定义格式等
		(3)只需要在创建表的时候告诉 Hive 数据中的 列分隔符和 行分隔符,Hive 就可以解析数据
			Hive 的默认列分隔符:控制符 Ctrl + A,\x01
			Hive 的默认行分隔符:换行符 \n
		(4)Hive 中包含以下数据模型:
			database:在 HDFS 中表现为${hive.metastore.warehouse.dir}目录下一个文件夹
			table:在 HDFS 中表现所属 database 目录下一个文件夹
			external table:与 table 类似,不过其数据存放位置可以指定任意 HDFS 目录路径
			partition:在 HDFS 中表现为 table 目录下的子目录
			bucket:在 HDFS 中表现为同一个表目录或者分区目录下根据某个字段的值进行 hash 散列之后的多个文件
			view:与传统数据库类似,只读,基于基本表创建
		(5)Hive 的元数据存储在 RDBMS 中,除元数据外的其它所有数据都基于 HDFS 存储。默认情
			况下,Hive 元数据保存在内嵌的 Derby 数据库中,只能允许一个会话连接,只适合简单的
			测试。实际生产环境中不适用,为了支持多用户会话,则需要一个独立的元数据库,使用
			MySQL 作为元数据库,Hive 内部对 MySQL 提供了很好的支持。
		(6)Hive 中的表分为 内部表、 外部表、 分区表和 Bucket
		(7)内部表和外部表的区别:
			删除内部表,删除表元数据和数据
			删除外部表,删除元数据,不删除数据
		(8)分区表和分桶表的区别:
			Hive 数据表可以根据某些字段进行分区操作,细化数据管理,可以让部分查询更快。同
		时表和分区也可以进一步被划分为 Buckets,分桶表的原理和 MapReduce 编程中的HashPartitioner 的原理类似
			分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于 Hive 是读模式,
		所以对添加进分区的数据不做模式校验,分桶表中的数据是按照某些分桶字段进行 hash 散列形成的多个文件,所以数据的准确性也高很多

(九)ZooKeeper

	1.概念:
		
		ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby一个开源的实现。它提供了简单原始的功能,
	分布式应用可以基于它实现更高级的服务,比如分布式同步,配置管理,集群管理,命名管理,队列管理。
	
	2.文件系统:
		
		ZooKeeper 的命名空间就是 ZooKeeper 应用的文件系统,而ZooKeeper统一叫做znode,
	一个 znode 节点可以包含子 znode,同时也可以包含数据。
		在 ZooKeeper 这里面就不叫文件文件也不叫文件夹,叫znode,每个znode有唯一的路径标识,既能存储数据,也能创建子znode。
	但是 znode 只适合存储非常小量的数据,不能超过 1M,最好小于 1K。
		1)znode类型:
			短暂(ephemeral)(断开连接自己删除)
			持久(persistent)(断开连接不删除)
		2)四种目录节点:
			PERSISTENT:持久化 znode 节点,一旦创建这个 znode 点存储的数据不会主动消失,除非是客户端主动的 delete
			PERSISTENT_SEQUENTIAL:自动增加顺序编号的 znode 节点
			EPHEMERAL:临时 znode 节点
			EPHEMERAL_SEQUENTIAL:临时自动编号节点,znode 节点编号会自动增加,但是会随session 消失而消失
		3)创建 znode 时设置顺序标识,znode 名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护
		4)在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序
		5)EPHEMERAL 类型的节点不能有子节点
		6)客户端可以在 znode 上设置监听器
	
	3.监听机制:
		
		客户端注册监听它关心的目录节点,当目录节点发生变化( 数据改变、 节点 删除、 子目录节点增加删除)时,
	ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序
	
	4.监听工作原理:
		
		ZooKeeper 的 Watcher 机制主要包括 客户端线程、 客户端 WatcherManager、Zookeeper  服务器三部分。
	客户端在向 ZooKeeper 服务器注册的同时,会将 Watcher 对象存储在客户端的WatcherManager 当中。
	当 ZooKeeper 服务器触发 Watcher 事件后,会向客户端发送通知,客户端线程从 WatcherManager 中取出对应的 Watcher 对象来执行回调逻辑
	
	5.ZooKeeper 典型应用场景
		
		1)命名服务:
			分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等,通过命名服务,客户端可以根据指定名字来获
		取资源的实体、服务地址和提供者的信息。在分布式环境中,上层应用仅仅需要一个全局唯一的名字。
		2)配置管理:
			程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。现在把这些配置全部放到 ZooKeeper 上去,
		保存在 ZooKeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到
		ZooKeeper 的通知,然后从 ZooKeeper 获取新的配置信息应用到系统中就好
		3)集群管理:
			所谓集群管理无在乎两点: 是否有机器退出和加入、选举 master。
			对于第一点,所有机器约定在父目录 GroupMembers 下创建临时目录节点,然后监听父目录节点的子节点变化消息。
			对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为 master 就好
		4)分布式锁:
			锁服务可以分为两三类
			一个是 写锁, 对写加锁, 保持独占 , 或者叫做排它锁,独占锁
			一个是 读锁,对读加锁 ,可共享访问,释放锁之后才可进行事务 操作,也叫共享锁
			一个是控制时序,叫时序锁
		5)队列管理:
			两种类型的队列:
			1、 同步队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
			2、 先进先出队列:队列按照 FIFO 方式进行入队和出队操作。
			第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
			第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。
	
	6.特点和设计目的:
		
		ZooKeeper 作为一个集群提供数据一致的协调服务,自然,最好的方式就是在整个集群中的各服务节点进行数据的复制和同步。
		数据复制的好处:
			1、容错:一个节点出错,不至于让整个集群无法提供服务、、
			2、扩展性:通过增加服务器节点能提高 ZooKeeper 系统的负载能力,把负载分布到多个节点上
			3、高性能:客户端可访问本地 ZooKeeper 节点或者访问就近的节点,依次提高用户的访问速度
	
	7.原理解析:
		
		1)集群角色描述:
			
			leader:领导者负责进行投票的发起和决议,更新系统状态
			follower:用于接收客户端请求并向客户端返回结果,在选主过程中参与投票
			observer:可以接收客户端连接,将写请求转发到leader节点。但observer不参与投票过程,只同步leader
						的状态。observer的目的是为了扩展系统,提高读取速度。
		
		2)Paxos:
			
			三种角色:
				1.Proposer:提议者,用来发出提案 proposal
				2.Acceptor:接受者,可以接受或拒绝提案
				3.Learner:学习者,学习被选定的提案,当提案被超过半数的 Acceptor 接受后为被批准
			解决问题:
				1.决议(value)只有在被 proposer 提出后才能被批准
				2.在一次 Paxos 算法的执行实例中,只批准(chose)一个 value
				3.learner 只能获得被批准(chosen)的 value
			ZooKeeper 的选举算法有两种:一种是基于 Basic Paxos(Google Chubby 采用)实现的,另外
		一种是基于 Fast Paxos(ZooKeeper 采用)算法实现的。
			ZooKeeper 的核心是原子广播,这个机制保证了各个 Server 之间的同步。实现这个机制的协
		议叫做 ZAB  协议(Zookeeper Atomic BrodCast)。
			ZAB 协议有两种模式,它们分别是 崩溃 恢复模式(选主)和 原子) 广播模式(同步)。
		
		3)ZooKeeper 的全新集群选主
			
			1、服务器 1 启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的
				选举状态一直是 LOOKING 状态
			2、服务器 2 启动,它与最开始启动的服务器 1 进行通信,互相交换自己的选举结果,由于
				两者都没有历史数据,所以 id 值较大的服务器 2 胜出,但是由于没有达到超过半数以上的
				服务器都同意选举它(这个例子中的半数以上是 3),所以服务器 1、2 还是继续保持 LOOKING状态
			3、服务器 3 启动,根据前面的理论分析,服务器 3 成为服务器 1,2,3 中的老大,而与上面不
				同的是,此时有三台服务器(超过半数)选举了它,所以它成为了这次选举的 leader
			4、服务器 4 启动,根据前面的分析,理论上服务器 4 应该是服务器 1,2,3,4 中最大的,但是
				由于前面已经有半数以上的服务器选举了服务器 3,所以它只能接收当小弟的命了
			5、服务器 5 启动,同 4 一样,当小弟
			总结:zookeeper server 的三种工作状态
			LOOKING:当前 Server 不知道 leader 是谁,正在搜寻,正在选举
			LEADING:当前 Server 即为选举出来的 leader,负责协调事务
			FOLLOWING:leader 已经选举出来,当前 Server 与之同步,服从 leader 的命令
		
		4)ZooKeeper 的非全新集群选主
			
			当 zookeeper 运行了一段时间之后,有机器 down 掉,重新选举时
			需要加入数据 version、serverid 和逻辑时钟。
			数据 version:数据新的 version 就大,数据每次更新都会更新 version
			server id:就是我们配置的 myid 中的值,每个机器一个
			逻辑时钟:这个值从 0 开始递增,每次选举对应一个值
				选举的标准就变成:
			1 、逻辑时钟小的选举结果被忽略,重新投票
			2 、统一逻辑时钟后,数据 version  大的胜出
			3 、数据 version  相同的情况下,server id  大的胜出
			根据这个规则选出 leader。
	
	8.数据同步:
		
		选完 leader 以后,zk 就进入状态同步过程。
			1、leader 等待 server 连接;
			2、follower 连接 leader,将最大的 zxid 发送给 leader;
			3、leader 根据 follower 的 zxid 确定同步点;
			4、完成同步后通知 follower 已经成为 uptodate 状态;
			5、follower 收到 uptodate 消息后,又可以重新接受 client 的请求进行服务了。
	
	9.ZooKeeper 工作流程:
		
		1)Leader 工作流程
			
			Leader 主要有三个功能:
			1、恢复数据
			2、维持与 Learner 的心跳,接收 Learner 请求并判断 Learner 的请求消息类型
				Learner 的消息类型主要:
				PING 消息:Learner 的心跳信息
				REQUEST 消息:Follower 发送的提议信息,包括读写请求
				ACK 消息:Follower 对提议的回复,超过半数的 Follower 通过,则 commit 该提议
				REVALIDATE 消息:用来延长 SESSION 有效时间
			3、根据不同的消息类型,进行不同的处理。
		
		2)Follower 工作流程
			
			Follower 主要有四个功能:
			1、向 Leader 发送请求(PING 消息、REQUEST 消息、ACK 消息、REVALIDATE 消息);
			2、接收 Leader 消息并进行处理;
			3、接收 Client 的请求,如果为写请求,则转发给 Leader;
			4、返回 Client 结果。
			Follower 的消息循环处理如下几种来自 Leader 的消息:
			1、PING 消息: 心跳消息;
			2、PROPOSAL 消息:Leader 发起的提案,要求 Follower 投票;
			3、COMMIT 消息:服务器端最新一次提案的信息;
			4、UPTODATE 消息:表明同步完成;
			5、REVALIDATE 消息:根据 Leader 的 REVALIDATE 结果,关闭待 revalidate 的 session 还是允许其接受消息;
			6、SYNC 消息:返回 SYNC 结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
		
		3)Observer 工作流程

(十)HBase

	1.概念:
		
		HBase 是 BigTable  的开源(源码使用 Java  编写)版本。是 Apache Hadoop 的数据库,是建在立在 HDFS  之上,
	被设计用来提供高可靠性、高性能、列存储、可伸缩的 、多版本的 NoSQL的分布式数据存储系统,实现对大型数据的实时、随机的读写访问 。
		HBase  依赖于 HDFS  做底层的数据存储 ,BigTable  依赖 Google GFS  做数据存储
		HBase  依赖于 MapReduce  做数据计算 ,BigTable  依赖 Google MapReduce  做数据计算
		HBase  依赖于 ZooKeeper  做服务协调 ,BigTable  依赖 Google Chubby 做服务协调
	
	2.关系型数据库和非关系型数据库的典型代表:
		
		NoSQL:hbase, redis, mongodb
		RDBMS:mysql,oracle,sql server,db2	
	
	3.HBase (NoSQL 数据库)的要点:	
		
		1)它介于 NoSQL 和 RDBMS 之间, 仅能通过主键(rowkey) 和主键的 range 来检索数据
		2)HBase 查询数据功能很简单, 不支持 join 等复杂操作
		3)不支持复杂的事务, 只支持 行级 事务(可通过 hive 支持来实现多表 join 等复杂操作)。
		4)HBase 中支持的数据类型:byte[] (底层所有数据的存储都是字节数组)
		5)主要用来存储结构化和半结构化的松散数据
			结构化:数据结构字段含义确定,清晰,典型的如数据库中的表结构
			半结构化:具有一定结构,但语义不够确定,典型的如 HTML 网页,有些字段是确定的(title),有些不确定(table)
			非结构化:杂乱无章的数据,很难按照一个概念去进行抽取,无规律性
	
	4.HBase 中的表特点
		
		1)大:一个表可以有上十亿行,上百万列
		2)面向列:面向列(族)的存储和权限控制,列(簇)独立检索。
		3)稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
		4)无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列
	
	5.表结构逻辑视图
		
		HBase 以表的形式存储数据。表由行和列组成。列划分为若干个列簇 (ColumnFamily)
		表结构:
			rowkey:按字典排序
			列簇:包含一组列,列在插入数据时指定,列簇在建表时指定
			列:一个列簇中可以有多个列,并且可以不同
			时间戳:每个列的值可以存多个版本的值,版本号就是时间戳,按照时间戳由近到远排序
		查数据流程:表---》rowkey---》列簇---》列---》时间戳
	
	6.行键 (RowKey)
		
		访问 HBase Table 中的行,只有三种方式:
		1)通过单个 row key  访问
		2)通过 row key 的 的 range
		3)全表扫描
		rowkey 行键可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),最
	好是8的倍数。在 HBase 内部,rowkey 保存为字节数组。HBase  会对表中的数据按照 rowkey  排序(字典顺序)
	
	7.列簇(Column Family)
		
		HBase 表中的每个列,都归属与某个列簇。列簇是表的 Schema 的一部分(而列不是),必须在使用表之前定义好,而且定义好了之后就不能更改。
		列名都以列簇作为前缀。例如 courses:history,courses:math 都属于 courses 这个列簇。访问控制、磁盘和内存的使用统计等都是在列簇层面进行的。
		列簇越多,在取一行数据时所要参与 IO、搜寻的文件就越多,所以,如果没有必要,不要设置太多的列簇(最好就一个列簇)
	
	8.时间戳:
		
		HBase 中通过 rowkey 和 columns 确定的为一个存储单元称为 cell。每个 cell 都保存着同一份数据的多个版本。版本通过时间戳来索引。
	时间戳的类型是 64 位整型。时间戳可以由hbase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由
	客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
	每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
		为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,hbase 提供了两种数据版本回收方式:
			保存数据的最后 n  个 版本
			保存最近一段时间内的版本(设置数据的生命周期 TTL )。
		用户可以针对每个列簇进行设置。
	
	9.单元格(cell):
		
		由{rowkey, column( =<family> + <column>), version} 唯一确定的单元。
		Cell 中的数据是没有类型的,全部是字节码形式存贮。
	
	10.HBase 应用场景
		
		1)半结构化或非结构化数据
		2)记录非常稀疏
		3)多版本数据
		4)超大数据量
	
	11.集群结构:
		
		1)region:是 hbase 中对表进行切割的单元,由 regionserver 负责管理
			
		2)hamster:hbase 的主节点,负责整个集群的状态感知,负载分配、负责用户表的元数据(schema)
			管理(可以配置多个用来实现 HA),hmaster 负载压力相对于 hdfs 的 namenode 会小很多
		3)regionserver:hbase 中真正负责管理 region 的服务器,也就是负责为客户端进行表数据读写
			的服务器每一台 regionserver 会管理很多的 region,同一个 regionserver 上面管理的所有的
			region 不属于同一张表
		4)zookeeper:整个 hbase 中的主从节点协调,主节点之间的选举,集群节点之间的上下线感
			知都是通过 zookeeper 来实现
		5)HDFS:用来存储 hbase 的系统文件,或者表的 region
	
	12.系统架构:
		
		1)Client 职责:
			
			1、HBase 有两张特殊表:
				.META.:记录了用户所有表拆分出来的的 Region 映射信息,.META.可以有多个 Regoin
				-ROOT-:记录了.META.表的 Region 信息,-ROOT-只有一个 Region,无论如何不会分裂
			2、Client 访问用户数据前需要首先访问 ZooKeeper,找到-ROOT-表的 Region 所在的位置,然
				后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次
				网络操作,不过 client 端会做 cache 缓存。
		
		2)ZooKeeper 职责:
			
			1、ZooKeeper 为 HBase 提供 Failover 机制,选举 Master,避免单点 Master 单点故障问题
			2、存储所有 Region 的寻址入口:-ROOT-表在哪台服务器上。-ROOT-这张表的位置信息
			3、实时监控 RegionServer 的状态,将 RegionServer 的上线和下线信息实时通知给 Master
			4、存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family
		
		3)Master 职责:
			
			1、为 RegionServer 分配 Region
			2、负责 RegionServer 的负载均衡
			3、发现失效的 RegionServer 并重新分配其上的 Region
			4、HDFS 上的垃圾文件(HBase)回收
			5、处理 Schema 更新请求(表的创建,删除,修改,列簇的增加等等)
		
		4)RegionServer 职责:
			
			1、RegionServer 维护 Master 分配给它的 Region,处理对这些 Region 的 IO 请求
			2、RegionServer 负责 Split 在运行过程中变得过大的 Region,负责 Compact 操作
		
		5)可以看到:
			
			client 访问 HBase 上数据的过程并不需要 master 参与(寻址访问 zookeeper 和
		RegioneServer,数据读写访问 RegioneServer),Master 仅仅维护者 Table 和 Region 的元数据
		信息,负载很低。
			.META. 存的是所有的 Region 的位置信息,那么 RegioneServer 当中 Region 在进行分裂之后
		的新产生的 Region,是由 Master 来决定发到哪个 RegioneServer,这就意味着,只有 Master
		知道 new Region 的位置信息,所以,由 Master 来管理.META.这个表当中的数据的 CRUD
			所以结合以上两点表明,在没有 Region 分裂的情况,Master 宕机一段时间是可以忍受的。
	
	13.HBase 和 Hive  的 比较:
		
		1)相同点:
			HBase 和 Hive 都是架构在 Hadoop 之上,用 HDFS 做底层的数据存储,用 MapReduce 做数据计算
		2)不同点:
			1、Hive 是建立在 Hadoop 之上为了降低 MapReduce 编程复杂度的 ETL 工具。
				HBase 是为了弥补 Hadoop 对实时操作的缺陷
			2、Hive 表是纯逻辑表,因为 Hive 的本身并不能做数据存储和计算,而是完全依赖 Hadoop
				HBase 是物理表,提供了一张超大的内存 Hash 表来存储索引,方便查询
			3、Hive 是数据仓库工具,需要全表扫描,就用 Hive,因为 Hive 是文件存储
				HBase 是数据库,需要索引访问,则用 HBase,因为 HBase 是面向列的 NoSQL 数据库
			4、Hive 表中存入数据(文件)时不做校验,属于读模式存储系统
				HBase 表插入数据时,会和 RDBMS 一样做 Schema 校验,所以属于写模式存储系统
			5、Hive 不支持单行记录操作,数据处理依靠 MapReduce,操作延时高
				HBase 支持单行记录的 CRUD,并且是实时处理,效率比 Hive 高得多
	
	14.过滤器分类:
		
		1)比较过滤器
			行键过滤器 RowFilter
			列簇过滤器 FamilyFilter
			列过滤器 QualifierFilter
			值过滤器 ValueFilter
			时间戳过滤器 TimestampsFilter
		2)专用过滤器
			单列值过滤器 SingleColumnValueFilter ----会返回满足条件的整行
			单列值排除器 SingleColumnValueExcludeFilter -----返回排除了该列的结果
			前缀过滤器 PrefixFilter----针对行键
			列前缀过滤器 ColumnPrefixFilter
			分页过滤器 PageFilter
	
	15.物理存储:
		
		1)整体物理结构:
			
			1、Table 中的所有行都按照 RowKsey 的字典序排列。
			2、Table 在行的方向上分割为多个 HRegion。
			3、HRegion 按大小分割的(默认 10G),每个表一开始只有一个 HRegion,随着数据不断插入
				表,HRegion 不断增大,当增大到一个阀值的时候,HRegion 就会等分会两个新的 HRegion。
				当表中的行不断增多,就会有越来越多的 HRegion。
			4、HRegion 是 Hbase 中分布式存储和负载均衡的最小单元。最小单元就表示不同的 HRegion
				可以分布在不同的 HRegionserver 上。但一个 HRegion 是不会拆分到多个 server 上的。
			5、HRegion 虽然是负载均衡的最小单元,但并不是物理存储的最小单元。事实上,HRegion
				由一个或者多个 Store 组成,每个 Store 保存一个 Column Family。每个 Strore 又由一个
				memStore 和 0 至多个 StoreFile 组成
		
		2)StoreFile 和 HFile 结构:
			
			StoreFile 以 HFile 格式保存在 HDFS 上
			HFile 分为六个部分:
			Data Block  段–保存表中的数据,这部分可以被压缩
			Meta Block  段 (可选的)–保存用户自定义的 kv 对,可以被压缩。
			File Info  段–Hfile 的元信息,不被压缩,用户也可以在这一部分添加自己的元信息。
			Data Block Index  段–Data Block 的索引。每条索引的 key 是被索引的 block 的第一条记录的key。
			Meta Block Index  段 (可选的)–Meta Block 的索引。
			Trailer  段–这一段是定长的。保存了每一段的偏移量,读取一个 HFile 时,会首先读取 Trailer,
			Trailer保存了每个段的起始位置(段的Magic Number用来做安全check),然后,DataBlock Index
			会被读取到内存中,这样,当检索某个 key 时,不需要扫描整个 HFile,而只需从内存中找
			到key所在的block,通过一次磁盘io将整个block读取到内存中,再找到需要的key。DataBlock
			Index 采用 LRU 机制淘汰。
		
		3)MemStore 和 StoreFile:
			
			一个 Hregion 由多个 Store 组成,每个 Store 包含一个列族的所有数据
			Store 包括位于内存的一个 memstore 和位于硬盘的多个 storefile 组成
			写操作先写入 memstore,当 memstore 中的数据量达到某个阈值,HRegionServer 启动
			flushcache 进程写入 storefile,每次写入形成单独一个 Hfile
			当总 storefile 大小超过一定阈值后,会把当前的 region 分割成两个,并由 HMaster 分配给相
			应的 region 服务器,实现负载均衡
			客户端检索数据时,先在 memstore 找,找不到再找 storefile
		
		4)HLog(WAL):	
			
			WAL 意为 Write ahead log(http://en.wikipedia.org/wiki/Write-ahead_logging),类似 mysql 中的
		binlog,用来做灾难恢复之用,Hlog 记录数据的所有变更,一旦数据修改,就可以从 log 中
		进行恢复。
			每个 Region Server 维护一个 Hlog,而不是每个 Region 一个。这样不同 region(来自不同 table)
		的日志会混在一起,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减
		少磁盘寻址次数,因此可以提高对 table 的写性能。带来的麻烦是,如果一台 region server
		下线,为了恢复其上的 region,需要将 region server 上的 log 进行拆分,然后分发到其它 region
		server 上进行恢复。
	
	16.寻址机制:
		
		1)老的 Region 寻址方式
			
			在 HBase-0.96 版本以前,HBase 有两个特殊的表,分别是-ROOT-表和.META.表,其中-ROOT-
		的位置存储在 ZooKeeper 中,-ROOT-本身存储了.META. Table 的 RegionInfo 信息,并且-ROOT-
		不会分裂,只有一个 Region。而.META.表可以被切分成多个 Region。
			读取的流程:
				第 1 步:Client 请求 ZooKeeper 获得-ROOT-所在的 RegionServer 地址
				第 2 步:Client 请求-ROOT-所在的 RS 地址,获取.META.表的地址,Client 会将-ROOT-的相关
						信息 cache 下来,以便下一次快速访问
				第 3 步:Client 请求.META.表的 RegionServer 地址,获取访问数据所在 RegionServer 的地址,
						Client 会将.META.的相关信息 cache 下来,以便下一次快速访问
				第 4 步:Client 请求访问数据所在 RegionServer 的地址,获取对应的数据
		
		2)新的 Region 寻址方式
			
			将-ROOT-表去掉了
			总结去掉-ROOT-的原因有如下 2 点:
			其一:提高性能
			其二:2 层结构已经足以满足集群的需求
			读取的流程:
				第 1 步:Client 请求 ZooKeeper 获取.META.所在的 RegionServer 的地址。
				第 2 步:Client 请求.META.所在的 RegionServer 获取访问数据所在的 RegionServer 地址,Client
						会将.META.的相关信息 cache 下来,以便下一次快速访问。
				第 3 步:Client 请求数据所在的 RegionServer,获取所需要的数据。
	
	17.读写流程:
		
		1)读请求过程:
			
			1、客户端通过 ZooKeeper 以及-ROOT-表和.META.表找到目标数据所在的 RegionServer(就是数据所在的 Region 的主机地址)
			2、联系 RegionServer 查询目标数据
			3、RegionServer 定位到目标数据所在的 Region,发出查询请求
			4、Region 先在 Memstore 中查找,命中则返回
			5、如果在 Memstore 中找不到,则在 Storefile 中扫描,为了能快速的判断要查询的数据在不在这个 StoreFile 中,应用了 BloomFilter
			(BloomFilter ,布隆过滤器:迅速判断一个元素是不是在一个庞大的集合内,但是他有一个弱点:它有一定的误判率)
			(误判率:原本不存在与该集合的元素,布隆过滤器有可能会判断说它存在,但是,如果
				布隆过滤器,判断说某一个元素不存在该集合,那么该元素就一定不在该集合内)
		
		2)写请求过程:
			
			1、Client 先根据 RowKey 找到对应的 Region 所在的 RegionServer
			2、Client 向 RegionServer 提交写请求
			3、RegionServer 找到目标 Region
			4、Region 检查数据是否与 Schema 一致
			5、如果客户端没有指定版本,自动插入版本信息,获取当前系统时间作为数据版本
			6、将更新写入 WAL Log,做灾难备份使用
			7、将更新写入 Memstore
			8、判断 Memstore 的是否(当Memstore写满的时候)需要 flush 为 StoreFile 文件,。
			
			建议: 在做海量数据的插入操作,避免出现递增 rowkey 的 put 操作
			如果 put 操作的所有 RowKey 都是递增的,那么试想,当插入一部分数据的时候刚好进行分
			裂,那么之后的所有数据都开始往分裂后的第二个 Region 插入,就造成了数据热点现象。
			HBase  的更新/ 修改 其实是不断追加的操作。
				
				Client 写入 -> 存入 MemStore,一直到 MemStore 满 -> Flush 成一个 StoreFile,直至增长到
			一定阈值 -> 触发 Compact 合并操作 -> 多个 StoreFile 合并成一个 StoreFile,同时进行版本
			合并和数据删除 -> 当StoreFiles Compact后,逐步形成越来越大的StoreFile -> 单个StoreFile
			大小超过一定阈值后,触发 Split 操作,把当前 Region Split 成 2 个 Region,Region 会下线,
			新 Split 出的 2 个孩子 Region 会被 HMaster 分配到相应的 HRegionServer 上,使得原先 1 个
			Region 的压力得以分流到 2 个 Region 上
				由此过程可知,HBase  只是增加数据,有所得更新在 和删除操作,都是在 Compact  阶段做的,
			所以,用户写操作只需要进入到内存即可立即返回,从而保证 I/O  高性能 。
				
				写入数据的过程补充:
				工作机制:每个 HRegionServer 中都会有一个 HLog 对象,HLog 是一个实现 Write Ahead Log
			的类,每次用户操作写入 Memstore 的同时,也会写一份数据到 HLog 文件,HLog 文件定期
			会滚动出新,并删除旧的文件(已持久化到 StoreFile 中的数据)。当 HRegionServer 意外终止
			后,HMaster 会通过 ZooKeeper 感知,HMaster 首先处理遗留的 HLog 文件,将不同 Region
			的log数据拆分,分别放到相应Region目录下,然后再将失效的Region (带有刚刚拆分的log)
			重新分配,领取到这些 Region 的 HRegionServer 在 load Region 的过程中,会发现有历史 HLog
			需要处理,因此会 Replay HLog 中的数据到 MemStore 中,然后 flush 到 StoreFiles,完成数据
			恢复。
	
	18.RegionServer 工作机制:
		
		1)Region分配
			
			任何时刻,一个 Region 只能分配给一个 RegionServer。master 记录了当前有哪些可用的
		RegionServer。以及当前哪些 Region 分配给了哪些 RegionServer,哪些 Region 还没有分配。
		当需要分配的新的 Region,并且有一个 RegionServer 上有可用空间时,Master 就给这个
		RegionServer 发送一个装载请求,把 Region 分配给这个 RegionServer。RegionServer 得到请
		求后,就开始对此 Region 提供服务。
		
		2)RegionServer上线
			
			Master 使用 zookeeper 来跟踪 RegionServer 状态。当某个 RegionServer 启动时,会首先在
		ZooKeeper 上的 server 目录下建立代表自己的 znode。由于 Master 订阅了 server 目录上的变
		更消息,当 server 目录下的文件出现新增或删除操作时,Master 可以得到来自 ZooKeeper
		的实时通知。因此一旦 RegionServer 上线,Master 能马上得到消息。
		
		3)RegionServer  下线
			
			当 RegionServer 下线时,它和 zookeeper 的会话断开,ZooKeeper 而自动释放代表这台 server
		的文件上的独占锁。Master 就可以确定:
			1、RegionServer 和 ZooKeeper 之间的网络断开了。
			2、RegionServer 挂了。
		无论哪种情况,RegionServer都无法继续为它的Region提供服务了,此时Master会删除server
		目录下代表这台 RegionServer 的 znode 数据,并将这台 RegionServer 的 Region 分配给其它还
		活着的同志。
	
	19.Master工作机制	
		
		1)Master 上线
			
			Master 启动进行以下步骤:
			1、从ZooKeeper上获取唯一一个代表Active Master的锁,用来阻止其它Master成为Master。
			2、扫描 ZooKeeper 上的 server 父节点,获得当前可用的 RegionServer 列表。
			3、和每个 RegionServer 通信,获得当前已分配的 Region 和 RegionServer 的对应关系。
			4、扫描.META. Region 的集合,计算得到当前还未分配的 Region,将他们放入待分配 Region列表。
		
		2)Master 下线
			
			由于 Master 只维护表和 Region 的元数据,而不参与表数据 IO 的过程,Master 下线仅
		导致所有元数据的修改被冻结(无法创建删除表,无法修改表的 schema,无法进行 Region
		的负载均衡,无法处理 Region 上下线,无法进行 Region 的合并,唯一例外的是 Region 的 split
		可以正常进行,因为只有 RegionServer 参与),表的数据读写还可以正常进行。因此 Master
		下线短时间内对整个 hbase 集群没有影响。
			从上线过程可以看到,Master 保存的信息全是可以冗余信息(都可以从系统其它地方收集到或者计算出来)
			因此,一般 HBase 集群中总是有一个 Master 在提供服务,还有一个以上的 Master 在等
		待时机抢占它的位置。
	
	20.Hbase高级:
		
		1)rowkey设计
			
			追求的原则是:在合理范围内能尽量少的减少列簇就尽量减少列簇。
			最优设计是:将所有相关性很强的 key-value 都放在同一个列簇下,这样既能做到查询效率
		最高,也能保持尽可能少的访问不同的磁盘文件
			三原则:
				 rowkey 长度原则:Rowkey 是一个二进制码流,Rowkey 的长度被很多开发者建议说设计在 10~100 个字节,不
								过建议是越短越好,不要超过 16 个字节,最好是8的倍数。
				 rowkey 散列规则:如果 Rowkey 是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将 Rowkey
								的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个
								Regionserver 实现负载均衡的几率。
				 rowkey 唯一原则:将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。
		
		2)列簇设计
			
			HBase 中,表会被划分为 1...n 个 Region,被托管在 RegionServer 中。Region 二个重要的
		属性:StartKey 与 EndKey 表示这个 Region 维护的 rowKey 范围,当我们要读/写数据时,如
		果 rowKey 落在某个 start-end key 范围内,那么就会定位到目标 region 并且读/写到相关的数据
			理论上相同IO特性,经验上越少越好,3个	
		
		3)防止数据热点的有效措施:
			
			加盐:在 rowkey 的前面增加随机数,具体就是给rowkey 分配一个随机前缀以使得它和之前的 rowkey 的开头不同。
			哈希:使用确定的哈希可以让客户端重构完整的 rowkey,可以使用 get 操作准确获取某一个行数据
			反转:反转固定长度或者数字格式的 rowkey
			时间戳反转:使用反转的时间戳作为 rowkey的一部分

(十一)Sqoop

	1.概述:
	
		sqoop 是 apache 旗下一款“Hadoop 和关系数据库服务器之间传送数据”的工具
		导入数据:MySQL,Oracle导入数据到Hadoop的HDFS、HIVE、HBASE等数据存储系统
		导出数据:从 Hadoop 的文件系统中导出数据到关系数据库 mysql 等
	
	2.工作机制:
	
		将导入或导出命令翻译成 MapReduce 程序来实现 
		在翻译出的 MapReduce 中主要是对 InputFormat 和 OutputFormat 进行定制
	
	3.Sqoop导出原理:
	
		1) 第一步,sqoop 依然会通过 JDBC 访问关系型数据库,得到需要导出数据的元
			数据信息
		2) 第二步,根据获取到的元数据的信息,sqoop 生成一个 Java 类,用来进行数据
			的传输载体。该类必须实现序列化和反序列化
		3) 第三步,启动 mapreduce 作业
		4) 第四步,sqoop 利用生成的这个 java 类,并行的从 hdfs 中读取数据
		5) 第五步,每个 map 作业都会根据读取到的导出表的元数据信息和读取到的数据,
			生成一批insert语句,然后多个 map 作业会并行的向数据库mysql中插入数据 

(十二)Azkaban

	1.概述:
	
		1) 为什么需要工作流调度器:
			1、一个完整的数据分析系统通常都是由大量任务单元组成:
				shell 脚本程序,java 程序,mapreduce 程序、hive 脚本等
			2、各任务单元之间存在时间先后及前后依赖关系
			3、为了很好地组织起这样的复杂执行计划,需要一个工作流调度系统来调度执行
		2) 处理步骤:
			1、 通过 Hadoop 先将原始数据同步到 HDFS 上;
			2、 借助 MapReduce 计算框架对原始数据进行清洗转换,生成的数据以分区表
				的形式存储到多张 Hive 表中;
			3、 需要对Hive中多个表的数据进行 JOIN 处理,得到一个明细数据Hive大表;
			4、 将明细数据进行各种统计分析,得到结果报表信息;
			5、 需要将统计分析得到的结果数据同步到业务系统中,供业务调用使用。
		3) 介绍:
				Azkaban 是由 Linkedin 开源的一个批量工作流任务调度器。用于在一个工
			作流内以一个特定的顺序运行一组工作和流程。
				Azkaban 定义了一种 KV 文件(properties)格式来建立任务之间的依赖关
			系,并提供一个易于使用的 web 用户界面维护和跟踪你的工作流。
	
	2.Azkaban 与 Oozie 对比:
	
		1) Oozie:ooize相比 azkaban 是一个重量级的任务调度系统,功能全面,但配置使用也更复杂
		   Azkaban:轻量级调度器
		2) 功能:
			两者均可以调度 mapreduce,pig,java,脚本工作流任务
			两者均可以定时执行工作流任务
		3) 工作流定义:
			Azkaban 使用 Properties 文件定义工作流
			Oozie 使用 XML 文件定义工作流
		4) 工作流传参:
			Azkaban 支持直接传参,例如${input}
			Oozie 支持参数和 EL 表达式,例如${fs:dirSize(myInputDir)} strust2(ONGL)
		5) 定时执行:
			Azkaban 的定时执行任务是基于时间的
			Oozie 的定时执行任务基于时间和输入数据
		6) 资源管理
			Azkaban 有较严格的权限控制,如用户对工作流进行读/写/执行等操作
			Oozie 暂无严格的权限控制
		7) 工作流执行
			  Azkaban 有两种运行模式,分别是 solo server mode(executor server
		   和 web server 部署在同一台节点)和 multi server mode(executor server
		   和 web server 可以部署在不同节点)
			  Oozie 作为工作流服务器运行,支持多用户和多工作流
		8) 工作流管理
			  Azkaban 支持浏览器以及 ajax 方式操作工作流
			  Oozie 支持命令行、HTTP REST、Java API、浏览器操作工作流

(十三)Flume

    1.数据采集工具/系统产生背景:
    
        1) Hadoop 业务的整体开发流程:
	        Flume数据采集---》MapReduce清洗---》存入Hbase---》Hive统计、分析
	        ---》存入Hive表---》Sqoop导出---》Mysql数据库---》Web展示
	    2) 大数据平台基本处理过程:
		    数据采集,数据ETL,数据存储,数据计算、分析,数据展现
		3) 数据采集的挑战:
			数据源多种多样
			数据量大,变化快
			如何保证数据采集的可靠性的性能
			如何避免重复数据
			如何保证数据的质量
			
	2.概念:
		
		Flume 是一个分布式、可靠、高可用的海量日志聚合系统,支持在系统中
	定制各类数据发送方,用于收集数据,同时,Flume 提供对数据的简单处理,并写
	到各种数据接收方的能力。
		Flume 使用 JRuby 来构建,所以依赖 Java 运行环境。Flume 最初是
	由 Cloudera 的工程师设计用于合并日志数据的系统,后来逐渐发展用于处理
	流数据事件。
		1) Apache Flume 是一个分布式、可靠、和高可用的海量日志采集、聚
	合和传输的系统,和Sqoop 同属于数据采集系统组件,但是 Sqoop 用来采集关
	系型数据库数据,而 Flume 用来采集流动型数据。
		2) Flume 名字来源于原始的近乎实时的日志数据采集工具,现在被广泛
	用于任何流事件数据的采集,它支持从很多数据源聚合数据到 HDFS。
		3) 一般的采集需求,通过对 flume 的简单配置即可实现。Flume 针对
	特殊场景也具备良好的自定义扩展能力,因此,flume 可以适用于大部分的日常
	数据采集场景
		4) Flume 最初由 Cloudera 开发,在 2011 年贡献给了 Apache 基金
	会,2012 年变成了 Apache的顶级项目。Flume OG(Original Generation)是
	Flume 最初版本,后升级换代成 FlumeNG(Next/New Generation)
		5) Flume 的优势:可横向扩展、延展性、可靠性
			
	3.体系结构/核心组件:
		
		1) 概述:
		
			Flume的数据流有事件(event)贯穿始终。事件是Flume的基本数据
		单位,它携带日志数据(字节数组形式)并且携带有头信息,这些Event
		由Agent外部的Source生成,当Source捕获事件后会进行特定的格式化
		,然后Source会把事件推入(单个或多个)Channel中。你可以把Channel
		看作是一个缓冲区,它将保存事件直到sink处理完该事件。Sink负责持久
		化日志或者把事件推向另一个Source。
			Flumn以agent为最小的独立运行单位。一个agent就是一个JVM。单
		agent由Source、Sink和Channel三大事件构成
		
		2) 三大核心组件:
		
			1、Agent:
			
				使用JVM运行Flume。每台机器运行一个agent,但是可以在一个agent
			中包含多个sources和sinks。
				一个Agent包含source,channel,sink和其他组件。
				它利用这些组件将events从一个节点传输到另一个节点或最终目的地
				agent是flume流的基础部分。
				flume为这些组件提供了配置,声明周期管理,监控支持
				
				Agent之Source:
				
				从Client收集数据,传递给Channel。
				Source负责接收event或通过特殊机制产生event,并将events
			批量的放到一个或多个

				Agent之Sink:
				
					从Channel收集数据,运行在一个独立线程。
					Sink负责将event传输到下一个或最终目的地,成功后将event
				从channel移除
					不同类型的sink:
					存储event到最终目的地终端sink,比如HDFS,HBase
					自动消耗的sink比如null sink
					用于agent间通信的IPC:sink:Avro
					必须作用于一个确切的channel
					
				Agent之channel:
				
					连接sources和sinks,这个有点像一个队列。
					包含event驱动和轮询两种类型
					不同类型的Source:
						与系统集成的Source:Syslog,Netcat,检测目录池
						自动生成事件的Source:Exec
					用于Agent和Agent之间通信的IPC source:avro,thift
					source必须至少和一个channel关联
					Channel位于Source和Sink之间,用于缓存进来的event
					当sink成功的将event发送到下一个的channel或最终目的后
				将event从channel删除
					不同的channel提供的持久化水平也是一样的:
						Memory channel:volatile(不稳定的)
						File Channel:基于WAL(预写式日志)实现
						JDBC channel:基于嵌入式database实现
					channel支持事务,提供较弱的顺序保证
					可以和任意数量的source和sink工作
			
			2、Client:
			
				生产数据,运行在一个独立的线程。
				Client是一个将原始log包装成events并且发送他们到一个或多个
			agent的实体,目的是从原数据源系统中解耦Flume,在flume的拓扑结
			构中不是必须的。
			
			3、Event:
			
				Events:可以是日志记录、avro对象等
				Event是Flume数据传输的基本单元。
				Flume以事件的形式将数据从源头传送到最终的目的。
				Event由可选的header和载有数据的一个byte array构成。载有的
			数据度flume是不透明的。
				header是容纳了key-value字符串对的无序集合,key在集合内是
			唯一的。
				header可以在上下文路由中使用扩展。
				
			4、Iterator:
			
				作用于Source,按照预设的顺序在必要地方装饰和过滤events
				
			5、Channel Selector:
			
				允许Source基于预设的标准,从所有channel中,选择一个或者
			多个channel
			
			6.Sink Processor:
			
				多个sink可以构成一个sink group
				sink processor可以通过组中所有sink实现负载均衡
				也可以在一个sink失败时转移到另一个
				
	4.经典部署方案:
		
		单Agent采集数据
		多Agent串联
		多Agent合并串联
		多路复用

(十四)Redis

```text
1. 概念:

	REmote DIctionary Server(Redis)是一个由 Salvatore Sanfilippo 
写的开源的、高性能的、使用ANSI C 语言编写、遵守 BSD 协议、支持网络、可
基于内存亦可持久化的日志型、key-value存储系统,并提供多种语言的 API。
和 memcached 类似,Redis 常被称作是一款 key-value 内存存储系统或者内
存数据库,同时由于它支持丰富的数据结构,又被称为一种数据结构服务器
(Data Structure Server)。因为值(value)可以是字符串(String),哈希
(Map),列表(list),集合(sets)和有序集合(sorted sets)等类型。

2. 特点:

	1)Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的
时候可以再次加载进行使用。
	2)Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,
set,zset,hash 等数据结构的存储。
	3)Redis 支持数据的备份,即 master-slave 模式的数据备份

3. 优势:
	
	1)性能极高:Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。
	2)丰富的数据类型:Redis 支持二进制案例的 String, List, Hash, Set 
及 Sorted Set 数据类型操作。
	3)原子操作:Redis 的所有操作都是原子性的,同时 Redis 还支持对几个
操作全并后的原子性执行。
	4)丰富的特性:Redis 还支持 Publish/Subscribe,通知 key 过期,支持
高可用集群等等特性。
	5)数据持久化机制
		持久化机制有两种:
		1、RDB 方式:定期将内存数据 dump 到磁盘
		2、AOF(append only file)持久化机制:用记日志的方式记录每一条
			数据更新操作,一旦出现灾难事件,可以通过日志重放来恢复整个
			数据库

4. 适用场景:		
	
	1)TopN 需求:取最新的 n 个数据,如读取作家博客最新的 50 篇文章,通
过 List 实现按时间排序的数据的高效获取
	2)排行榜应用:以特定条件为排序标准,将其设成 sorted set 的 score,
进而实现高效获取
	3)需要精准设定过期时间的应用:把 sorted set 的 score 值设置成过期
时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了
	4)计数器应用:Redis 的命令都是原子性的,可以轻松地利用 INCR,DECR
命令来构建计数器系统。
	5)去除大量数据中的重复数据:将数据放入 set 中,就能实现对重复数据的排除
	6)构建队列系统:使用 list 可以构建队列系统,使用 sorted set 甚至可
以构建有优先级的队列系统。
	7)实时系统,反垃圾系统:通过上面说到的 set 功能,你可以知道一个终端
用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。
	8)Publish/SubScribe 构建实时消息系统
	9)缓存(会话,商品列表,评论列表,经常查询的数据等)				

5. 高可用概述

	在 Redis 中,实现高可用的技术主要包括持久化、复制、哨兵和集群
	1)持久化:
		持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要
	作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失
	2)主从复制:
		复制是高可用 Redis 的基础,哨兵和集群都是在复制基础上实现高可用
	的。复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。
		缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
	3)哨兵:
		哨兵在复制的基础上,哨兵实现了自动化的故障恢复。
		缺陷:写操作无法负载均衡;存储能力受到单机的限制。
	4)集群:
		通过集群,Redis 解决了写操作无法负载均衡,以及存储能力受到单机
	限制的问题,实现了较为完善的高可用方案。

6. 持久化

	1)持久化的功能:
	
		Redis 是内存数据库,数据都是存储在内存中,为了避免进程退出导致
	数据的永久丢失,需要定期将 Redis 中的数据以某种形式(数据或命令)从内
	存保存到硬盘;当下次 Redis 重启时,利用持久化文件实现数据恢复。除此
	之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。
	
	2)持久化的分类:
	
		1、RDB 持久化:
		
			将当前进程中的数据生成快照保存到硬盘(因此也称作
		快照持久化),保存的文件后缀是 rdb;当 Redis 重新启动时,
		可以读取快照文件恢复数据。
			有两个触发条件:
			手动方式:save 命令和 bgsave 命令都可以生成 RDB 文件。
			save 命令:
			会阻塞 Redis 服务器进程,直到 RDB 文件创建完毕为止,在 
		Redis 服务器阻塞期间,服务器不能处理任何命令请求。					
			整个过程都会阻塞服务器
			bgsave 命令:
		    会创建一个子进程,由子进程来负责创建 RDB 文件,父进程(即 
		Redis 主进程)则继续处理请求。
			只有 fork 子进程时会阻塞服务器
			自动触发:save m n
			默认配置文件:
			save 900 1 #900 秒内如果超过 1 个 key 被修改,则发起快照保存
			save 300 10 #300 秒内容如超过 10 个 key 被修改,则发起快照保存
			save 60 10000 #60 秒内容如超过 10000 个 key 被修改,则发起快照保存
		
		2、AOF 持久化:
		
			将每次执行的写命令保存到硬盘(类似于 MySQL 的 binlog)
			在使用 AOF 持久化方式时,Redis 会将每一个收到的写命令都
		通过write 函数追加到文件中(默认是 appendonly.aof)。当
		Redis 重启时会通过重新执行文件中保存的写命令来在内存中重建
		整个数据库的内容。
		appendonly yes #启用 aof 持久化方式
		# appendfsync always #每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
		appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
		# appendfsync no #完全依赖 os,性能最好,持久化没保证
	
7. 主从复制
	
	1)特点:
	
		1、master 可以有多个 slave
		2、除了多个 slave 连到相同的 master 外,slave 也可以连接其他 slave 形成图状结构
		3、主从复制不会阻塞 master。也就是说当一个或多个 slave 与 master 进行初次同步数据时,
		master 可以继续处理 client 发来的请求。相反 slave 在初次同步数据时则会阻塞不能处理
		client 的请求。
		4、主从复制可以用来提高系统的可伸缩性,我们可以用多个 slave 专门用于 client 的读请求,
		比如 sort 操作可以使用 slave 来处理。也可以用来做简单的数据冗余
		5、可以在 master 禁用数据持久化,只需要注释掉 master 配置文件中的所有 save 配置,然
		后只在 slave 上配置数据持久化。
		
	2)过程:

		当设置好 slave 服务器后,slave 会建立和 master 的连接,然后发送 sync 命令。无论是第一
	次同步建立的连接还是连接断开后的重新连接,master 都会启动(fork)一个后台进程,将数
	据库快照保存到文件中(fork 一个进程入内在也被复制了,即内存会是原来的两倍),同时
	master 主进程会开始收集新的写命令并缓存起来。后台进程完成写文件后,master 就发送
	文件给 slave,slave 将文件保存到磁盘上,然后加载到内存恢复数据库快照到 slave 上。接
	着 master 就会把缓存的命令转发给 slave。而且后续 master 收到的写命令都会通过开始建立
	的连接发送给 slave。从 master 到 slave 的同步数据的命令和从 client 发送的命令使用相同的
	协议格式。当 master 和 slave 的连接断开时 slave 可以自动重新建立连接。如果 master 同时
	收到多个 slave 发来的同步连接命令,只会使用启动一个进程来写数据库镜像,然后发送给所有 slave。

		配置 slave 服务器只需要在配置文件中加入如下配置:
		slaveof centos02 6379 #指定 master 的 ip 和端口
		注意:主节点不用加!!!

8. redis和memcached的区别
	
	1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;
	2、Redis不仅仅支持简单的k/胜利类型的数据,同时还提供list,set,hash等数据结构的存储;
	3、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;			
	4、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;			
	5、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;			
	6、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);			
	7、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;		
	8、Redis支持数据的备份,即master-slave模式的数据备份;		
	9、应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。

作者:成神之路
来源:CSDN
原文:https://blog.csdn.net/weixin_42882274/article/details/81545871
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值