Я хочу создать распределенное хранилище на базе GlusterFS с автоматической репликацией файлов (AFR) для отказоустойчивого хранения файлов пользователей.
Но я также хочу получить доступ к базе данных SQLite3, хранящейся на томе GlusterFS (и, следовательно, реплицированной на нескольких серверах) от нескольких клиентов. Является ли это возможным? Будет ли согласованность между несколькими клиентами правильно обработана и не приведет ли к коррупции?
Или есть лучшая альтернатива GlusterFS для распространения базы данных SQLite3?
Я написал sqlite_shared_fs_check.sh скрипт для имитации множества операций чтения и записи в базу данных sqlite3. Предполагается, что он будет работать в одном каталоге GlusterFS на нескольких клиентских машинах.
Я протестировал следующие конфигурации:
Результаты последнего теста (ext3 + sqlite3) возложили ответственность за несоответствие блокировки POSIX на GlusterFS 3.2.
Вот сценарий, который я использовал для тестирования:
#!/bin/bash
function ErrorExit()
{
echo Error: $@
exit 1
}
# Microseconds
timeout=5000
if [ ! -f test.sqlite3 ];
then
touch test.sqlite3
echo 'create table test1 (id integer primary key autoincrement,datetime text,hostname text);' | sqlite3 test.sqlite3 || ErrorExit "Create"
fi
if [ ! -f /tmp/insert.sql ];
then
echo .timeout $timeout > /tmp/insert.sql
echo "insert into test1 values (NULL,datetime('now','localtime'),'$HOSTNAME');" >> /tmp/insert.sql
fi
if [ ! -f select.sql ];
then
echo .timeout $timeout > select.sql
echo "select * from test1 order by id desc limit 1;" >> select.sql
fi
if [ ! -f count.sql ];
then
echo .timeout $timeout > count.sql
echo "select count(*) from test1;" >> count.sql
fi
i=1
while [ $i -le 1000 ];
do
lockfile-create --retry 20 test.sqlite3 || echo -n "?"
sqlite3 test.sqlite3 < /tmp/insert.sql
lockfile-remove test.sqlite3
# Sleep a bit to allow other users
sleep 0.5
lockfile-create --retry 20 test.sqlite3 || echo -n "?"
sqlite3 test.sqlite3 < select.sql >/dev/null || ErrorExit select [$i]
sqlite3 test.sqlite3 < count.sql >/dev/null || ErrorExit count [$i]
lockfile-remove test.sqlite3
let i++
echo -n "."
done
Обратите внимание, что мне пришлось использовать утилиту lockfile-create, чтобы получить блокировку базы данных, так как внутренняя блокировка sqlite недостаточно надежна.
GlusterFS поддерживает полную блокировку уровня файлов / записей POSIX даже в режиме репликации. Должно работать нормально.
Я думаю, что блокировка может быть самой сложной частью этого. Представьте, что процесс записи должен блокировать базу данных (файл) sqlite3 при записи в нее. Вопрос в том, какой уровень параллелизма вам нужен? Я думаю, вы столкнетесь с возможными проблемами производительности с приложением, привязанным к записи.
У вас будут проблемы с блокировкой, когда (фактически) один клиент за раз может записывать в файл.