# GeeseFS ## Задача Есть несколько серверов (2-4), на каждом запущено несколько сервисов. Сервисы работают только с файловой системой. Необходимо создать папку, которая будет синхронизироваться с такой же папкой на другой машине. Таким образом каждый экземпляр сервиса будет иметь доступ ко всем файлам на чтение или запись, вне зависимости от того, на каком сервере они созданы. Для решения было предложено использовать единый S3-бакет, смонтированный локально на каждой ВМ. В качестве драйвера была выбрана GeeseFS. ## Стенд Для проверки работоспособности был создан бакет `geesefs-test` и собран стенд из 2х ВМ вида IceLake 2vCPU, 2Gb, network-hdd 15Gb с установленной geesefs: ```bash ubuntu@test1:~$ geesefs --version geesefs version 0.34.1 ``` Написаны 2 скрипта, имитирующих, насколько это возможно, работу сервисов. Все скрипты при тестах запускались максимально одновременно. ## Тестирование Монтирование с дефолтными параметрами показало, что процесс GeeseFS был убит OOM. Так же имела место быть "рассинхронизация" - количество файлов созданных одной ВМ не совпадало с количеством этих файлов на "реплике". В итоге бакет был смонтирован с параметрами: ``` geesefs-test /opt/backet fuse.geesefs _netdev,allow_other,--file-mode=0666,--dir-mode=0777,--max-flushers=64,--max-parallel-parts=16,--max-parallel-copy=32,--stat-cache-ttl=10s,--memory-limit=512 0 0 ``` По результатам тестирования рассинхронизация минимальна, скорость работы удовлетворительная. После 10+ запусков script1 geesefs была убита OOM. После перезагрузки ВМ бакет был смонтирован с параметрами: ``` geesefs-test /opt/backet fuse.geesefs _netdev,allow_other,--file-mode=0666,--dir-mode=0777,--max-flushers=64,--max-parallel-parts=16,--max-parallel-copy=32,--stat-cache-ttl=10s,--memory-limit=256 0 0 ``` Однократный запуск script1 прошел нормально. Потом был запущен script2. Приблизительно через 12 часов работы на одной из машин geesefs "упал". Сам процесс был в памяти, выполнялся, но любое обращение к точке монтирования зависало. Даже простейшая команда: ```ls -l /opt/backet/``` не могла быть выполнена, так как "зависала". При этом в остальном ВМ находилась в норме. В syslog было обнаружено следующее: ![](https://i.imgur.com/xXbup8r.jpg) --- ## Скрипты **script1:** ```bash #!/bin/bash PID=$$ for i in $(seq 1 5000); do count=$(openssl rand -hex 10 | sed 's/[a,b,c,d,e.f]//g') count=$(echo ${count:0:3} | sed 's/^0*//') fn=$(echo "$(date +%d_%H_%M_%S)-$(hostname)") # echo "$PID: $fn $count" # echo "$fn $PID $(hostname)" > /opt/backet/$fn (dd if=/dev/urandom bs=512 count=$(($count*2)) of=/opt/backet/$fn status=none && \ cat /opt/backet/$fn >> /dev/null)& p_count=$(ps ax | grep dd | grep -v grep | wc -l) while [ $p_count -ge 20 ] do p_count=$(ps ax | grep dd | grep -v grep | wc -l) if [ "$(date +%M)" != "$m" ]; then my_f=$(ls /opt/backet/ | grep $(hostname) | wc -l) al_f=$(ls /opt/backet/ | grep -v $(hostname) | wc -l) echo "$(date +%H:%M:%S): my_files: $my_f synced_files: $al_f" m=$(date +%M) fi sleep 1 done done echo "################## All started ###################" ``` --- **script2:** ```bash #!/bin/bash PID=$$ for i in $(seq 1 5000); do count=$(openssl rand -hex 10 | sed 's/[a,b,c,d,e.f]//g') count=$(echo ${count:0:3} | sed 's/^0*//') if [ -z $count ]; then count=1 fi fn=$(echo "$(date +%d_%H_%M_%S)-$(hostname)") # echo "$PID: $fn $count" # echo "$fn $PID $(hostname)" > /opt/backet/$fn (fio --filename=/opt/backet/$fn --output=./report.log --direct=1 --rw=randrw --bs=1k --ioengine=libaio --iodepth=256 --runtime=20 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1 --size=$(($count*1024)) 2>1 1>/dev/null)& p_count=$(ps ax | grep fio | grep -v grep | wc -l) while [ $p_count -ge 5 ] do p_count=$(ps ax | grep fio | grep -v grep | wc -l) if [ "$(date +%M)" != "$m" ]; then my_f=$(ls /opt/backet/ | grep $(hostname) | wc -l) al_f=$(ls /opt/backet/ | grep -v $(hostname) | wc -l) echo "$(date +%H:%M:%S): my_files: $my_f synced_files: $al_f" m=$(date +%M) fi sleep 1 done done echo "################## All started ###################" ```