На нашем видео-пректе при отдаче видео с серверов возникает вопрос производительност дисковой подсистемы. Очевидно, что гигабитные сетевые интерфейсы обладают большей производительностью, чем, скажем, RAID0 из 2х дисков. И если бы видео-ролики обладали одинаковой популярностью, то диски являлись бы узким местом при отдаче контента.
Однако же, нам повезло и всегда есть небольшой набор роликов, которые делают 80% трафика, и длинный хвост с редкой посещаемостью. Этот небольшой набор оседает в кеше файловой системы и отдается практически без дисковой активности.
Например, если у нас на сервере лежит 100 гигабайт роликов, а памяти на сервере 24 гигабайта, то мы можен нарисовать такой график. По горизонтали у нас будут «файлы», отсортированные по популярности, по вертикали — трафик, порождаемый этими файлами. Суммарный трафик — площадь поверхности под графиком.

filesystemcache

С другой стороны, всегда стоит вопрос, сколько памяти на сервер лучше поставить и как померять hit/miss ratio. В этом посте мы рассмотрим, как это можно сделать.

Насколько мне известно, нет стандартной утилиты, которая бы собирала cache hit ratio для кеша файловой системы, но мы собираем это при помощи SystemTap.
Вот скрипт, комментарии ниже.

global total_bytes, disk_bytes, counter, overall_cache_bytes, overall_disk_bytes

probe vfs.read.return {
        if ($return > 0) {
                total_bytes += $return
        }
}

probe generic.fop.sendfile.return {
	if ($return > 0) {
		total_bytes += $return
	}
}

probe ioblock.request {
        if (rw == 0 && size > 0 && devname == "dm-0") {
                disk_bytes += size
        }
}

probe begin {
	disk_bytes = 0
	total_bytes = 0
}

probe timer.s(1) {
        if (counter%15 == 0) {
                printf ("\n%18s %18s %18s %10s %10s\n", 
                        "Total Reads (KB)", "Cache Reads (KB)", "Disk Reads (KB)", "Miss Rate", "Hit Rate")
        }
        counter++

        cache_bytes = total_bytes - disk_bytes
        if (cache_bytes < 0) {
                cache_bytes = 0
	}
        if (cache_bytes+disk_bytes > 0) {
                hitrate =  10000 * cache_bytes / (cache_bytes+disk_bytes)
                missrate = 10000 * disk_bytes / (cache_bytes+disk_bytes)
        } else {
                hitrate = 0
                missrate = 0
        }
        printf ("%18d %18d %18d %6d.%02d%% %6d.%02d%%\n", total_bytes/1024, cache_bytes/1024, disk_bytes/1024, missrate/100, missrate%100, hitrate/100, hitrate%100)
        overall_cache_bytes += cache_bytes
        overall_disk_bytes += disk_bytes
        total_bytes = 0
        disk_bytes = 0
}

probe end {
        avg_hitrate =  10000 * overall_cache_bytes / ( overall_cache_bytes + overall_disk_bytes )
        avg_missrate = 10000 * overall_disk_bytes  / ( overall_cache_bytes + overall_disk_bytes )
        printf("\n%s: %d.%02d\n%s: %d.%02d\n", 
                " Average Hit Rate", avg_hitrate/100, avg_hitrate%100, 
                "Average Miss Rate", avg_missrate/100, avg_missrate%100)
}

Сервер отдает файлы не при помощи read/write, а используя sendfile. Поэтому, основной дисковый трафик накручивается в probe generic.fop.sendfile.return. Также, т.к. мы считаем только read и sendfile, а дисковый трафик может порождаться операциями записи или разными stat-ами, readdir-ами, getdents-ами и прочим, total_bytes могут оказаться меньше, чем read_bytes. Но у нас на сервере 99% процентов операций — это read или sendfile, поэтому мы на такое закрываем глаза, вносимые искажения довольно малы.

Результат получается примерно следующий:

# stap cache-hit-rate.stp 
  Total Reads (KB)   Cache Reads (KB)    Disk Reads (KB)  Miss Rate   Hit Rate
            116150             113894               2256      1.94%     98.05%
            119515             116643               2872      2.40%     97.59%
            117422             114438               2984      2.54%     97.45%
            115679             112203               3476      3.00%     96.99%
            121254             118526               2728      2.24%     97.75%
            119375             116059               3316      2.77%     97.22%
            114101             109885               4216      3.69%     96.30%
            114776             112416               2360      2.05%     97.94%
            118970             116062               2908      2.44%     97.55%
            121416             117820               3596      2.96%     97.03%
            115386             112790               2596      2.24%     97.75%
            119955             116831               3124      2.60%     97.39%
            118245             115893               2352      1.98%     98.01%
            118250             115398               2852      2.41%     97.58%
            117079             114171               2908      2.48%     97.51%

  Total Reads (KB)   Cache Reads (KB)    Disk Reads (KB)  Miss Rate   Hit Rate
            112801             110241               2560      2.26%     97.73%
            118078             115742               2336      1.97%     98.02%
            117863             114659               3204      2.71%     97.28%
            119600             117120               2480      2.07%     97.92%
            118293             114977               3316      2.80%     97.19%

Average Hit Rate: 97.51
Average Miss Rate: 2.48
#
  • Sharing

    Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather