Увеличение плотности контейнеров на ноде с помощью технологии PFCACHE

a-fci74gdtqxnzgdn7b_q41lr3k.jpeg

Одной из целей хостинг-провайдера является максимально возможная утилизация имеющегося оборудования для предоставления качественного сервиса конечным пользователям. Ресурсы конечных серверов всегда ограничены, однако количество размещенных клиентских сервисов, а в нашем случае речь о VPS, может существенно отличаться. О том, как на елку влезть и бургер съесть, читайте под катом.

Уплотнение VPS на ноде таким образом, чтобы клиенты этого совсем не чувствовали, очень помогает повышать экономические показатели любого хостинг-провайдера. Безусловно, нода не должна трещать по швам, если в нее напихано контейнеров под завязку, и любой всплеск по нагрузке сразу чувствуют все клиенты.

Сколько VPS может быть размещено на одной ноде, зависит от множества факторов, таких очевидных как:

1. Характеристики железа самой ноды
2. Размер VPS
3. Характер нагрузки на VPS
4. Технологии софта, помогающие оптимизировать плотность

В данном случае мы поделимся опытом использования технологии Pfcache для Virtuozzo.
Мы используем 6-ю ветку, но все сказанное справедливо и для 7-й.

Pfcache — механизм Virtuozzo, помогающий дедуплицировать IOPS и RAM в контейнерах, выделяя одинаковые файлы в контейнерах в отдельную общую зону.

Фактически он состоит из:
1. Кода ядра
2. User-space демона
3. User-space утилиты

На стороне ноды, мы выделяем целый раздел, в котором будут создаваться файлы, которыми будут непосредственно пользоваться все VPS на ноде. В данный раздел монтируется блочное устройство ploop. Далее при старте контейнера, он получает референс на данный раздел:

[root@pcs13 ~]# cat /proc/mounts
...
/dev/ploop62124p1 /vz/pfcache ext4 rw,relatime,barrier=1,data=ordered,balloon_ino=12 0 0
...
/dev/ploop22927p1 /vz/root/418 ext4 rw,relatime,barrier=1,data=ordered,balloon_ino=12,pfcache_csum,pfcache=/vz/pfcache 0 0
/dev/ploop29642p1 /vz/root/264 ext4 rw,relatime,barrier=1,data=ordered,balloon_ino=12,pfcache_csum,pfcache=/vz/pfcache 0 0
...

Вот примерная статистика количества файлов на одной из наших нод:

[root@pcs13 ~]# find /vz/pfcache -type f | wc -l
45851
[root@pcs13 ~]# du -sck -h /vz/pfcache
2.4G    /vz/pfcache
2.4G    total

Принцип работы pfcache заключается в следующем:
• User-space демон Pfcached прописывает sha-1 хеш файла в xattr атрибут данного файла. Файлы обрабатываются не все, а только в директориях /usr, /bin, /usr/sbin, /sbin, /lib, /lib64

• Наиболее вероятно, что файлы в данных директориях будут «общими» и будут использованы несколькими контейнерами;

• Pfcached периодически собирает статистику чтения файлов из ядра, анализирует ее, и добавляет файлы в кеш, если их использование частое;

• Данные директории могут быть другими, и настраиваются в конфигрурационных файлах.

• При чтении файла проверяется, содержит ли он указанный хеш в расширенных атрибутах xattr. Если содержит — открывается «общий» файл, вместо файла контейнера. Данная подмена происходит незаметно для кода контейнера, и скрывается в ядре;

• При записи в файл, хеш инвалидируется. Таким образом, при последующем открытии будет открываться уже непосредственно файл контейнера, а не его кеш.

Держа в страничном кеше общие файлы из /vz/pfcache мы добиваемся экономии этого самого кеша, а также экономии IOPS, Вместо чтения десяти файлов с диска, читаем один, который сразу идет в страничный кеш.

struct inode {
...
 struct file             *i_peer_file;
...
};
struct address_space {
...
 struct list_head        i_peer_list;
...
}

Список VMA для файла остается единым (дедуплицируем память) и с диска читаем реже (экономим iops). Наш «общак» размещен на SSD — дополнительный выигрыш в скорости.

Пример для кеширования файла /bin/bash:

[root@pcs13 ~]# ls -li /vz/root/2388/bin/bash
524650 -rwxr-xr-x 1 root root 1021112 Oct  7  2018 /vz/root/2388/bin/bash
[root@pcs13 ~]# pfcache dump /vz/root/2388 | grep 524650
8e3aa19fdc42e87659746f6dc8ea3af74ab30362 i:524650      g:1357611108  f:CP
[root@pcs13 ~]# sha1sum /vz/root/2388/bin/bash
8e3aa19fdc42e87659746f6dc8ea3af74ab30362  /vz/root/2388/bin/bash
[root@pcs13 /]# getfattr -ntrusted.pfcache /vz/root/2388/bin/bash
# file: vz/root/2388/bin/bash
trusted.pfcache="8e3aa19fdc42e87659746f6dc8ea3af74ab30362"
[root@pcs13 ~]# sha1sum /vz/pfcache/8e/3aa19fdc42e87659746f6dc8ea3af74ab30362
8e3aa19fdc42e87659746f6dc8ea3af74ab30362  /vz/pfcache/8e/3aa19fdc42e87659746f6dc8ea3af74ab30362

Эффективность использования вычисляем готовым скриптом.

Данный скрипт проходит по всем контейнерам на ноде, высчитывая закешированные файлы, каждого контейнера.

[root@pcs16 ~]# /pcs/distr/pfcache-examine.pl
...
Pfcache cache uses 831 MB of memory
Total use of pfcached files in containers is 39837 MB of memory
Pfcache effectiveness: 39006 MB

Таким образом, по памяти экономим порядка 40 гигабайт файлов в контейнерах, они будут загружаться из кеша.

Чтобы данный механизм работал еще лучше необходимо размещать на ноде максимально «одинаковые» VPS. Например, те, на которые, у пользователя нет root-доступа и на которых настроено окружение из развернутого образа.

Тюнить работу pfcache можно через конфиг файл
/etc/vz/pfcache.conf

MINSIZE, MAXSIZE — минимальный/максимальный размер файла для кеширования
TIMEOUT — таймаут между попытками кеширования

С полным списком параметров можно ознакомится по ссылке.

© Habrahabr.ru