Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Melhor maneira de lidar com problemas de simultaneidade


A resposta de Donnie (enquete) é provavelmente sua melhor opção - simples e funciona. Ele cobrirá quase todos os casos (é improvável que uma simples pesquisa de PK prejudique o desempenho, mesmo em um site muito popular).

Para completar, e se você quiser evitar pesquisas, você pode usar um push-model . Existem várias maneiras descritas no artigo da Wikipedia. Se você puder manter um cache de gravação (toda vez que atualizar o registro, atualizará o cache), poderá eliminar quase completamente a carga do banco de dados.

No entanto, não use uma coluna "last_updated" de carimbo de data/hora. As edições no mesmo segundo não são inéditas. Você pode se safar disso se adicionar informações extras (servidor que fez a atualização, endereço remoto, porta etc.) para garantir que, se duas solicitações vierem no mesmo segundo, para o mesmo servidor, você possa detectar a diferença. Se você precisar dessa precisão, no entanto, você também pode usar um campo de revisão exclusivo (não precisa necessariamente ser um número inteiro incrementado, apenas exclusivo dentro da vida útil desse registro).

Alguém mencionou conexões persistentes - isso reduziria o custo de configuração das consultas de pesquisa (toda conexão consome recursos no banco de dados e na máquina host, naturalmente). Você manteria uma única conexão (ou a menor possível) aberta o tempo todo (ou o maior tempo possível) e a usaria (em combinação com armazenamento em cache e memoização, se desejado).

Finalmente, existem instruções SQL que permitem adicionar uma condição em UPDATE ou INSERT. Meu SQl está realmente enferrujado, mas acho que é algo como UPDATE ... WHERE ... . Para corresponder a esse nível de proteção, você teria que fazer seu próprio bloqueio de linha antes de enviar a atualização (e todo o tratamento de erros e limpeza que isso pode acarretar). É improvável que você precise disso; Estou apenas mencionando-o para completar.

Editar:

Sua solução parece boa (timestamps de cache, solicitações de pesquisa de proxy para outro servidor). A única mudança que eu faria é atualizar os timestamps em cache em cada salvamento. Isso manterá o cache mais atualizado. Eu também verificaria o carimbo de data/hora diretamente do banco de dados ao salvar para evitar que um salvamento se infiltrasse devido a dados de cache obsoletos.

Se você usa o APC para armazenamento em cache, um segundo servidor HTTP não faz sentido - você teria que executá-lo na mesma máquina (o APC usa memória compartilhada). A mesma máquina física faria o trabalho, mas com a sobrecarga adicional de um segundo servidor HTTP. Se você quiser descarregar as solicitações de pesquisa para um segundo servidor (lighttpd, no seu caso), seria melhor configurar lightttpd na frente do Apache em uma segunda máquina física e usar um servidor de cache compartilhado (memcache) para que o O servidor lighttpd pode ler os timestamps em cache e o Apache pode atualizar os timestamps em cache. A justificativa para colocar o lighttpd na frente do Apache é, se a maioria das solicitações forem solicitações de pesquisa, para evitar o uso de processos pesados ​​do Apache.

Você provavelmente não precisa de um segundo servidor, na verdade. O Apache deve ser capaz de lidar com as solicitações adicionais. Se não puder, eu revisitaria sua configuração (especificamente as diretivas que controlam quantos processos de trabalho você executa e quantas solicitações eles têm permissão para manipular antes de serem eliminados).