虚拟存储(Storage Virtualization)是指将多个不同类型、独立存在的物理存储体,通过软、硬件技术,集成转化为一个逻辑上的虚拟的存储单元,集中管理供用户统一使用。这个虚拟逻辑存储单元的存储容量是它所集中管理的各物理存储体的存储量的总和,而它具有的访问带宽则在一定程度上接近各个物理存储体的访问带宽之和。
虚拟存储器实际上是一种逻辑存储器,实质是对物理存储设备进行逻辑化的处理,并将统一的逻辑视图呈现给用户。因此,用户在使用时,操作的是虚拟设备,无需关心底层的物理环境。因而,可以充分利用基于异构平台的存储空间,达到化的使用效率。
虚拟存储系统一般具有以下功能:
(1)具有存储设备故障确定及自动触发故障设备接替功能。
(2)具有存储协议的自由转换功能,从而能实现对不同协议下的,异构的存储和服务器环境的支持;
(3)支持SAN存储配置,能实现存储体的集中式管理和存储容量扩充。
(4)能通过TCP/IP协议,在网络上实现对存储器的各种远程同步操作;
(5)可实现数据高速缓存、定时自动备份和恢复等。
因此,其在使用时存储效率较高,用户存储硬件开销和管理维护成本可大幅降低,系统安全性得到提升,特别适合具有海量级信息资源的企业级和网络环境下使用。
虚拟存储系统从体系结构上可分为对称式和非对称式两种。
1 对称式结构
对称式虚拟存储的控制交换设备直接存在于服务器和存储设备之间,用运行在虚拟存储控制设备中的管理软件来管理和配置所有的存储设备,组成一个大型的存储池,其中的若干存储设备以一个逻辑分区的形式被系统中所有的服务器访问。其结构如图1所示。
图1 对称式虚拟存储系统结构
对称式结构的优点主要有:
(1)虚拟存储控制设备有多个数据通道与存储设备连接,多个存储设备并发工作,所以系统总的存储设备访问速度可以达到较高的水平;
(2)设备集中,因此系统的安装和管理非常简便;
(3)存储设备对主机是透明的。
缺点主要有:
(1)所有服务器对存储设备的访问都要经过控制交换设备的通道。控制交换设备容易成为整个系统的带宽瓶颈;
(2)数据传输和控制设备在整个系统中是一个单点失效点,它的故障将导致整个系统的瘫痪;
(3)系统扩展性相对较差。
2 非对称式结构
非对称式虚拟存储又称通道外虚拟存储。其结构如图2所示。
图2 非对称式虚拟存储系统
非对称式结构的虚拟存储系统主要通过软件手段实现虚拟存储控制。其虚拟存储控制器独立于数据传输通道之外,数据和控制信息在传输通道上分离。虚拟存储控制器不直接参与数据的传输,运行在其上的虚拟存储控制软件对存储设备进行统一管理和配置并形成逻辑存储单元和存储设备映射表,任何服务器在初始化时,均要通过虚拟存储控制器获得存储设备的映射表并实现对虚拟存储单元的访问。
非对称式结构的优点主要有:
(1)可将不同物理硬盘阵列进行逻辑组合以实现虚拟存储,并可将多个硬盘阵列控制器端口绑定提高系统的可用带宽;
(2)在交换机端口数量足够的情况下,可在一个网络内安装冗余备份的两台虚拟存储设备;
(3)系统配置非常灵活,具有较高的开放性和可扩展性;
(4)系统的安全性较高,虚拟存储控制器位于数据传输通道之外虚拟存储控制器出现故障,不会引起存储系统的数据传输通道阻塞;
(5)由于服务器通过连接设备直接访问存储设备,因此存储虚拟化后不会带来任何延迟;
(6)存储系统对于操作系统和应用系统都是透明的,因此存储系统的管理比较方便。
缺点主要有:
(1)由于虚拟存储控制器保存有存储设备信息映射表,如果虚拟存储控制器发生故障,则新加入设备无法获得映射表,无法访问存储系统;
(2)需要FC光纤通道接口卡来实现与存储设备的数据读写;
(3)由于该结构本质上属于磁盘阵列群结构,一旦磁盘阵列群中的某个磁盘阵列控制器损坏,或者这个阵列到交换机路径失效,都会导致相应的虚拟存储控制器离线并丢失其数据;
(4)可用带宽的提高是通过磁盘阵列端口绑定来实现的,因此,很难实现几百兆以上的可用带宽;
(5)由于不同品牌或型号的磁盘阵列的性能不完全相同,出于虚拟化的目的将不同品牌或型号的阵列进行绑定,会产生以下问题:即数据写入或读出时各并发数据流的速度不同,原来的数据包顺序在传输完毕后被打乱,系统需要占用时间和资源去重新进行数据包排序整理,这会严重影响系统性能。
虚拟存储器是根据程序的逻辑地址转换来的,也称线性地址空间。一般每个进程,甚至每个段都有一个,以32位为例,则每个可达4G。
而主存目前一般为百M。因此程序中所指的存储单元并不能都放到主存中,也就是并不是每个程序所用的存储单元,都有具体的物理的存储器单元与之对应。
但由于程序的两个局部性原理,在一个时刻,程序只在一个比较小的范围内运行。所以我们把程序可能用到的整个存储空间分成一个个相同大小的页(按页管理硬件上容易实现),只把其中的一些页放在主存中,而其它的页则等需要时再建,或放在辅存(磁盘)中。同时建立一个页表,对应于每一页,如果该页在主存中,则页表记录它在主存中的地址;如果不在主存中,则在页表上作不在主存的标记。
这样,当程序需要调用某个存储单元的内容时,先根据它的线性地址,算出其所在的页。查页表,看是不是在主存中?如果在,则直接存取。如果查到页表上是不在的标记,那就是一个page fault。要把主存中的某一页(LRU策略)换到磁盘上,把要访问的那个单元所在的页调入主存,再进行存取。
就象一个预计有一万学生的学校,理论上每个学生都应有一个位子上课(一万个虚拟位子),而学校只有一千个(物理)位子。但实际上,学校也不会一万个人同时上课,只要让上课的同学有位子(在主存中),而其它同学只要留下联系方法能找到就好。为了降低管理的复杂性,我们采用按学号分班(页)管理。每个班要么一起上课(主存),要么一起呆在寝室(磁盘)。而在学校保留一个动态表(页表)表明每个班在哪儿(物理地址)上课,或者没上课(不在主存)。现在假设我们想按学号找一个同学,而且是女同学,只能在教室说话,呵呵。那么:
先算出来是哪个班的,查动态表,看该班是否在教室。在,直接按位置找到(hit);不在(page fault),要先找个不上课的班赶回寝室,把要找女生所在的班调到教室,再按位置找那个同学。
动态表(页表)的大小=表项数*每个表项所需的位数。
表项数=虚拟班数=虚拟人数(虚拟地址空间)/每班人数(每页大小)
每个表项的位数=Log(教室数)+适当控制位数
教室数=实际可以上课的人数(物理地址空间)/每班人数(每页大小)
虚拟地址换算:
TLB miss:
4G(32-bit)的存储空间,如果按4K分页,则可分1M页。每个页表项为4B,则一个页表大小为4MB。由于页表太大,只能放在主存中。这样每次读内存都要读主存,大大影响读写速度。而同样基于局部性原理,整个页表在某一时刻,所用的也仅仅几页而已。所以我们把某段时间经常用的几个页表项,即常用的虚拟页号和其对应的物理页地址,存在Cache中,即TLB。
这样,当程序需要调用某个存储单元的内容时,先根据它的线性地址,算出其所在的页。先查TLB(比较虚拟页号),如果有相同的虚拟页号,则就可以马上知道其所在的物理地址,根据物理地址进行存取。
如果没有相同的虚拟页号,则说明该页没有记录在TLB中,那再去查页表,按page fault中所说的进行。
TLB像我们随身记录电话的小纸片,当要查一个电话时,我们先看小纸片。有,我们可以直接打电话。如果没有,我们再回家查详细的电话号码簿(页表),再打电话。虚拟存储器是根据程序的逻辑地址转换来的,也称线性地址空间。一般每个进程,甚至每个段都有一个,以32位为例,则每个可达4G。
而主存目前一般为百M。因此程序中所指的存储单元并不能都放到主存中,也就是并不是每个程序所用的存储单元,都有具体的物理的存储器单元与之对应。
但由于程序的两个局部性原理,在一个时刻,程序只在一个比较小的范围内运行。所以我们把程序可能用到的整个存储空间分成一个个相同大小的页(按页管理硬件上容易实现),只把其中的一些页放在主存中,而其它的页则等需要时再建,或放在辅存(磁盘)中。同时建立一个页表,对应于每一页,如果该页在主存中,则页表记录它在主存中的地址;如果不在主存中,则在页表上作不在主存的标记。
这样,当程序需要调用某个存储单元的内容时,先根据它的线性地址,算出其所在的页。查页表,看是不是在主存中?如果在,则直接存取。如果查到页表上是不在的标记,那就是一个page fault。要把主存中的某一页(LRU策略)换到磁盘上,把要访问的那个单元所在的页调入主存,再进行存取。
就象一个预计有一万学生的学校,理论上每个学生都应有一个位子上课(一万个虚拟位子),而学校只有一千个(物理)位子。但实际上,学校也不会一万个人同时上课,只要让上课的同学有位子(在主存中),而其它同学只要留下联系方法能找到就好。为了降低管理的复杂性,我们采用按学号分班(页)管理。每个班要么一起上课(主存),要么一起呆在寝室(磁盘)。而在学校保留一个动态表(页表)表明每个班在哪儿(物理地址)上课,或者没上课(不在主存)。现在假设我们想按学号找一个同学,而且是女同学,只能在教室说话,呵呵。那么:
先算出来是哪个班的,查动态表,看该班是否在教室。在,直接按位置找到(hit);不在(page fault),要先找个不上课的班赶回寝室,把要找女生所在的班调到教室,再按位置找那个同学。
动态表(页表)的大小=表项数*每个表项所需的位数。
表项数=虚拟班数=虚拟人数(虚拟地址空间)/每班人数(每页大小)
每个表项的位数=Log(教室数)+适当控制位数
教室数=实际可以上课的人数(物理地址空间)/每班人数(每页大小)
虚拟地址换算:
TLB miss:
4G(32-bit)的存储空间,如果按4K分页,则可分1M页。每个页表项为4B,则一个页表大小为4MB。由于页表太大,只能放在主存中。这样每次读内存都要读主存,大大影响读写速度。而同样基于局部性原理,整个页表在某一时刻,所用的也仅仅几页而已。所以我们把某段时间经常用的几个页表项,即常用的虚拟页号和其对应的物理页地址,存在Cache中,即TLB。
这样,当程序需要调用某个存储单元的内容时,先根据它的线性地址,算出其所在的页。先查TLB(比较虚拟页号),如果有相同的虚拟页号,则就可以马上知道其所在的物理地址,根据物理地址进行存取。
如果没有相同的虚拟页号,则说明该页没有记录在TLB中,那再去查页表,按page fault中所说的进行。
TLB像我们随身记录电话的小纸片,当要查一个电话时,我们先看小纸片。有,我们可以直接打电话。如果没有,我们再回家查详细的电话号码簿(页表),再打电话。