歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Linux中Buffer cache性能問題解析

1, Buffer cache的作用

為了提高磁盤設備的IO性能,我們采用內存作為磁盤設備的cache。用戶操作磁盤設備的時候,首先將數據寫入內存,然後再將內存中的髒數據定時刷新到磁盤。這個用作磁盤數據緩存的內存就是所謂的buffer cache。在以前的Linux系統中,有很完善的buffer cache軟件層,專門負責磁盤數據的緩存。在磁盤設備的上層往往會架構文件系統,為了提高文件系統的性能,VFS層同樣會提供文件系統級別的page cache。這樣就導致系統中存在兩個cache,並且重疊在一起,顯得沒有必要和冗余。為了解決這個問題,在現有的Linux系統中對buffer cache軟件層進行了弱化,並且和page cache進行了整合。Buffer cache和page cache都采用radix tree進行維護,只有當訪問裸設備的時候才會使用buffer cache,正常走文件系統的IO不會使用buffer cache。

我們知道ext3文件系統的page cache都是以page頁大小為單位的,那麼buffer cache中緩存塊大小究竟是多大呢?其對性能影響如何呢?這兩天我在Linux-2.6.23平台上針對這個問題做了很多實驗,得到了一些數據結果,並從源代碼分析中得到設置緩存塊大小的方法。在此對這個buffer cache的性能問題進行分析說明,供大家討論。

2, Buffer cache的性能問題

2.1 測試實驗

首先讓我們來做一個實驗,在Linux-2.6.23平台上,采用dd工具對一個塊設備進行順序寫操作,可以采用如下的命令格式:

dd if=/dev/zero of=/dev/sda2 bs=<request_size> count=100

采用該命令在不同buffer cache塊(blk_size)大小配置的情況下測試不同請求大小(req_size)的IO性能,可以得到如下表所示的測試數據:

表:不同buffer cache塊大小配置下的吞吐量

將表中的數據做成性能對比圖,如下圖所示:

從圖中可以看出,在請求大小小於Cache塊大小的時候,Cache塊越大,IO性能越高;但是,請求大小大於Cache塊大小之後,性能都有明顯的飛躍。

例如,當buffer cache塊大小被配置成2KB時,小於2KB的塊性能基本都在19MB/s左右;當buffer cache塊大小被配置成512B時,小於512B的寫性能都保持在5MB/s;當buffer cache塊大小被配置成1024B時,小於1KB的寫性能基本都保持在9.5MB/s上下。這就說明對於小於cache塊大小的small_write,buffer cache越大,其性能會越好,反之,性能越差,這就是buffer cache的作用。

觀察發現一旦請求大小大於等於cache塊大小之後,性能急劇提升,由於測試工具的IO壓力足夠大,能夠一下子將磁盤性能耗盡。這是為什麼呢?其實,當請求塊比較小時,對於cache塊而言是“局部操作”,這種“局部操作”會引入buffer cache的數據讀操作,並且數據讀操作和用戶寫操作存在順序關系,這就極大的影響了IO的寫性能。因此,當請求大小大於cache塊時,並且能夠和Cache塊對齊時,就能夠充分利用磁盤的IO帶寬,所以就產生了上圖中所示的性能飛躍。

看到上圖中的測試結果之後,我們就會想在實際應用中,我們該如何選擇buffer cache的塊大小?如果請求大小是512B時,顯然將buffer cache塊設置成512比較合適;如果請求大小是256B時,顯然將buffer cache塊設置成2KB比較合適。所以,個人認為塊大小的設置還需要根據實際的應用來決定,不同的應用需要設置不同的塊大小,這樣才能使整體性能達到最佳。

2.2 Buffer cache塊大小

Linux系統在創建塊設備的時候是如何設置塊大小的呢?這裡面涉及到Linux針對塊大小設置的一個小小算法。在此結合源碼對Linux的這個方法加以說明。

總體來說,Linux決定buffer cache塊大小采用的是“最大塊大小”的設計思想。Linux根據塊設備容量決定buffer cache的塊大小,並且將值域限定在512B和4KB之間。當然,這個值域內的元素不是連續的,並且都是2的冪。在這個值域的基礎上取塊設備大小的最大公約數,這個值就是buffer cache的塊大小。這種算法的指導思想就是buffer cache的塊越大越好,因此,能夠取2KB就不會選擇512B。Linux中算法實現代碼如下所示:

void bd_set_size(struct block_device *bdev, loff_t size)  
{  
                unsigned bsize = bdev_logical_block_size(bdev);  
     
                bdev->bd_inode->i_size = size;      //size為塊設備大小  
                while (bsize < PAGE_CACHE_SIZE) {   //bsize不能大於Page size  
                                if (size & bsize)  
                                                break;  
                                bsize <<= 1;    //bsize只能取2的冪  
                }  
                bdev->bd_block_size = bsize;  
    /* 設置buffer cache塊大小 */
                bdev->bd_inode->i_blkbits = blksize_bits(bsize);  
}

3, 小結

本文對buffer cache的性能問題進行了分析,通過實驗發現當請求塊比較小時,buffer cache塊大小對IO性能有很大的影響。Linux根據塊設備的容量采用“最大cache塊”的思想決定buffer cache的塊大小。在實際應用中,我們應該根據應用特征,通過實際測試來決定buffer cache塊大小。

Copyright © Linux教程網 All Rights Reserved