O GlusterFS suporta bloqueio de arquivo / registro POSIX completo, mesmo no modo de replicação. Deve funcionar bem.
Eu quero construir um armazenamento distribuído baseado no GlusterFS com o Automatic Replication (AFR) para armazenar arquivos de usuários de uma maneira tolerante a falhas.
Mas eu também quero acessar um banco de dados SQLite3 armazenado no volume GlusterFS (e assim replicado em vários servidores) de múltiplos clientes. É possível? A concordância entre os vários clientes será bem tratada e não levará à corrupção?
Ou existe uma alternativa melhor ao GlusterFS para distribuir o banco de dados SQLite3?
Eu escrevi um script sqlite_shared_fs_check.sh para simular muitas leituras e gravações no banco de dados sqlite3. Ele deve rodar no mesmo diretório do GlusterFS em várias máquinas clientes.
Eu testei seguindo as configurações:
Os resultados do último teste (ext3 + sqlite3) colocam a culpa na não-conformidade de bloqueio POSIX no GlusterFS 3.2.
Aqui está o script que usei para fazer o teste:
#!/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
Note que eu tive que usar o utilitário lockfile-create para adquirir o bloqueio no banco de dados, já que o bloqueio interno do sqlite não é confiável o suficiente.
Eu acho que o bloqueio pode ser a parte mais difícil disso. Imagine que o processo de gravação tenha que bloquear o banco de dados sqlite3 (arquivo) quando estiver escrevendo nele. A questão é qual o nível de concorrência que você precisa? Acho que você vai enfrentar possíveis problemas de desempenho com um aplicativo vinculado à gravação.
Você terá problemas de bloqueio em que (com efeito) um cliente por vez pode gravar no arquivo.
Tags sqlite high-availability