Distribuído Bloqueio de serviço sobre MySql / GigaSpaces / Netapp [fechado]
-
21-08-2019 - |
Pergunta
Aviso : Eu já pedi esta questão , mas sem a exigência de implantação. Eu tenho um responder que tem 3 upvotes, e quando eu editada a questão para incluir o requisito de implantação, a resposta em seguida tornou-se irrelevante. A razão que eu sou reenviar é porque SO considera à pergunta original 'respondeu', mesmo embora eu não tenho significativa upvoted responda. Abri um uservoice submissão sobre este problema. A razão que eu anunciado é tão StackOverflow considerar a pergunta original respondeu, de modo que não aparecem na guia 'perguntas não respondidas'.
Qual o serviço de bloqueio distribuído você usaria?
Os requisitos são:
- A exclusão mútua (bloqueio), que pode ser visto a partir de diferentes processos / máquinas
- Bloqueio ... semântica libertação
- liberação automática de bloqueio depois de um certo tempo de espera - se morre titular de bloqueio, ele será automaticamente liberada após X segundos
- implementação Java
- implantação Fácil - não deve exigir a implantação complicado para além quer Netapp, MySql ou GigaSpaces. Deve jogar bem com esses produtos (especialmente GigaSpaces - é por isso terracota foi descartada).
- É bom ter: implementação .Net
- Se é grátis: Impasse detecção / mitigação
Eu não estou interessado em respostas como "isso pode ser feito ao longo de um banco de dados", ou "isso pode ser feito ao longo JavaSpaces" - Eu sei. respostas relevantes deve conter apenas um, out-of-the-box, implementação pronto comprovada.
Solução
Aqui está o esboço de uma resposta baseada GigaSpaces que atende aos seus critérios, dependendo exatamente o que você quer dizer em critérios 3. Eu trabalho com GigaSpaces de .Net, não Java:
Crie uma classe de travamento com uma propriedade SpaceID + SpaceRouting Iding o que está bloqueado e uma propriedade DataMember bool Desbloqueado:
sealed public class IdLockTrans
{
[SpaceID]
[SpaceRouting]
public string ID
{
get;
set;
}
[DataMember]
public bool Unlocked
{
get;
set;
}
public IdLockTrans(Id id)
{
ID = id.ID;
}
public IdLockTrans()
{
}
}
Você vai usar tempo de concessão GigaSpaces' para o desbloqueio depois de um certo tempo esgotado. Isso fará com que GigaSpaces para remover objetos IdLockTrans a partir do espaço automaticamente depois de terem sido ocioso para o tempo limite período. A falta de um IdLockTrans para um ID significa que o ID é desbloqueado.
Sua classe armário vai definir e inicializar esses membros da classe
private readonly ISpaceProxy _proxy;
private readonly long _leaseTime;
public override bool Lock(Id id, long timeout)
{
bool locked;
IdLockTrans lockTransTemplate = new IdLockTrans(id);
// Assume that this is a new id.
try
{
_proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly);
locked = true;
}
catch (EntryAlreadyInSpaceException)
{
using (ITransaction tx = _proxy.CreateLocalTransaction())
{
try
{
lockTransTemplate.Unlocked = true;
IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout);
locked = (lockTrans != null);
if (lockTrans != null)
{
lockTrans.Unlocked = false;
_proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly);
}
tx.Commit();
}
catch
{
tx.Abort();
throw;
}
}
}
return locked;
}
public override void Unlock(Id lockedId)
{
IdLockTrans lockTrans = new IdLockTrans(lockedId);
lockTrans.Unlocked = true;
try
{
_proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly);
}
catch (EntryNotInSpaceException)
{
throw new Exception("IdLockTrans for " + lockTrans.ID
+ " not found on Unlock. Lock time exceeded lease time.");
}
}
Outras dicas
A implementação Net é muito próximo a sair existente do bloqueio caixa / API desbloqueio fornecido com a API Java. Vejo: http://www.gigaspaces.com/docs/JavaDoc8 0,0 / org / openspaces / core / DefaultGigaMap.html
Você pode encontrei o código fonte para esta classe Java como parte do arquivo gs-openspaces-src.zip fornecido com o produto. Tendo o mesmo com GigaSpaces .Net API deve ser straightfwd.
No caso de você ainda está procurando, dê uma olhada Apache Zookeeper :
ZooKeeper é um serviço centralizado para manter as informações de configuração, nomeando, proporcionando sincronização distribuída, e prestação de serviços do grupo. Todos esses tipos de serviços são utilizados de alguma forma ou de outra por aplicações distribuídas.
A documentação Zookeeper fornece exemplos de como construir um serviço de bloqueio no topo do Zookeeper.
Use mysql para bloquear uma chave única é muito simples.
Assunção 1:
Você usa transação e seu nível de isolamento é lido comprometido.
Hipótese 2: Você trancá-lo processando fio por uma chave única, e liberá-lo quando a sua transação confirmada.
Em seguida, você pode usar este sql como distribuir lock:
Inserir em distributed_lock (key) valores (# {key}) Tecla ON DUPLICATE KEY update = chave;