Armazenamento de Sessões PHP no Conjunto de Memoriais com Tolerância a Falhas

5

Recentemente, tive a oportunidade de migrar um aplicativo da Web de um proxy "loadbalancer" do Nginx para um loadbalancer F5. Infelizmente, durante essa migração, ficou claro que o armazenamento de sessão memcached precisava ser movido do servidor proxy Nginx para "em algum lugar". Meu pensamento é que eu deveria colocar memcached em todos os 3 servidores da web (os servidores que ficam atrás da F5 em um pool) e usar php-memcache ou php-memcached para salvar as sessões. Aqui está o problema:

Eu tentei os dois php-memcache e php-memcached e nenhum deles pode se comportar corretamente se um dos servidores ficar inativo. Minha última tentativa foi com essa configuração:

memcached versão 2.2.0 com as definições de configuração:

session.save_handler = memcached
session.save_path    = "172.29.104.13:11211,172.29.104.14:11211"

Não tenho nada especial em memcached.ini que não seja extension=memcached.so .

Com esta configuração no servidor 1 e 2 (removi 3 temporariamente para testar), aponto o JMeter no VIP F5 e inicio o tráfego. Eu posso ver memcached.log (o daemon) em ambos os sistemas, embora não tenha gasto tempo para decifrar, começar a correr.

Então, se eu parar um dos daemons memcached , o tráfego começa a falhar e meu retorno é

session_start(): Write of lock failed

pelo memcached restante.

No final do dia, meu objetivo é simples - eu preciso ser capaz de a) não executar memcached em um único servidor (ponto único de falha), e o cluster precisa ser resiliente a uma falha de um membro do pool.

Eu também tentei php-memcache , mas ele também falha. Para php-memcache , a configuração é assim:

memcache versão 3.0.8 (beta) com as definições de configuração:

 
session.save_handler = memcache
session.save_path    = "tcp://172.29.104.13:11211, tcp://172.29.104.14:11211"

e em memcache.ini :

extension=memcache.so
[memcache]
memcache.dbpath="/var/lib/memcache"
memcache.maxreclevel=0
memcache.maxfiles=0
memcache.archivememlim=0
memcache.maxfilesize=0
memcache.maxratio=0
memcache.hash_strategy=consistent
memcache.allow_failover=1
memcache.session_redundancy=2

O erro aqui é simplesmente token de sessão inválido (implicando para mim que o servidor que permaneceu não tinha o token de sessão realmente armazenado, significando que a replicação de salvar a sessão não estava ativa).

Eu não olhei para colocar a persistência de sessão de volta na F5, embora como último recurso eu pudesse fazê-lo, e os clientes tentando se conectar ao membro perdido teriam que se autenticar novamente.

    
por Joe 15.08.2014 / 18:26

1 resposta

0

É muito mais simples ter os clientes armazenando o estado da sessão para você em cookies. Isso significa que não há armazenamento de sessão em todos os servidores, apenas alguns microssegundos de uso da CPU para descriptografar o & verifique o cookie. Como a CPU é, de longe, o recurso mais abundante em um datacenter, esse esquema terá um desempenho muito melhor do que uma consulta a partir do memcached ou de qualquer outro armazenamento de sessão do servidor.

Veja link para uma implementação, há muitos outros por aí. Observe que os dados da sessão devem ser criptografados, mas devem ser autenticados via HMAC ou uma criptografia AEAD. Não escreva este código você mesmo, a menos que você seja um criptógrafo; use uma biblioteca criogênica bem avaliada.

O Facebook usa essa técnica para que qualquer servidor possa responder a qualquer solicitação do usuário, mesmo que a sessão do usuário tenha começado em outro datacenter.

    
por 15.08.2014 / 18:50