Arquivos no banco o que fazer?




    Diogo Biazus <diogob em gmail.com>
Arquivos no banco o que fazer?

                   Arquivos podem fazer
                    parte de um modelo de
                    banco de dados.
                   Não entre em pânico.
                   Temos opções:
                       Bytea
                       LO
                       Sistema de arquivos
As opções do PostgreSQL

   Bytea:
       Campo normal, array de bytes com tamanho
        variável.
   LO (Large Object):
       Armazena na tabela apenas um OID.
       Usa a pg_largeobject para armazenar o arquivo em
        várias linhas com bytea.
   Sistema de arquivos:
       Gravamos apenas o caminho no sistema de
        arquivos.
Critérios para seleção
(ou: não deixe a sorte escolher)
                     Pense um pouco, o
                      que você quer?
                         Compatibilidade com
                          cliente.
                         Facilidade de
                          gerenciamento.
                         Segurança.
                         Escala.
                         Performance.
Compatibilidade com cliente

   Bytea:
       Total, é um campo como qualquer um.
       Só precisamos usar a codificação do bytea.
       INSERT INTO tabela VALUES ('arquivo com byte
        zero (000) no conteudo');
Compatibilidade com cliente

   LO:
       Muitos: npgsql, PyGreS, JDBC, PDO, ...
       Mas nem todos: psycopg2.
       Usamos chamadas especiais:
            lo_create
            lo_write
            lo_read
Compatibilidade com cliente

   Sistema de arquivos
       Nenhum (se virem programadores)
       NFS, SMB, HTTP existem para isso.
       + trabalhoso.
Até agora ...

   Bytea 2 x LO 1 x SA 0
Facilidade de gerenciamento

   Bytea
       Muito fácil.
       Na verdade é exatamente igual a qualquer outro
        campo.
       Apenas cria um certo desconforto ao usar o
        ”SELECT * ...”, cuidado com consultas desse tipo.
       Integridade e backup não precisam de nenhum
        cuidado extra.
Facilidade de gerenciamento

   LO
       Fácil.
       Backup e não precisa de cuidados extra.
       Integridade pode gerar orfãos.
       Cuidados especiais:
            DELETE e DROP podem criar LOs orfãos.
            Use gatilhos com lo_unlink.
            Em último caso DELETE FROM pg_largeobject ...
Facilidade de gerenciamento

   Sistema de arquivos
       Nem um pouco fácil.
       Backup precisa de rotina para buscar arquivos e
        salvar uma cópia.
       Integridade não existe, precisamos implementar
        gatilhos para tudo.
       DELETE e DROP não liberam espaço sem um
        gatilho.
Bytea continua na frente

   Bytea 4 x LO 2 x SA 0
Segurança

   Bytea e LO
       Aproveita todos os mecanismos do banco de
        restrição de acesso.
   Sistema de arquivos
       Dificulta a implementação de restrições de acesso,
        pois passa a ser responsabilidade do desenvolvedor
        cuidar das permissões no SA.
Escala

            Muito bonito, mas
             será que agüenta o
             tranco?
Escala

   Bytea
       Limite de 1 GB por arquivo.
       Operações só gravam ou lêem arquivos inteiros.
       SELECT * é um desastre.
       Consome bastante memória no cliente.
       Não é bom para arquivos muito grandes.
Escala

   LO
       Limite de 2 GB por arquivo.
       Operações são orientadas a fluxo de dados.
       Ótimo para arquivos muito grandes.
Escala

   Sistema de arquivos
       Limitação de tamanho depende do sistema de
        arquivos subjacente, mas é muito superior aos
        outros.
       Operações podem ser feitas diretamente sobre o
        arquivo.
       Ótimo para arquivos muito grandes.
Os adversários se recuperam

   Bytea 4 x LO 3 x SA 2
Performance

   Ambiente de testes
       Cliente (Core 2 Duo, 1 GB RAM, SATA 2)
       Servidor (Pentium D, 1GB RAM, SATA 2)
       SO Ubuntu 7.10
       Sistema de arquivos: ext3
       Sistema de arquivos distribuído: NFS
       Rede 100 Mbps
Performance

   postgresql.conf
       shared_buffers = 300MB
       work_mem = 10MB
       max_fsm_pages = 204800
       wal_buffers = 512kB
       checkpoint_segments = 13
       checkpoint_timeout = 35min
       effective_cache_size = 400MB
Performance

   Testes:
       Inserção – Inserção com INSERT de 1.1 GB em
        aprox. 2700 arquivos.
       Consulta – 20 execuções de SELECTs com ORDER
        BY random() e LIMIT 50 em 10 clientes concorrentes.
        Copiando um total de aprox. 700 MB do servidor.
       Exclusão – Exclusão de todos arquivos do banco
        (considerando o unlink para LO e rm para o SA).
       Arquivos variando de poucos KB até 30 MB.
Performance

                      Inserção   Consulta Exclusão
Bytea                 00:24:10 00:31:50    00:01:56
LO                    00:05:16 00:03:38    00:02:17
Sistema de arquivos   00:02:29 00:05:24    00:00:34
Performance

   Bytea
       Muita carga na máquina do cliente.
       Load no cliente chegou a 24 na consulta.
       Uso de memória e CPU altos no cliente.
       Servidor ocioso durante todos os testes exceto o de
        exclusão, mas com grande consumo de memória.
Performance

   LO
       Consumo de recursos muito inferior no cliente.
       Usa mais recursos de CPU no servidor.
       Mesmo assim o servidor continuou ocioso na
        inserção.
       Carga do servidor chegou a 4 nas consultas.
Performance

   Sistema de arquivos
       Baixo consumo de recursos no cliente.
       Trabalho sujo é feito pelo sistema NFS.
       Baixo uso de CPU.
       Servidor ocioso na inserção.
       Carga chegou a 3 nas consultas.
E finalmente o vencedor ...

   Considerando todos os aspectos, a resposta que
    todos aguardam é...
Temos um empate senhoras e
senhores
   Quase enganei vocês, como sempre a resposta
    certa em TI é: depende.
Isso eu já sabia

   Alguém pode perguntar:
       Se é para ver essa conclusão porque assistimos
        essa palestra?
   Eu responderia:
       É importante conhecer bem as opções e saber
        quando e onde cada uma pode ser a estratégia
        vencedora!
Considerações finais

   Você quer armazenar a foto do cliente?
       Considere usar o tipo bytea.
   Ou talvez grandes conjuntos de áudio
    compactado?
       LO pode ser mais adequado.
   Arquivos com mais de 2 GB?
       Sistema de arquivos é o caminho.
The End




          Muito Obrigado!

Arquivos No Banco

  • 1.
    Arquivos no bancoo que fazer? Diogo Biazus <diogob em gmail.com>
  • 2.
    Arquivos no bancoo que fazer?  Arquivos podem fazer parte de um modelo de banco de dados.  Não entre em pânico.  Temos opções:  Bytea  LO  Sistema de arquivos
  • 3.
    As opções doPostgreSQL  Bytea:  Campo normal, array de bytes com tamanho variável.  LO (Large Object):  Armazena na tabela apenas um OID.  Usa a pg_largeobject para armazenar o arquivo em várias linhas com bytea.  Sistema de arquivos:  Gravamos apenas o caminho no sistema de arquivos.
  • 4.
    Critérios para seleção (ou:não deixe a sorte escolher)  Pense um pouco, o que você quer?  Compatibilidade com cliente.  Facilidade de gerenciamento.  Segurança.  Escala.  Performance.
  • 5.
    Compatibilidade com cliente  Bytea:  Total, é um campo como qualquer um.  Só precisamos usar a codificação do bytea.  INSERT INTO tabela VALUES ('arquivo com byte zero (000) no conteudo');
  • 6.
    Compatibilidade com cliente  LO:  Muitos: npgsql, PyGreS, JDBC, PDO, ...  Mas nem todos: psycopg2.  Usamos chamadas especiais:  lo_create  lo_write  lo_read
  • 7.
    Compatibilidade com cliente  Sistema de arquivos  Nenhum (se virem programadores)  NFS, SMB, HTTP existem para isso.  + trabalhoso.
  • 8.
    Até agora ...  Bytea 2 x LO 1 x SA 0
  • 9.
    Facilidade de gerenciamento  Bytea  Muito fácil.  Na verdade é exatamente igual a qualquer outro campo.  Apenas cria um certo desconforto ao usar o ”SELECT * ...”, cuidado com consultas desse tipo.  Integridade e backup não precisam de nenhum cuidado extra.
  • 10.
    Facilidade de gerenciamento  LO  Fácil.  Backup e não precisa de cuidados extra.  Integridade pode gerar orfãos.  Cuidados especiais:  DELETE e DROP podem criar LOs orfãos.  Use gatilhos com lo_unlink.  Em último caso DELETE FROM pg_largeobject ...
  • 11.
    Facilidade de gerenciamento  Sistema de arquivos  Nem um pouco fácil.  Backup precisa de rotina para buscar arquivos e salvar uma cópia.  Integridade não existe, precisamos implementar gatilhos para tudo.  DELETE e DROP não liberam espaço sem um gatilho.
  • 12.
    Bytea continua nafrente  Bytea 4 x LO 2 x SA 0
  • 13.
    Segurança  Bytea e LO  Aproveita todos os mecanismos do banco de restrição de acesso.  Sistema de arquivos  Dificulta a implementação de restrições de acesso, pois passa a ser responsabilidade do desenvolvedor cuidar das permissões no SA.
  • 14.
    Escala  Muito bonito, mas será que agüenta o tranco?
  • 15.
    Escala  Bytea  Limite de 1 GB por arquivo.  Operações só gravam ou lêem arquivos inteiros.  SELECT * é um desastre.  Consome bastante memória no cliente.  Não é bom para arquivos muito grandes.
  • 16.
    Escala  LO  Limite de 2 GB por arquivo.  Operações são orientadas a fluxo de dados.  Ótimo para arquivos muito grandes.
  • 17.
    Escala  Sistema de arquivos  Limitação de tamanho depende do sistema de arquivos subjacente, mas é muito superior aos outros.  Operações podem ser feitas diretamente sobre o arquivo.  Ótimo para arquivos muito grandes.
  • 18.
    Os adversários serecuperam  Bytea 4 x LO 3 x SA 2
  • 19.
    Performance  Ambiente de testes  Cliente (Core 2 Duo, 1 GB RAM, SATA 2)  Servidor (Pentium D, 1GB RAM, SATA 2)  SO Ubuntu 7.10  Sistema de arquivos: ext3  Sistema de arquivos distribuído: NFS  Rede 100 Mbps
  • 20.
    Performance  postgresql.conf  shared_buffers = 300MB  work_mem = 10MB  max_fsm_pages = 204800  wal_buffers = 512kB  checkpoint_segments = 13  checkpoint_timeout = 35min  effective_cache_size = 400MB
  • 21.
    Performance  Testes:  Inserção – Inserção com INSERT de 1.1 GB em aprox. 2700 arquivos.  Consulta – 20 execuções de SELECTs com ORDER BY random() e LIMIT 50 em 10 clientes concorrentes. Copiando um total de aprox. 700 MB do servidor.  Exclusão – Exclusão de todos arquivos do banco (considerando o unlink para LO e rm para o SA).  Arquivos variando de poucos KB até 30 MB.
  • 22.
    Performance Inserção Consulta Exclusão Bytea 00:24:10 00:31:50 00:01:56 LO 00:05:16 00:03:38 00:02:17 Sistema de arquivos 00:02:29 00:05:24 00:00:34
  • 23.
    Performance  Bytea  Muita carga na máquina do cliente.  Load no cliente chegou a 24 na consulta.  Uso de memória e CPU altos no cliente.  Servidor ocioso durante todos os testes exceto o de exclusão, mas com grande consumo de memória.
  • 24.
    Performance  LO  Consumo de recursos muito inferior no cliente.  Usa mais recursos de CPU no servidor.  Mesmo assim o servidor continuou ocioso na inserção.  Carga do servidor chegou a 4 nas consultas.
  • 25.
    Performance  Sistema de arquivos  Baixo consumo de recursos no cliente.  Trabalho sujo é feito pelo sistema NFS.  Baixo uso de CPU.  Servidor ocioso na inserção.  Carga chegou a 3 nas consultas.
  • 26.
    E finalmente ovencedor ...  Considerando todos os aspectos, a resposta que todos aguardam é...
  • 27.
    Temos um empatesenhoras e senhores  Quase enganei vocês, como sempre a resposta certa em TI é: depende.
  • 28.
    Isso eu jásabia  Alguém pode perguntar:  Se é para ver essa conclusão porque assistimos essa palestra?  Eu responderia:  É importante conhecer bem as opções e saber quando e onde cada uma pode ser a estratégia vencedora!
  • 29.
    Considerações finais  Você quer armazenar a foto do cliente?  Considere usar o tipo bytea.  Ou talvez grandes conjuntos de áudio compactado?  LO pode ser mais adequado.  Arquivos com mais de 2 GB?  Sistema de arquivos é o caminho.
  • 30.
    The End Muito Obrigado!