Perguntas da entrevista distribuída (1): Bloqueio distribuído

Q:
Bloqueio distribuído
1. Em um ambiente de sistema distribuído, um método só pode ser executado por um thread de uma máquina ao mesmo tempo
2. Aquisição de bloqueio altamente disponível e bloqueio de liberação
3. Aquisição de bloqueio de alto desempenho e bloqueio de liberação
4. Com reentrante recursos (pode ser entendido como reentrada, uso simultâneo por mais de uma tarefa sem se preocupar com erros de dados)
5. Com mecanismo de falha de bloqueio para evitar deadlock
6. Com recurso de bloqueio sem bloqueio, ou seja, o bloqueio não será adquirido Retorne diretamente para a falha em adquirir o bloqueio

P:
Bloqueio distribuído com base no zookeeper
1. Alguns recursos do zookeeper

Nó ordenado: Se o nó pai atual for / lock, podemos criar um nó filho sob este nó pai; o zookeeper fornece um recurso opcional ordenado, por exemplo, podemos criar um nó filho "/ lock / node-" e Especificar ordem, então o zookeeper adicionará automaticamente um número de série inteiro de acordo com o número atual de nós filhos ao gerar nós filhos, ou seja, se for o primeiro nó filho criado, então o nó filho gerado é / lock / node-0000000000, próximo Um nó é / lock / node-0000000001 e assim por diante.

Nó temporário: O cliente pode estabelecer um nó temporário. Zookeeper irá deletar automaticamente o nó após o término da sessão ou a sessão expirar.

Monitoramento de eventos: Ao ler os dados, podemos definir o monitoramento de eventos para o nó ao mesmo tempo. Quando os dados ou a estrutura do nó mudarem, o zookeeper notificará o cliente. Atualmente zookeeper tem os seguintes quatro eventos:
1. Criação de nó;
2. Exclusão de nó;
3. Modificação de dados de nó;
4. Alteração de nó filho.

2. Realize
① O cliente se conecta ao zookeeper e cria nós filhos temporários e ordenados em / lock.O primeiro cliente corresponde ao nó filho / lock / lock-1, e o segundo é / lock / lock- 2, e assim por diante.
②O cliente obtém a lista de nós filhos em / bloqueio e avalia se o nó filho criado é o nó filho com o menor número de sequência na lista de nós filhos atuais. Se for, é considerado bloqueado, caso contrário, monitora o mensagem de mudança de nó filho de / bloquear e obter o nó filho. Após a notificação de mudança de nó, repita esta etapa até que o bloqueio seja obtido;
③ Execute o código de negócios;
④Após concluir o processo de negócios, exclua o nó filho correspondente para liberar o bloqueio.

P:
Implementação de bloqueio distribuído zookeeper com base no curador

public static void main(String[] args) throws Exception {
    
    
        //创建zookeeper的客户端
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);

        CuratorFramework client = CuratorFrameworkFactory.newClient("10.21.41.181:2181,10.21.42.47:2181,10.21.49.252:2181", retryPolicy);

        client.start();

        //创建分布式锁, 锁空间的根节点路径为/curator/lock
        InterProcessMutex mutex = new InterProcessMutex(client, "/curator/lock");

        mutex.acquire();

        //获得了锁, 进行业务流程
        System.out.println("Enter mutex");

        //完成业务流程, 释放锁
        mutex.release();

        //关闭客户端
        client.close();

    }

Q: Bloqueio
distribuído baseado em Redis
1. Processo
1. Para obter o bloqueio, o Serviço A inicia o seguinte comando para Redis: SET productId: lock 0xx9p03001 NX PX 30000 Entre eles, "productId" é definido por si mesmo e pode ser relacionado a este id de negócio, "0xx9p03001" é uma string de valores aleatórios, que deve ser globalmente exclusivo (o motivo será mencionado mais tarde), "NX" refere-se a se e somente se a chave (ou seja, "productId: lock" em o caso) está no Redis Se não existir, a execução foi bem-sucedida, caso contrário, a execução falha. "PX 30000" significa que após 30 segundos, a chave será excluída automaticamente. O sucesso é retornado após a execução do comando, indicando que o serviço obteve o bloqueio com sucesso.
2. Para obter o bloqueio, o serviço B inicia o mesmo comando para o Redis: SET productId: lock 0000111 NX PX 30000 Como a chave com o mesmo nome já existe no Redis e não expirou, a execução do comando falha e o serviço B falha para obter o bloqueio. O serviço B entra no estado de solicitação cíclica, como enviar uma solicitação ao Redis a cada 1 segundo (definido por ele mesmo), até que a execução seja bem-sucedida e o bloqueio seja obtido.
3. O tempo de execução do código de negócios do serviço A excede 30 segundos, o que faz com que a chave atinja o tempo limite, então o Redis exclui a chave automaticamente. Nesse momento, o serviço B envia o comando novamente e é executado com sucesso, supondo que o valor definido nesta solicitação seja 0000222.
4. Após a conclusão da execução do serviço A, para liberar o bloqueio, o serviço A iniciará ativamente uma solicitação de exclusão de chave para o Redis.

2. Realize
① O
cliente de bloqueio integra o Redisson. Antes de bloquear, primeiro você precisa selecionar um Redis mestre no cluster por meio do algoritmo de hash. Os processos subsequentes de bloqueio e desbloqueio estão todos vinculados a este Redis mestre. Entre os nós escravos. ②Execute o
script lua para realizar o bloqueio.
③Watch dog estende automaticamente o
watch dog é um thread de segundo plano, ele observará se o cliente atual ainda mantém o bloqueio a cada 10 segundos, se ele segurar, o cliente ainda pode estar usando o bloqueio, então estenda o tempo de sobrevivência restante do bloqueio.
④Libere o mecanismo de bloqueio. Se lock.unlock () for executado, o Redis encontrará a estrutura de dados de teste acima e reduzirá o número de bloqueios em um. Se o número de bloqueios for 0 após a redução, significa que o cliente atual não possui mais o bloqueio, portanto, execute o comando del test para excluir esta chave do Redis.

// 准备为名为"test"的key加锁
RLock lock = redisson.getLock("test");
// 加锁
lock.lock();
// 解锁
lock.unlock();

A conta oficial deste blog: negócio do lado da rede Muzi, bem-vindo para prestar atenção à troca!

Acho que você gosta

Origin blog.csdn.net/ncw8080/article/details/113879257
Recomendado
Clasificación