O SQLite pode ser usado com o GlusterFS?

6

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?

    
por math 05.09.2009 / 01:05

4 respostas

3

O GlusterFS suporta bloqueio de arquivo / registro POSIX completo, mesmo no modo de replicação. Deve funcionar bem.

    
por 24.09.2009 / 17:57
6

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:

  • GlusterFS 3.2 e sqlite3 3.5.9 (ubuntu 8.10). O DB não foi corrompido.
  • GlusterFS 3.2 e sqlite3 3.6.22-1 (Ubuntu 10.04). TBD.
  • Ext3 e sqlite3 3.5.9 (Ubuntu 8.10): O teste foi executado a partir de duas janelas de terminal de uma só vez. O teste terminou sem nenhum problema.

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.

    
por 14.06.2011 / 18:45
1

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.

    
por 05.09.2009 / 01:56
1

Você terá problemas de bloqueio em que (com efeito) um cliente por vez pode gravar no arquivo.

    
por 05.09.2009 / 01:59