Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

File system benchmark

Я провел небольшое исследование и сравнил производительность четырех файловых систем, которые поддерживаются в ядре практически всеми основными дистрибутивами.
Речь идет о ext4, btrfs, xfs, jfs .

Нам понадобятся отдельная партиция размером желательно порядка 10 гигов, а также стандартные утилиты для создания файловых систем:

mkfs.ext4
mkfs.btrfs
mkfs.xfs
mkfs.jfs

В разных дистрибутивах эти утилиты могут лежать в разных пакетах. Например, для того чтобы в центосе установить xfs, нужно выполнить
yum install xfsprogs-devel
yum install kmod-xfs xfsdump xfsprogs dmapi
а для btrfs соответственно
yum install btrfs*

В Suse соответственно нужно выполнить команды:
zypper in xfsprogs
zypper in btrfsprogs
zypper in jfsutils

Первый тест

Первый тест будет совсем простой. Будет создана файловая структура, в которую будет положено 200 тысяч мелких файлов каждый размером в один килобайт. На моем подопытном компьютере винчестер - сата-шный, оперативной памяти - 2 гига, процессор - пень три гигагерца. Параметры файловой системы берутся по умолчанию. При этом во всех случаях размер блока равен 4 килобайтам.

Итак, начинаем с ext4. Форматируем партицию, предварительно ее отмонтировав:

mkfs.ext4 /dev/sda10

Вывод:

 mke2fs 1.42.4 (12-June-2012)
 Filesystem label=
 OS type: Linux
 Block size=4096 (log=2)
 Fragment size=4096 (log=2)
 Stride=0 blocks, Stripe width=0 blocks
 960992 inodes, 3839527 blocks
 191976 blocks (5.00%) reserved for the super user
 First data block=0
 Maximum filesystem blocks=3934257152
 118 block groups
 32768 blocks per group, 32768 fragments per group
 8144 inodes per group
 Superblock backups stored on blocks: 
         32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
 
 Allocating group tables: done                            
 Writing inode tables: done                            
 Creating journal (32768 blocks): done
 Writing superblocks and filesystem accounting information: done 
 
Проверим результат форматирования:

fdisk -l /dev/sda10

 Disk /dev/sda10: 15.7 GB, 15726703104 bytes
 255 heads, 63 sectors/track, 1911 cylinders, всего 30716217 секторов
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 
Код утилиты для первого теста, которая сгенерирует 200 тысяч файлов:
 #include < stdio.h>
 #include < stdlib.h>
 #include < unistd.h>
 #include < fcntl.h>
 #include < sys/stat.h>
 #include < sys/types.h>
 #include < time.h>
 #include < sys/time.h>
 
 
 static void doit(char *name) {
   static char stuff[1024];
   int fd;
 
   fd = creat(name, 0666);
   if (fd < 0) {
     perror(name);
     exit(1);
   }
   write(fd, stuff, sizeof(stuff));
   close(fd);
 }
 
 
 int timeval_subtract (result, x, y)
 struct timeval *result, *x, *y;
 {
    /* Perform the carry for the later subtraction by updating y. */
    if (x->tv_usec < y->tv_usec) 
    {
        int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
        y->tv_usec -= 1000000 * nsec;
        y->tv_sec += nsec;
    }
    if (x->tv_usec - y->tv_usec > 1000000) 
    {
        int nsec = (x->tv_usec - y->tv_usec) / 1000000;
        y->tv_usec += 1000000 * nsec;
        y->tv_sec -= nsec;
    }
    result->tv_sec = x->tv_sec - y->tv_sec;
    result->tv_usec = x->tv_usec - y->tv_usec;
    return x->tv_sec < y->tv_sec;
 }
                                                                            
 
 int main(void) {
 
   int i, j, k, l;
   char buf[100];
   struct timeval tv1, tv2, diff;
   
   gettimeofday(&tv1, NULL);
   
   for (i = 0; i < 10; i++) {
     sprintf(buf, "%d", i);
     mkdir(buf, 0777);
     for (j = 0; j < 10; j++) {
       sprintf(buf, "%d/%d", i, j);
       mkdir(buf, 0777);
       printf("%s\n", buf);
       for (k = 0; k < 10; k++) {
 	sprintf(buf, "%d/%d/%d", i, j, k);
 	mkdir(buf, 0777);
 	for (l = 0; l < 200; l++) {
 	  sprintf(buf, "%d/%d/%d/%d", i, j, k, l);
 	  doit(buf);
 	}
       }
     }
   }
   
   gettimeofday(&tv2, NULL);
   
   int result = timeval_subtract(&diff, &tv2, &tv1);
   
   printf("seconds: %d", diff.tv_sec);
   
   exit(0);
 }
 
 
Монтируем партицию. Копируем утилиту на тестируемую партицию и запускаем. Результат у меня для ext4 получился - 17 секунд.

Переходим к btrfs. Форматируем партицию, предварительно ее отмонтировав:

mkfs.btrfs /dev/sda10

Вывод:

 fs created label (null) on /dev/sda10
         nodesize 4096 leafsize 4096 sectorsize 4096 size 14.65GB
 
 

Результат для btrfs похуже - 24 секунды.

Переходим к xfs. Форматируем партицию:

mkfs.xfs -f /dev/sda10

Вывод:

 meta-data=/dev/sda10             isize=256    agcount=4, agsize=959882 blks
          =                       sectsz=512   attr=2, projid32bit=0
 data     =                       bsize=4096   blocks=3839527, imaxpct=25
          =                       sunit=0      swidth=0 blks
 naming   =version 2              bsize=4096   ascii-ci=0
 log      =internal log           bsize=4096   blocks=2560, version=2
          =                       sectsz=512   sunit=0 blks, lazy-count=1
 realtime =none                   extsz=4096   blocks=0, rtextents=0
 

Результат для xfs совсем плохой - 74 секунды, при этом винт нещадно хрустит.

Переходим к jfs. Форматируем партицию, предварительно ее отмонтировав:

mkfs.jfs /dev/sda10

Запускаем тест и получаем совершенно неприличный результат - 131 секунду.

Второй тест

Для чистоты эксперимента, перед каждым последующим тестом мы снова форматируем партицию и начинаем с чистого листа.

В качестве второго теста мы используем Bonnie:

http://www.textuality.com/bonnie/

Его также можно скачать тут

Этот тест выполняет посимвольно и поблочно запись, чтение и поиск.

Снова форматируем под ext4. Компилируем Bonnie, копируем на тестируемую партицию. Запускаем команду - при этом будет создан тестовый файл размером в 1 гигабайт:

Bonnie -s 1000

Вывод:

 File './Bonnie.7870', size: 1048576000
 Writing with putc()...done
 Rewriting...done
 Writing intelligently...done
 Reading with getc()...done
 Reading intelligently...done
 Seeker 1...Seeker 2...Seeker 3...start 'em...done...done...done...
               -------Sequential Output-------- ---Sequential Input-- --Random--
               -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
 Machine    GB M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU  /sec %CPU
             1  34.9 94.6  54.8 13.6  53.2 10.3  41.1 99.2 1807.9 99.8 90214 162.4
 
Теперь форматируем под btrfs. Запускаем тест:

Bonnie -s 1000

Вывод:

               -------Sequential Output-------- ---Sequential Input-- --Random--
               -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
 Machine    GB M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU  /sec %CPU
             1  33.9 96.3  47.1 16.4  54.5 11.7  40.9 99.6 1516.9 99.5 69369 138.7
 
На чтение и на запись btrfs чуть похуже, чем ext4.

Теперь форматируем под xfs. Запускаем тест:

Bonnie -s 1000

Вывод:

               -------Sequential Output-------- ---Sequential Input-- --Random--
               -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
 Machine    GB M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU  /sec %CPU
             1  37.7 98.2  53.2 10.2  54.0  9.1  41.2 99.0 1774.6 99.4 76499 137.7
 
 
xfs показывает почти такой же результат, что и ext4, т.е. здесь xfs уже опережает btrfs.

Теперь форматируем под jfs. Запускаем тест:

Bonnie -s 1000

               -------Sequential Output-------- ---Sequential Input-- --Random--
               -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
 Machine    GB M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU M/sec %CPU  /sec %CPU
             1  32.1 92.4  53.8 15.7  25.3  5.2  42.2 99.7 1834.7 99.8 97489 175.5
 
jfs на запись показывает самые плохие результаты, а вот на чтение/поиск неожиданно опережает всех.

Третий тест

В качестве третьего теста мы используем ffsb: http://sourceforge.net/projects/ffsb/

Его также можно скачать тут

В этом многопоточном тесте можно настроить различные параметры под различную конфигурацию: число тестируемых файлов, минимальный и максимальный размер файла, число потоков. Тест выполняет последовательное и произвольное чтение, запись, создание файла случайного размера, добавление в файл. Для данного теста используется следующий конфиг:

 [filesystem0]
 
 location=/mnt/sda10
 num_files=10000
 num_dirs=1000
 max_filesize=665536
 min_filesize=4096
 
 agefs=0
 [threadgroup0]
 num_threads=10
 write_size=40960
 write_blocksize=4096
 create_weight=10
 append_weight=10
 delete_weight=1
 [end0]
 desired_util=0.02
 
 create_blocksize=1024
 age_blocksize=1024
 reuse=0
 [end0]
 

Копируем на тестируемую партицию 2 файла и запускаем:

ffsb ffsb.cfg

Получаем следующие результаты:

ext4 - 79 секунд

btrfs - 55 секунд

xfs - 75 секунд

jfs - 93 секунды

Неожиданно ext4 проигрывает всем. Но это особенности конфигурации именно для этого теста. Если поиграть с настройкой конфига, я думаю, что можно получить прямо противоположный результат

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье