2019-02-21 12:14:18 OOFFrankDura 阅读数 1676
  • hadoop全分布式集群配置

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性 的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序 的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。本课程讲解搭建hadoop集群的全过程,从安装vmware,centos开始,从本地模式,伪分布式到全分布式,讲解实现经典案例wordcount结束,全方位讲解hadoop的操作细节,带你完成hadoop的安装和入门

    1244 人正在学习 去看看 冯文凯

综述

操作系统的理论学习也算结束了,考试其实对自己并不是很满意。后面继续努力吧。先前基地班学长给了一个复习的资料关于文件打开过程的,感觉很不错

正文

文件打开的过程如下图所示(从右往左看)
在这里插入图片描述
首先,操作系统根据文件名a,在系统文件打开表中查找
第一种情况:
如果文件a已经打开,则在进程文件打开表中为文件a分配一个表项,然后将该表项的指针指向系统文件打开表中和文件a对应的一项;
然后再PCB中为文件分配一个文件描述符fd,作为进程文件打开表项的指针,文件打开完成。
第二种情况:
如果文件a没有打开,查看含有文件a信息的目录项是否在内存中,如果不在,将目录表装入到内存中,作为cache;
根据目录表中文件a对应项找到FCB在磁盘中的位置;
将文件a的FCB装入到内存中的Active inode中;
然后在系统文件打开表中为文件a增加新的一个表项,将表项的指针指向Active Inode中文件a的FCB;
然后在进程的文件打开表中分配新的一项,将该表项的指针指向系统文件打开表中文件a对应的表项;
然后在PCB中,为文件a分配一个文件描述符fd,作为进程文件打开表项的指针,文件打开完成。
为了保证进程有独立的内存空间:基地址寄存器、界限地址寄存器

2015-07-19 16:39:19 giantpoplar 阅读数 5988
  • hadoop全分布式集群配置

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性 的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序 的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。本课程讲解搭建hadoop集群的全过程,从安装vmware,centos开始,从本地模式,伪分布式到全分布式,讲解实现经典案例wordcount结束,全方位讲解hadoop的操作细节,带你完成hadoop的安装和入门

    1244 人正在学习 去看看 冯文凯

fd=fopen()是一个系统调用,用于根据文件名打开一个文件,返回该文件的文件描述符,文件打开后进程便可以根据文件描述符fd进行其他操作,比如读,写,关闭等操作。

各个操作系统打开文件的过程是类似的,本文以Unix为例,介绍打开一个文件操作系统所做的工作,正式介绍这个过程之前先简要介绍几个概念。

PCB(process control block)进程控制块,它是一个内核数据结构,相当于一个档案,是操作系统感知进程存在的唯一标识。包括进程状态,进程id,PC,寄存器,内存信息,文件打开信息等,如下图所示


FCB(file control block)文件控制块,是文件系统的一部分,在磁盘上一般会创建一个文件系统,文件系统中包含目录信息,以及文件的FCB信息。FCB一半包含文件的读写模式,所有者,时间戳,数据块指针等信息,unix的FCB称为inode,其结构如下图所示

本图片来自http://codex.cs.yale.edu/avi/os-book/OS9/slide-dir/os-figures.zip


文件打开的过程如下图所示(从右往左看)



首先,操作系统根据文件名a,在系统文件打开表中查找

第一种情况:

如果文件a已经打开,则在进程文件打开表中为文件a分配一个表项,然后将该表项的指针指向系统文件打开表中和文件a对应的一项;

然后再PCB中为文件分配一个文件描述符fd,作为进程文件打开表项的指针,文件打开完成。

第二种情况:

如果文件a没有打开,查看含有文件a信息的目录项是否在内存中,如果不在,将目录表装入到内存中,作为cache;

根据目录表中文件a对应项找到FCB在磁盘中的位置;

将文件a的FCB装入到内存中的Active inode中;

然后在系统文件打开表中为文件a增加新的一个表项,将表项的指针指向Active Inode中文件a的FCB;

然后在进程的文件打开表中分配新的一项,将该表项的指针指向系统文件打开表中文件a对应的表项;

然后在PCB中,为文件a分配一个文件描述符fd,作为进程文件打开表项的指针,文件打开完成。

2016-12-27 18:06:23 ZDF19 阅读数 456
  • hadoop全分布式集群配置

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性 的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序 的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。本课程讲解搭建hadoop集群的全过程,从安装vmware,centos开始,从本地模式,伪分布式到全分布式,讲解实现经典案例wordcount结束,全方位讲解hadoop的操作细节,带你完成hadoop的安装和入门

    1244 人正在学习 去看看 冯文凯

5.2打开文件

  在操作系统中就是确定进程操作哪个文件。这个确定过程由两个事件构成:

  1.将用户进程task_struct中的*filp[20]与内核中的file_table[64]进行挂接。

  2.将用户进程需要打开的文件对应的i节点在file_table[64]中进行登记。

  *filp[20]:掌控一个进程可以打开的文件,既可以打开多个不同的文件,也可以同一个文件多次打开,每打开一次文件(不论是否是同一个),就要在*filp[20]中占用一个项记录指针。一个进程可以同时打开的文件次数不能超过20次。

  file_table[64]是管理所有进程打开文件的数据结构,不但记录了不同的进程打开不同的文件,也记录了不同的进程打开同一个文件,还记录了同一个进程多次打开同一个文件。与*filp[20]类似,只要打开一次文件,就要在file_able[64]中记录.(所以一个进程最多打开20次文件,但所有进程打开文件的总和不能超过64?)

  文件的i节点:是记载文件属性的最关键的数据结构。在操作系统中i节点和文件是一一对应的,找到i节点就能唯一确定文件。

  inode_table[32]:内核通过inode_table[32]掌控正在使用的文件i节点数,每个被使用的文件i节点都要记录在其中。

  打开文件的本质就是要建立*filp[20],file_table[64],inode_table[32]三者之间的关系。

  建立关系的这个过程分为三个步骤:

   1.将用户进程task_struct中的*filp[20]与内核中的file_table进行挂接。

   2.以用户给定的路径名“/mnt/user/user1/user2/hello.txt”为线索,找到hello.txt文件的i节点。

   3.将hello.txt对应的i节点在file_table[64]中进行登记。

  具体的操作是在进程中调用open()函数实现打开文件,该函数最终映射到sys_open()系统调用函数执行。映射过程以及sys_open()函数的基本执行情况已经在4.4.1节。

 5.2.1将进程的*filp[20]与file_table[64]挂接

 5.2.2获取文件i节点

 5.2.3将文件i节点与file_table[64]挂接

5.3读文件

  读文件就是从用户进程打开的文件中读取数据,读文件由read函数完成。

 5.3.1确定数据块在外设中的位置

 5.3.2将数据块读入缓冲块

 5.3.3将缓冲块中的数据复制到进程空间

5.4新建文件

  新建文件就是根据用户进程要求,创建一个文件系统中不存在的文件。新建文件由creat()函数实现。

 5.4.1 查找文件

 5.4.2 新建文件i节点

  新建hello.txt 文件 i 节点,将会在user2目录文件(作出目录文件的示意图)中写入hello.txt文件对应的新目录项信息。

 5.4.3 新建文件目录项

  只要在user2目录文件中寻找到空闲项,就在此位置加载新目录项,如果缺失找不到空闲项,就在外设上创建新的数据块来加载(此过程示意图类似P234所示)。

5.5 写文件

  操作系统对写文件操作的规定是:进程空间的数据先要写入缓冲区中,然后操作系统在适当条件下,将缓冲区中的数据同步到外设上。而且,操作系统只能以数据块(1 KB)为单位,将缓冲区中的缓冲块(1 KB) 的数据同步到外设上。这就需要在同步之前,缓冲块与外设上要写入的逻辑块进行一对一绑定,确定外设上的写入位置,以此保证用户空间写入缓冲块的数据能够准确地同步到指定逻辑块中。

  首先介绍如何确定绑定关系

 5.5.1 确定文件的写入位置

 5.5.2 申请缓冲块

 5.5.3 将指定的数据从进程空间复制到缓冲块

 5.5.4 数据同步到外设的两种方法

5.6 修改文件

 5.6.1 重定位文件的当前操作指针

 5.6.2 修改文件

5.7 关闭文件

  关闭文件对应的是打开文件,是在close()函数中完成的。

 5.7.1 当前进程的filp与file_table[64]脱钩

 5.7.2 文件i节点被释放

5.8 删除文件

  删除文件对应的是新建文件。删除文件与关闭文件有所不同:关闭文件只是解除当前进程与hello.txt文件在file_table[64]中指定挂接点的关系,而删除操作的效果表现为所有进程都无法访问到hello.txt这个文件。

 5.8.1 对文件的删除条件进行检查

 5.8.2 进行具体的删除工作

5.9 本章小节

  操作系统对文件的一切操作,都可以分为两个方面:对super_block,d_super_block,m_inode,d_inode,i节点位图,逻辑块位图这类文件管理信息的操作以及对文件数据内容的操作。新建,打开,关闭,删除文件属于对文件管理信息的操作。读文件,写文件和修改文件则主要是操作文件数据内容。

  操作系统管理信息就是建立或解除进程与文件的关系链条,链条的主干为task_struct中的*filp[20]——file_table[64]——inode_table[32].进程就可以沿着关系链条,依托缓冲区与硬盘进行数据交互。当关系链条解除后,进程则不再具备操作指定文件的能力。如果文件管理被更改,则操作系统要将此更改落实在硬盘上,以免失去对文件数据内容的控制。












2018-08-05 17:45:37 qq_38410730 阅读数 8086
  • hadoop全分布式集群配置

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性 的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序 的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。本课程讲解搭建hadoop集群的全过程,从安装vmware,centos开始,从本地模式,伪分布式到全分布式,讲解实现经典案例wordcount结束,全方位讲解hadoop的操作细节,带你完成hadoop的安装和入门

    1244 人正在学习 去看看 冯文凯

在虚拟文件系统的支持下,Linux可以支持迄今为止的大多数文件系统。但是,Linux并不是在初始化时就把所有文件系统全部都装入,而只是安装一个文件系统(通常是Ext2)作为根文件系统。根文件系统在整个系统运行过程中是不能被拆卸的,是系统的基本组成部分。通常,根文件系统上主要安装了保证系统正常工作运行的操作系统代码文件以及若干语言编译程序、命令解释程序和相应的命令处理程序等文件。其他文件系统则都定义成可安装模块,以便用户需要时动态地进行安装。

所谓安装,就是在虚拟文件系统中建立一个超级块super_block,并用被安装文件系统超级块中的相关信息填写super_block,然后用被安装文件系统的根目录代替系统现有目录结构的一个空目录,从而把子系统与原文件系统连接起来。

为使系统在安装之前了解待安装文件子系统的基本信息(例如超级块的位置),必须向系统文件注册表提交一个数据结构进行注册。

把一个文件系统安装到根文件系统的一个节点上的示意图如下所示:

 

文件系统的注册

由于不同的文件系统具有不同的特点,因此其安装过程也不尽相同。为了正确地安装一个文件系统,被安装的文件系统在安装之前必须向系统进行注册,以便使系统感知和了解待安装文件系统的类型及安装相关的信息。

系统通过调用文件的初始化例程来填写一个叫做file_system_type的数据结构,并调用函数register_filesystem()把该数据结构加入到由系统维护的已注册文件系统的链表中。如下图所示:

数据结构file_system_type的定义如下:

struct file_system_type {
	const char *name;                //文件系统的名称
	int fs_flags;        
	int (*get_sb) (struct file_system_type *, int,
		       const char *, void *, struct vfsmount *);
	void (*kill_sb) (struct super_block *);
	struct module *owner;
	struct file_system_type * next;            //下一个文件系统的指针
	struct list_head fs_supers;

	struct lock_class_key s_lock_key;
	struct lock_class_key s_umount_key;

	struct lock_class_key i_lock_key;
	struct lock_class_key i_mutex_key;
	struct lock_class_key i_mutex_dir_key;
	struct lock_class_key i_alloc_sem_key;
};

 

文件系统的安装与卸载

当系统试图安装一个子文件系统时,系统会调用函数mount()首先在文件系统注册链表中查找与用户提供名称相匹配的注册文件系统,如果找到,则在该文件系统的file_system_type中获得与文件系统对应的超级块的指针,并用超级块中的相关信息填写系统分配给该系统的VFS超级块,并把这个超级块加入到VFS超级块链表中。

接下来就要填写一个系统分配给该文件系统的vfsmount数据结构,以保存已被安装的文件系统的基本安装信息,从而把该文件系统的根节点安装到选定的VFS索引节点上。vfsmount结构的定义如下:

struct vfsmount {
	struct list_head mnt_hash;
	struct vfsmount *mnt_parent;	/* 本系统所挂接的父文件系统 */
	struct dentry *mnt_mountpoint;	/* 挂接点的dentry结构 */
	struct dentry *mnt_root;	/* 本系统的根目录 */
	struct super_block *mnt_sb;	/* pointer to superblock */
	struct list_head mnt_mounts;	/* list of children, anchored here */
	struct list_head mnt_child;	/* and going through their mnt_child */
	int mnt_flags;
	/* 4 bytes hole on 64bits arches */
	const char *mnt_devname;	/* 设备名称 e.g. /dev/dsk/hda1 */
	struct list_head mnt_list;
	struct list_head mnt_expire;	/* link in fs-specific expiry list */
	struct list_head mnt_share;	/* circular list of shared mounts */
	struct list_head mnt_slave_list;/* list of slave mounts */
	struct list_head mnt_slave;	/* slave list entry */
	struct vfsmount *mnt_master;	/* slave is on master->mnt_slave_list */
	struct mnt_namespace *mnt_ns;	/* containing namespace */
	int mnt_id;			/* mount identifier */
	int mnt_group_id;		/* peer group identifier */
	/*
	 * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
	 * to let these frequently modified fields in a separate cache line
	 * (so that reads of mnt_flags wont ping-pong on SMP machines)
	 */
	atomic_t mnt_count;
	int mnt_expiry_mark;		/* true if marked for expiry */
	int mnt_pinned;
	int mnt_ghosts;
	/*
	 * This value is not stable unless all of the mnt_writers[] spinlocks
	 * are held, and all mnt_writer[]s on this mount have 0 as their ->count
	 */
	atomic_t __mnt_writers;
};

所有已经被安装的系统都有一个对应的vfsmount数据结构,结构中的指针mnt_mountpoint指向挂接点的目录,而指针mut_root指向被安装系统的根目录,所以结构vfsmount是子系统与父系统之间的桥梁。该数据结构一旦被填写,系统便认为该结构所对应的文件系统已经被安装。

所以,已经被安装的系统的vfsmount数据结构,在系统中也是用一个链表来管理的。

拆卸一个文件子系统的过程基本与安装的过程相反。系统首先验证文件子系统是否为可拆卸的:如果该文件子系统的文件正在被使用,则该系统时不可拆卸的;否则,释放该文件子系统所占用的VFS超级块和安装点,从而卸下该文件子系统。

 

2019-10-21 11:37:47 qq_34650584 阅读数 18
  • hadoop全分布式集群配置

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性 的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序 的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。本课程讲解搭建hadoop集群的全过程,从安装vmware,centos开始,从本地模式,伪分布式到全分布式,讲解实现经典案例wordcount结束,全方位讲解hadoop的操作细节,带你完成hadoop的安装和入门

    1244 人正在学习 去看看 冯文凯

硬核详情请查看原文链接,以下是我个人利用书本比喻的理解。

先来看看一本书籍:

假设我们从图书馆中寻找一本“操作系统”的书,我们需要知道的是书名;当我们找到这本书后,我们相当于得到了书本的全部内容,即使我们还没开始阅读。

书本会有目录:

从目录中我们知道:这是一本操作系统的书;以及每部分内容对应的页码。

打开某一页(节选):

我们发现,在具体页中也写着页码,同时存在层级结构:进程的通信方式-同步与互斥与P/V信号量操作-进程互斥。假设我们要查找的内容是“进程互斥”,那么需要经过上述的过程才能找到。


接下来说一下虚拟文件系统,在原文链接中提到的作用是用户空间与内核空间的适配。看看虚拟文件系统图:

与前文说到的书本作比较,

超级块:即super_block,类似于整本书;也可以理解为这本书的“书名”,可以通过“书名”从图书馆找到这本书,同时从书的开头开始阅读到整本书的内容。

目录项:类似于书的目录,可以找到目标内容对应的页码。

inode:类似于页码,通过页码可以找到目标内容是在哪一页,这是查找的关键。

打开文件列表:相当于已经打开的一些页或者折起来的一些页。想想我们看书时,有时也同时翻开多页来看,或者把一些页折起来,方便下次直接查看。

address_space:类似于具体的某一页,但这是一个抽象的概念,可以理解为用于承载页面内容的一个空间,相当于书本页在印刷前的一张白纸,但不是这一页的内容。

页缓存基数树:类似于具体的某一页的内容,相当于前文书本例子的层级结构。

file_operations:是对内容的一些操作,例如读read、写write。

【再说两句】

虚拟文件系统中有很多反向或迂回的箭头,这就像我们打开书本某一页,这一页也有页码,可以反推该页在目录中的位置。通过指针使书本结构更加紧密;在利用页码找到对应页时,可能会出现印刷缺漏的情况,这时候又该怎么办呢?

 

【最后再附上原文链接中读写文件的内容】


读文件

1、进程调用库函数向内核发起读文件请求;

2、内核通过检查进程的文件描述符定位到虚拟文件系统的已打开文件列表表项;

3、调用该文件可用的系统调用函数read()

3、read()函数通过文件表项链接到目录项模块,根据传入的文件路径,在目录项模块中检索,找到该文件的inode;

4、在inode中,通过文件内容偏移量计算出要读取的页;

5、通过inode找到文件对应的address_space;

6、在address_space中访问该文件的页缓存树,查找对应的页缓存结点:

(1)如果页缓存命中,那么直接返回文件内容;

(2)如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页;重新进行第6步查找页缓存;

7、文件内容读取成功。

 

写文件

前5步和读文件一致,在address_space中查询对应页的页缓存是否存在:

6、如果页缓存命中,直接把文件内容修改更新在页缓存的页中。写文件就结束了。这时候文件修改位于页缓存,并没有写回到磁盘文件中去。

7、如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页。此时缓存页命中,进行第6步。

8、一个页缓存中的页如果被修改,那么会被标记成脏页。脏页需要写回到磁盘中的文件块。有两种方式可以把脏页写回磁盘:

(1)手动调用sync()或者fsync()系统调用把脏页写回

(2)pdflush进程会定时把脏页写回到磁盘

同时注意,脏页不能被置换出内存,如果脏页正在被写回,那么会被设置写回标记,这时候该页就被上锁,其他写请求被阻塞直到锁释放。

python12文件操作

阅读数 121

没有更多推荐了,返回首页