免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5575 | 回复: 1
打印 上一主题 下一主题

HP-UX缓冲区高速缓存(转载) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-05-16 09:40 |只看该作者 |倒序浏览
HP-UX缓冲区高速缓存的配置可能会令您十分困惑,您可能常常将它配置地过低或过高。了解如何保留和使用HP-UX缓冲区高速缓存将有助于您为您的应用环境确定适合的配置。
本文将着重讨论关于HP-UX缓冲区高速缓存的下述问题:
1. 什么是缓冲区高速缓存?
2. 静态缓冲区高速缓存与动态缓冲区高速缓存的区别何在?
3. 缓冲区高速缓存的工作原理是怎样的?
4. 缓冲区高速缓存及其相关结构需要多少内存?
5. 使用缓冲区高速缓存的利弊何在?
6. 是否可以绕过缓冲区高速缓存?
7. 配置缓冲区高速缓存应遵循什么原则?
 
什么是缓冲区高速缓存?
 
缓冲区高速缓存是内存中的一个区域,用于保存二级存储设备中的页。缓冲区高速缓存通过在内存中存储经常被访问的页来减少对二级存储设备的访问。
      
一旦文件数据被调入内存,就可以在内存中进行随后的访问,而无需访问二级存储设备。
 
静态与动态缓冲区高速缓存
 
默认情况下,缓冲区高速缓存是动态的,因为它可以根据需要扩大或缩小。要调节动态缓冲区高速缓存,可以将内核可调参数nbuf和bufpages设为零,并将dbc_min_pct和dbc_max_pct分别设为占用内存的最小和最大比例。默认值为:
dbc_max_pct 50
dbc_min_pct 5
注意:dbc_min_pct不能低于2,dbc_max_pct不能高于90。
系统最初启动时,将按照dbc_min_pct的值(默认为5%)为缓冲区页分配相应比例的内存(每页为4096个字节)。系统还会为每2个缓冲区页分配1个缓冲区头指针(header)。随着新页不断从磁盘调入,缓冲区高速缓存的大小将不断增加。缓冲区高速缓存可以快速增大,达到dbc_max_pct指定的最高内存比例。大型文件拷贝和备份会使缓冲区高速缓存迅速达到其最大值。缓冲区高速缓存增加速度非常快,但只有当内存需求紧张时它才会减少。
通过设置nbuf或bufpages可将静态缓冲区高速缓存的大小配置为固定值。设定nbuf的值可以指定应分配的缓冲区头指针的数量。系统将为每个缓冲区头指针分配两个缓冲区页,缓冲区页总量为nbuf*2。如果设置了bufpages内核参数,且nbuf为0,那么缓冲区页的页数将被赋值给bufpages,每2个缓冲区页将分配到一个缓冲区头指针,缓冲区头指针的总量为bufpages/2个。如果同时设置了nbuf和bufpages的值,那么nbuf就用于调节缓冲区高速缓存的大小。
另外,将dbc_min_pct和dbc_max_pct设为相同值也可以对静态缓冲区高速缓存进行配置。
静态和动态缓冲区高速缓存都存在折衷。如果出现内存需求紧张,静态缓冲区高速缓存无法减少,很可能会造成比较重要的页被换出或者进程被释放。相比之下,在管理动态缓冲区高速缓存(如缓冲区的动态分配)以及管理缓冲区高速缓存地址映像或缓冲区高速缓存虚拟位图(bufmap和bcvmap将在以下章节进行详细讨论)方面存在一些系统开销。另外,动态缓冲区高速缓存的增加速度非常快,但降低速度非常慢,只有当内存需求紧张时它才会释放空间。
 

缓冲区高速缓存的工作原理

 
缓冲区高速缓存的主要部分有缓冲区高速缓存哈希表、缓冲区头指针和缓冲区页。我们至少要为实际缓冲区的每个缓冲区头指针分配1个页,即使缓冲区的大小只有1kb。缓冲区最大为64kb。当需要磁盘上的数据时,我们可以利用块设备(特别是块设备的vnode地址)和块号来计算哈希索引,并将其存入缓冲区高速缓存哈希表,该表存放的是一系列缓冲区高速缓存哈希头指针。缓冲区高速缓存哈希头指针将指向一个缓冲区链表,这些缓冲区的块设备和块号映射到同一哈希头指针。
如果要从一台设备访问一个块,而它不在相应的哈希链中,这时就会出现缓冲区高速缓存故障,并发生以下两种情形之一:
1. 分配一个新缓冲区(如果使用的是动态缓冲区高速缓存)。必须从磁盘读入数据。
2. 重复使用现有缓冲区(如果使用的是静态缓冲区高速缓存,或者该缓冲区高速缓存已经达到dbc_max_pct值),必须从磁盘读入数据。重复使用的缓冲区或者是无效缓冲区(即文件已被删除或文件系统已被卸载),或者是最近没有访问过的缓冲区。
但如果在该缓冲区高速缓存中找到了需要访问的缓冲区,那么无需访问磁盘就可以访问数据了。
 

 
图表:HP-UX缓冲区高速缓存
注意:即使文件关闭后缓冲区仍保留在缓冲区高速缓存中。因此,如果一小段时间后重新打开文件,缓冲区仍然在缓冲区高速缓存中。例如,如果您的缓冲区高速缓存大小为500 MB,当您对一个100MB的文件执行grep(1)命令时,系统在扫描文件时需要将每个数据块都读入缓冲区高速缓存。但随后如果您在同一文件上再执行grep(1)命令,系统会通过缓冲区高速缓存访问该文件,而无需访问磁盘设备,即使该文件在执行完第一次grep(1)后已经关闭。
 
缓冲区高速缓存与内存
 
缓冲区高速缓存占用多少内存?这个问题似乎很简单。如果您在12GB内存的系统上将缓冲区高速缓存配置为动态的,最高占物理内存的10%,那么缓冲区高速缓存最大可为1.2GB。但这只是指缓冲区页。用于管理缓冲区高速缓存的其它结构不在此范围之列。这些其它结构包括:
• 缓冲区头指针。
• 缓冲区高速缓存哈希表
• 缓冲区散列锁(Hash Lock)
• 缓冲区高速缓存地址映像/缓冲区高速缓存虚拟映像
 
缓冲区头指针
 
缓冲区高速缓存中的每个缓冲区都需要一个头指针结构,用于定义块所代表的内容、它的使用方法及其连接方式。缓冲区头指针长度约为600字节。如果缓冲区高速缓存是固定的,则系统初始化时将为其分配nbuf缓冲区头指针。如果缓冲区高速缓存是动态的,则系统将根据需要为其动态分配缓冲区头指针。当需要更多缓冲区头指针时,系统将为其分配一个内存页,该内存页将被划分为一个4K页所能容纳的最大数量的缓冲区头指针。
缓冲区高速缓存哈希表
缓冲区高速缓存中的块被映射,以便可以对其进行快速访问。在启动时系统将计算哈希表目的数量,该数值是空闲内存页数的¼,不足¼按最近的2的幂数计算。因此一个12 GB内存的系统大约有100万个哈希表目(不考虑缓冲区高速缓存配置)。一页为4096字节,因此12GB就有3145728个页。它的¼为786432个,与它最近的2的幂数即1,048,576。每个哈希头指针为40个字节,因此12GB的系统就应该为缓冲区高速缓存哈希表分配40MB的内存。
缓冲区高速缓存散列锁
并非每个缓冲区高速缓存哈希头指针都有一个锁,而是多个哈希头指针共用一个锁。这就减少了哈希锁需要的内存量。以下表2详细说明了每个哈希锁覆盖的哈希链数量。
缓冲区高速缓存地址映像/缓冲区高速缓存虚拟映像
在HP-UX 11.00和此前的版本中,缓冲区高速缓存地址映像(实际上有2个映像 — bufmap/bufmap2。下面提到bufmap时指的是上述两个映像)是一种资源映像,用于追踪缓冲区高速缓存使用的虚拟地址。bufmap包含所有可用于缓冲区高速缓存的空闲地址范围的记录。bufmap的大小视内存大小的不同而不同。在32位系统上,它约占内存的1%,在64位操作系统上约占内存的2%。
 
缓冲区高速缓存虚拟映像(bcvmap)是HP-UX 11.11中采用的一种位映像,代表缓冲区高速缓存中的页。由于它是位映像(bitmap),因此其内存需求比bufmap要低。默认情况下,位映像的大小(单位:位)与物理内存页的数量*内核可调参数bcvmap_size_factor(默认值为2)一致。管理位映像组需要一些系统开销,但总的来说,内存使用量非常小。
 
bcvmap_size_factor的默认值2适用于许多系统,尤其是将dbc_max_pct值设为20或更低的系统。但当使用动态缓冲区高速缓存时,各种大小的缓冲区可以根据需要随时分配和释放。大小可变的缓冲区的分配和释放可以将bcvmap分割开使用。如果没有任何位映像区域可以用来表示所需的缓冲区大小,那么系统可能会震荡(thrash)。这种现象在dbc_max_pct配置为50%或更高的系统上较为常见,在使用不同大小的缓冲区的系统上也比较常见。在下述情况下可以使用大小不同的缓冲区:当使用数据块大小不同的多个HFS文件系统或使用多个JFS文件系统时,其中部分文件系统将max_buf_data_size设为8 KB,而其他文件系统将max_buf_data_size设为64 KB。在这种高速缓存中,bcvmap_size_factor应至少增加到16。
参见vxtunefs(1M),了解关于max_buf_data_size的更多信息。
 
注意:bcvmap_size_factor参数仅用于安装了PHKL_27808的64位11.11系统。
下表提供的部分实例列举了具有不同内存大小、不同可调参数值的系统的内存需求。
系统内存大小 10% BufPages/缓冲区头指针 20%BufPages/缓冲区头指针 50%BufPages/缓冲区头指针
1GB             100MB/7.3MB                    200MB/15MB              500MB/36MB
2GB             200MB/15MB                     400MB/30MB                1GB/75MB
4GB             400MB/30MB                     800MB/60MB                2GB/150MB
8GB             800MB/60MB                     1.6GB/120MB               4GB/300MB
12GB            1.2GB/90MB                     2.4GB/180MB               6GB/450MB
32GB            3.2GB/240MB                    6.4GB/480MB              16GB/1.2GB
256GB          25.6GB/2GB                       51GB/4GB               128GB/9.6GB
系统内存大小 哈希表大小 每个锁的哈希表目数量 哈希表内存需求
1GB           65536            512               2.5MB
2GB          131072           1024                 5MB
4GB          262144           2048                10MB
8GB          524288           4096                20MB
12GB        1048576           8192                40MB
32GB        2097152          16384                80MB
256GB      16777216         131072               640MB
缓冲区高速缓存的优势
 
采用缓冲区高速缓存有以下几大优势。
1. 顺序I/O很少。应用通过各种不同大小的请求从文件系统读取数据,这些请求可能与实际的文件系统块大小不一致。没有缓冲区高速缓存的话,每次请求都必须到物理磁盘中访问整个磁盘块,即使它们需要的容量可能只有几个字节。如果下一次读操作是读取同一个物理磁盘块,那么系统就需要再次读入该磁盘块,因为它没有保存。但如果有缓冲区高速缓存,第一次读是与磁盘之间进行物理I/O,但接下来对同一磁盘块的读操作就可以通过缓冲区高速缓存来完成了。
 
2. 预读。如果文件系统的访问是顺序的,那么缓冲区高速缓存将通过预读来提高性能。当文件系统检测到对文件的顺序访问时,就开始对后面的块进行异步读取(也被称为预取),因此当应用对数据发出请求时该数据可能已经在(或者正在传输中)缓冲区高速缓存中了。
 
在HFS文件系统中,一般的顺序读取通过系统可调参数hfs_ra_per_disk来配置。如果使用LVM条带化,我们可以将hfs_ra_per_disk的值与条带的数量相乘。
 
在JFS 3.1文件系统中,顺序预读刚开始时读取数据很少,随着顺序访问的不断进行,JFS预读的数据越来越多。
 
在JFS 3.3/3.5中,预读区域是文件系统可调参数read_pref_io和read_nstream的乘积。当第一次检测到顺序访问时,系统将把4倍的预读区域读入缓冲区高速缓存(4 * read_pref_io * read_nstream)。当应用完成了一个区域的读取后,系统将异步预取下一区域。预读可能非常有益于顺序文件存取。但通常进行随机I/O操作的应用可能会偶尔读取连续的数据块,从而无意中产生大量的预读数据。这种情况下可能不使用预读,因为文件整体上是随机读取的。
 
在JFS 3.3/3.5中,预读数据的大小受vxtunefs参数read_nstream和read_pref_io的控制,在JFS3.5中可以通过将vxtunefs参数read_ahead设为0来取消预读。在JFS 3.1中,预读数据的大小不可调节。
 
3. 热数据块。如果应用(单进程或多进程)反复读取文件系统块,则该块将保留在缓冲区高速缓存中,因此系统每次需要访问该数据时都无需到磁盘中读取。当应用反复搜索一个大型目录(可能要创建一个临时文件)时缓冲区高速缓存尤其有用。如果经常使用这些目录块,那么它们很可能会被保留在缓冲区高速缓存中,系统就无需访问物理磁盘了。
 
4. 延迟写。缓冲区高速缓存支持应用进行延迟或异步写。应用只需将数据写到缓冲区高速缓存中,系统调用就会返回,而无需等待系统完成对磁盘的I/O操作。随后系统会通过syncer(1M)、sync(1M)或fsync(2)等操作将脏缓冲区刷新到磁盘。进行延迟写有时被称为后刷新(flush behind)。
 
使用缓冲区高速缓存的弊端
 
每个应用似乎都可以从使用缓冲区高速缓存中受益,其实使用缓冲区高速缓存要付出一些代价。
1. 内存。根据缓冲区高速缓存的配置情况,它可能会是占用内存最厉害的。默认情况下,在8 GB内存的系统中,仅缓冲区高速缓存页就会占去4 GB的内存(dbc_max_pct设为50)。即使采用动态缓冲区高速缓存,大容量的缓冲区高速缓存也可能导致总的内存需求紧张。记住,除非内存出现需求紧张,否则缓冲区高速缓存不会释放缓冲区页。一旦出现内存紧张,缓冲区页就像其它用户页一样从时间最长的开始被侵占,因此它的减小速度比扩张速度要慢得多。
2. 刷新缓冲区高速缓存。
Syncer — syncer(1M)是将延迟写缓冲区刷新至物理磁盘的进程。当然,缓冲区高速缓存越大,syncer就可能完成越多工作。11.0 syncer是单线程进程。它定时被唤醒,并顺序扫描整个缓冲区高速缓存,以查找需要写到物理设备上的数据块。默认的syncer间隔为30秒,也就是说每隔30秒,系统就会对整个缓冲区高速缓存进行扫描,以查找延迟写数据块。实际上在每次syncer间隔中syncer运行5次,每次扫描1/5的缓冲区高速缓存。
 
HP-UX 11.11在刷新脏缓冲区时更加高效。11.11 syncer是多线程进程,每个CPU有一个线程。每个CPU都有一个脏表(dirty list),每个syncer线程负责从其各自的脏表刷新缓冲区。这就提高了缓冲区高速缓存的缩放,因为系统只扫描脏缓冲区,而且每个线程都有自己的脏缓冲区表,这就避免了对一个表的争用。
其他Sync操作 — 各种系统操作要求在操作完成前将缓冲区高速缓存中的脏块写到磁盘中。文件的最后一次关闭,文件系统的卸载或一次sync系统调用都属于此类操作。这些操作独立于syncer,必须扫描整个缓冲区高速缓存,以查找需要写到设备的块。对于卸载这种情形,一旦操作完成,它必须重新扫描缓冲区高速缓存,以便使刷新后的缓冲区无效。缓冲区高速缓存的这些扫描可能十分耗时,尤其是当出现散列锁争夺现象时。
3. 限制IO — 除了检查哈希链和锁定/打开散列锁之外,缓冲区高速缓存越大,在高速缓存中需要刷新到磁盘的脏缓冲区数量可能就越多。这可能会导致在sync操作过程中大量写I/O操作排队等待磁盘。一个读请求或异步写请求可能会滞后于写操作,从而引起应用延迟。由于限制了每次排队等待磁盘的缓冲区数量,缓冲区高速缓存的刷新速度可能会受到限制。默认情况下,关闭限制功能。在JFS 3.1中,如果安装了PHKL_27070,则可以通过将vx_nothrottle设置为0来启用限制功能。这就通过sync操作(如卸载文件系统)减轻了读饥饿。在JFS 3.3/3.5中,从单个文件刷新到磁盘的数据量可以通过vxtunefs max_diskq参数来控制。
 
限制写操作 — 设置max_diskq来限制脏缓冲区的刷新有一个弊端。执行sync操作的进程(如umount(1M)或bdf(1M))可能会由于写操作受到限制而停止。设置max_diskq并不会阻止应用继续执行异步写操作。如果对大型文件进行写,那么脏缓冲区很有可能会耗尽所有缓冲区,并可能导致其它重要应用的读或写延迟。
 
JFS 3.5中采用了一个新的可调参数 — write_throttle.它可以控制一个文件可以容纳的未完成的脏缓冲区的数量。如果一个应用的写速度意欲超过数据写到磁盘的速度,并且达到了write_throttle的值,那么该应用将一直等到部分数据写到磁盘后,脏缓冲区中的数据量重新低于write_throttle值为止。
设置write_throttle能够减少long sync的次数,同时保持磁盘I/O队列的可管理性。但是写到磁盘的应用在其写数据时可能会遇到延迟。
 
4. 大型I/O。一个缓冲区最大可以为64 Kb。对于高于64 Kb的I/O来说,请求必须分解成多个64 Kb I/O。因此从磁盘读取256 Kb的数据就需要4次I/O。但如果绕过缓冲区高速缓存,就可以直接执行一次256 Kb I/O。
 
5. 只访问一次的数据。缓冲区高速缓存的管理需要额外的代码和处理。对于只访问一次的数据,使用缓冲区高速缓存在高速缓存中保存数据没有任何好处。事实上,将只访问一次的数据放入高速缓存,系统可能需要移出那些经常访问的缓冲区页。
 
6. 系统崩溃。由于许多写操作都被延迟,当系统崩溃时,系统可能在缓冲区高速缓存中有许多需要刷新至磁盘的“脏”缓冲区。缓冲区高速缓存中在系统崩溃前没有更新的的数据就会丢失。
 
绕过缓冲区高速缓存
 
有几种方法可以避免I/O使用全部缓冲区高速缓存。绕过缓冲区高速缓存被称为直接I/O。对于下面提到的JFS特性来说,要执行直接I/O需要HP OnlineJFS授权。
- mincache=direct,convosync=direct
 
在JFS文件系统中,如果文件系统在安装时选择了mincache=direct选项和/或convosync=direct选项,那么将绕过对缓冲区高速缓存的读写 — 参见mount_vxfs(1M)的manpage,了解更多详细信息。如果文件系统在安装时选择了这些选项,那么所有对文件系统的I/O操作将绕过缓冲区高速缓存。当绕过缓冲区高速缓存时将无法进行预读和延迟写,因为没有了中间保存区。
- ioctl (fd,VX_SETCACHE, VX_DIRECT)
 
在JFS文件系统中,该ioctl调用将把对fd引用的文件的访问设为直接访问,并绕过缓冲区高速缓存。该调用仅用于fd引用的文件实例。其它打开同一文件的应用不受影响。参见vxfsio(7) manpage,了解更多信息。
-discovered direct IO
 
JFS提供了一种被称为discovered direct I/O的特性,其中超过一定大小的I/O操作使用直接I/O来完成。只进行一次数据读取的应用(如备份或拷贝操作)通常执行大型I/O。由于只进行一次数据存取,因此将数据调入高速缓存不会带来任何好处。将数据调入高速缓存甚至可能会带来负面效果,因为只访问一次的数据可能会占用比较有用的缓冲区。因此,JFS文件系统上的大型I/O采用“直接”执行,绕过缓冲区高速缓存。在JFS 3.1中,discovered direct I/O的大小固定为128 Kb。在JFS 3.3/3.5中,默认的discovered direct IO的大小为256 Kb,但可以通过设置vxtunefs(1M)的discovered_direct_iosz可调参数来对其进行设定。
-raw io
 
如果对数据的访问是通过原始设备文件,则不使用缓冲区高速缓存。
-async driver
 
一些数据库使用async driver(/dev/async)来执行异步I/O操作,而绕过缓冲区高速缓存,直接读入共享内存段。
HP-UX缓冲区高速缓存调节指南。
 
为调节缓冲区高速缓存提供指南非常困难。很多因素要取决于在系统上运行的各种应用。但我们可以提供一些一般性总结。
 
如果使用数据库,数据库缓冲很可能比系统缓冲更加高效。数据库可能更熟悉I/O模式,从而将相关的缓冲区留在内存中。因此如果可以选择的话,内存应分配给数据库全局区,而不是系统缓冲区高速缓存。
 
我们已经了解到HP-UX 11.11在处理大型缓冲区高速缓存方面比HP-UX 11.0更加高效。“大型”这一词是相对而言的,但在本文讨论中可以认为它是指大于1 Gb或高于50%内存的缓冲区高速缓存。总体而言,由于大型高速缓存存在缩放问题,11.0上的缓冲区高速缓存应配置为1GB或更低,但可以比11.11上的大。但如果您使用的是11.11上的大型缓冲区高速缓存,那么您应该安装PHKL_27808或替代补丁,以提高缓冲区高速缓存的虚拟映像的大小。
缓冲区高速缓存越大,您的sync操作所用时间就会越长。这尤其会影响文件系统的安装和卸载次数。如果需要快速安装或卸载文件系统(如在SG数据包交换过程中),那么可以考虑使用较小的缓冲区高速缓存。
 
如果缓冲区高速缓存的配置过低,那么系统可能会不断搜索可用的缓冲区。在大多数系统上应尽可能将缓冲区高速缓存配置为最低200MB。
 
最受益于大型高速缓存的应用往往是文件服务器,如NFS或web服务器,其中大量数据经常要被访问到。一些不管理自身文件存取的数据库应用也可能属于这一类。请与您的应用厂商联系,了解具体厂商的建议。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12951/showart_113267.html

论坛徽章:
0
2 [报告]
发表于 2011-08-09 00:18 |只看该作者
很好的文章,推荐CU友看一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP