20180423-hdfs

### 1.[volatile和synchronized的区别与联系](#1)
### 2.[hdfs](#2)
### 3.[yarn](#3)
### 4.[乐观锁和悲观锁](#4)





<span id="1" style="font-size: 20px;">


```
1. volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,
只有当前线程可以访问该变量,其他线程被阻塞住;
2. volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的;
3. volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性;
4. volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞;
5. volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。


红字体部分的原因如下:
线程A修改了变量还没结束时,另外的线程B可以看到已修改的值,
而且可以修改这个变量,而不用等待A释放锁,因为Volatile 变量没上锁
```


<span />






<span id="2" style="font-size: 20px;">


```
优点
- 能够处理超大的文件,GB,TB级别的文件
- 流式的访问数据,最小化了磁盘的寻址开销,只需要寻址一次,然后就一直读下去。更多的响应在一次写入,多次读取的任务的基础之上,对于分析任务的    请求比较合适,因为分析任务一般都会涉及比较集中的一堆数据,所以对hdfs来说,读    取整个数据集要比读取一个记录要高效。
- 运行于廉价的商用集群上,因此对可靠性,高可用性,以及安全性的要求比较高。


缺点:
    不适合低延时访问,因为他为了达到比较高的数据吞吐量而放弃了响应的需求。
    不适合存储大量小文件,hadoop用namenode来管理文件系统的元数据,来响应客户请求返回文件位置。hdfs一个文件的地址等相关信息占用大约100字节,小文件多了会导致namenode的内存不够用。


hdfs架构
    hdfs是采用master/slave架构对文件系统进行管理,master中运行了namenode节点,slave中运行了datanode节点。
    namenode负责管理文件的namespace,维护整个文件系统的目录树,以及这些文件的索引目录。这些信息以两种形式存储在本地文件系统中,一种是(namenode image)叫做fsimage,一种是(编辑日志)editlog。从namenode可以获得每个块所在的datanode。
    datanode负责管理存储文件块,被客户端和namenode调用,通过heartbeat定时向namenode发送所在存储块的信息。


读过程:
    客户端通过rpc协议向namenode发送请求,确定文件块的所在位置,namenode不是返回文件所有块的位置,只是返回所调用文件开始的几个块而不是全部,每一块都包含了所在datanode的地址,客户端就会开启一个inputstream进程,去读取离机器最近的datanode去读取文件。


hdfs系统的可靠性
    1.每一种文件会存储3份在磁盘上。
    2.datanode有一个directoryscan操作,会每隔一段时间进行内存和磁盘数据集块的校验,更新内存中的信息和磁盘不一致的情况。
    还有一个intervalmsec,定时向namenode汇报自己的块信息。
    当一个block丢失之后,我们通过directoryscan去排查出block有问题,他首先会删除自己内存里面的映射,他会向namdenode发出一个请求,然后namenode会将告诉他说你可以去某个节点去复制之前的块信息
    
hdfs系统的可用性
   1. hadoop2.0 中,有两个namenode,一个namenode是active状态,一个namenode节点standby状态。为了保持这两个节点的数据的一致性,他们通过一个叫做journalnode的进程来进行交互。当我们在active namenode执行一些修改操作的时候,journal node进程会记录并修改log,standby name node会检测到journalnode里面的同步log,发生了变化就会读取journallog,然 后同步到自己的镜像目录中。
  2.  zkfc机制-(协调和故障恢复服务的角色)
     他是namenode的一个守护进程,主要做了下面几个方面的事情
        1.健康管理:周期性的向namenode发送heartbeat信息,确认namenode是否处于健康状态,如果机器宕机了,heartbeat命令失败,zkfc就会标记它为不健康的状态。
        2.会话管理:健康的namenode会向zookeeper注册一个Znode节点,来保持一个会话过程,进行通信。同时获得一把锁,当这个Name node挂掉了时候,这个znode会话就会被删除,然后会用standby的Name node,standby的时候获得锁。并且将standby的namenode标记为active。
        3. 当宕机的namenode重新启动时,它会再次注册zookeeper,发现已经有一把znode锁了,那他自己就变成standby状态。
```


<span />


<span id="3" style="font-size: 20px;">


```
Yarn的设计思路就是希望将资源管理和作业管理进行分离。所以他分成了resourcemanager以及nodemanager两个组件。
这里面出现了很多名词:
1.ResourceManager会对所有的资源进行统一的调度分配,是一个资源的协调者
 ResourceManager手下有两个主要的组件:
    Scheduler:会根据现有的资源状况,负责分配满足application所需要的资源给application,并不负责监视/跟踪application的状态,当然也不会处理失败的task
    applicationManager:负责接受client提出的任务,协商获取第一个container用于执行任务,并且为失败的applicationmaster重新分配container。
    
2.NodeManager是resourceManager的代理节点,负责container的管理,包括启动container,监控container的使用状况,并报告每台机器上的的资源使用状况给调度器


3.applicationMaster
    1.当提交一个job之后,就会生成一个对应的applicationmaster作为一个守护进程,他主要是与scheduler协商资源,在容器中运行相应的task,并且去监控这些task的执行。如果container出现故障,appmaster会重新申请相应的资源。


而且yarn是基于事件驱动的异步编程模型,他通过事件分发将组件联系起来,由一个中央事件调度器将各种事件分配给对应的处理器。当MRapplicationmaster启动了,这些事件处理器会注册到这个master上,当出现某一事件的时候,applicationmaster会将该事件进行一个分发操作。例如TaskCleaner,清理失败任务。Speculator推测执行功能ContainerLauncher 启动一个container。
    //如果是MapReduce的话,map数目和reduce数目就是container数目
    整个mapreduce的运行流程是这样的
1. Mapreduce jobclient会向resourManager提交一个job
2. ResourceManger下面的ApplicationManager会申请一个container来给applcationmaster运行,然后启动application-master
3. appliacitonMaster启动后会向applicationManager进行一个注册
4.MR JobClient向applicationManager获取到applicationMaster相关的信息,然后直接与applicationMaster进行通信
5.applicationMaster会计算splits为map构成一些资源请求,同时做一些必要的准备工作
6.applicationMaster 发起一个资源请求,得到一组供mapreduce运行的container,然后与namenode一起对每一个container做一些资源的初始化。
7,applicationMaster监视task直到每个任务完成。当task失败的话,就申请新的container去运行失败的task
8.应用运行结束后,ApplicationMaster向ResourceManager注销自己,并允许属于它的container被收回


```


<span />




<span id="3" style="font-size: 20px;">


```
1. 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取
这个字段。
处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。之所以叫乐观,因为这个模式没有从数据库加锁。


2. 悲观锁是读取的时候为后面的更新加锁,之后再来的读操作都会等待。(synchronized的思想也是悲观锁)


    这种是数据库锁
乐观锁优点程序实现,不会存在死锁等问题。他的适用场景也相对乐观。阻止不了除了程序之外的数据库操作。悲观锁是数据库实现,他阻止一切数据库操作。再来说更新数据丢失,所有的读锁都是为了保持数据一致性。乐观锁如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户从新操作。悲观锁则会等待前一个更新完成。这也是区别。具体业务具体分析




1.响应速度:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁
2.冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率,如果冲突频率大,乐观锁会需要多次重试才能成功,代价比较大
3.重试代价:如果重试代价大,建议采用悲观锁




```


<span />

猜你喜欢

转载自blog.csdn.net/z471365897/article/details/80064520
今日推荐