notas de estudo etcd

Autor: Chen Jinjian
blog pessoal: HTTPS: //jian1098.github.io
CSDN blog: https: //blog.csdn.net/c_jian
Jane book: https: //www.jianshu.com/u/8ba9ac5706b6
Contato: jian1098 @ qq.com

Sobre etcd

Introdução


etcdÉ um sistema de armazenamento de valor-chave distribuído de código aberto e altamente disponível, desenvolvido com a linguagem Go, que pode ser usado para configurar o compartilhamento e o registro e a descoberta de serviços.

Características


  • Replicação completa: cada nó do cluster pode usar o arquivo completo
  • Alta disponibilidade: Etcd pode ser usado para evitar pontos únicos de falha de hardware ou problemas de rede
  • Consistência: cada leitura retornará a gravação mais recente em vários hosts
  • Simples: inclui uma API bem definida e orientada ao usuário (gRPC)
  • Segurança: Implementado TLS automatizado com autenticação de certificado de cliente opcional
  • Rápido: velocidade de referência de 10.000 gravações por segundo
  • Confiável: o algoritmo Raft é usado para obter um catálogo de armazenamento de serviço altamente consistente e disponível

Grupo


Como um sistema de armazenamento de valores-chave de alta disponibilidade, o etcd é inerentemente projetado para clustering. Como o algoritmo Raft requer uma maioria de nós para votar ao tomar decisões, o etcd geralmente recomenda um número ímpar de nós para implantação de cluster, e o número recomendado é 3, 5 ou 7 nós para formar um cluster.

Descoberta de serviço


A descoberta de serviço visa resolver um dos problemas mais comuns em sistemas distribuídos, ou seja, como os processos ou serviços no mesmo cluster distribuído podem se encontrar e estabelecer uma conexão. Essencialmente, a descoberta de serviço é saber se há processos no cluster escutando nas portas udp ou tcp, e você pode localizar e conectar pelo nome. Para resolver o problema de descoberta de serviço, os três seguintes pilares são necessários, nenhum dos quais é indispensável

  • Catálogo de armazenamento de serviço altamente consistente e disponível. Etcd baseado no algoritmo Raft é um diretório de armazenamento de serviço altamente consistente e disponível.

  • Um mecanismo para registrar serviços e monitorar o estado de saúde dos serviços. Os usuários podem registrar serviços no etcd, definir os serviços registrados e key TTLmanter a pulsação do serviço regularmente para obter o efeito de monitorar o status de integridade.

  • Um mecanismo para localizar e conectar serviços. Os serviços registrados sob o assunto especificado por etcd (catálogo de serviços composto de nomes de serviços) também podem ser encontrados no assunto correspondente.

Componentes do núcleo

  • Servidor HTTP: usado para processar solicitações de API enviadas por usuários e solicitações de sincronização e informações de pulsação de outros nós etcd.

  • Armazenar: Usado para processar várias funções suportadas pelo etcd, incluindo indexação de dados, mudanças de status de nó, monitoramento e feedback, processamento e execução de eventos, etc. É a implementação específica da maioria das funções de API fornecidas pelos usuários pelo etcd.

  • Jangada: A implementação específica do algoritmo de consistência forte de Jangada é o núcleo do etcd.

  • WAL: O registro de gravação antecipada é o método de armazenamento de dados do etcd. Além de armazenar o estado de todos os dados na memória e o índice do nó, o etcd usa o WAL para armazenamento persistente. No WAL, todos os dados serão registrados antecipadamente antes do envio. Instantâneo é um instantâneo de estado obtido para evitar dados excessivos; a entrada representa o conteúdo de log específico armazenado.

Instale o etcd

A partir do https://github.com/etcd-io/etcd/releasesdownload da última versão, descompacte etcde descompacte etcdctldois programas (linux e windows iguais). Entre eles etcdestá o arquivo binário que executa o serviço etcd, que etcdctlé o cliente etcd da linha de comando oficial, que etcdctlpode ser usado para acessar o serviço etcd na linha de comando.

Para facilitar a operação, os dois arquivos podem ser adicionados à variável de ambiente do sistema por soft link

ln -fs /root/eosio/2.0/bin/etcd /usr/local/bin/etcd
ln -fs /root/eosio/2.0/bin/etcdctl /usr/local/bin/etcdctl

Ver versão

etcd --version

Inicie o etcd


etcd

Parâmetros opcionais:

-name Nome do nó, o padrão é UUID

-data-dir O diretório onde os logs e instantâneos são salvos, o padrão é o diretório de trabalho atual

-addrO endereço IP publicado e a porta. O padrão é 127.0.0.1:2379

-bind-addr O endereço de escuta usado para conexões de cliente, o padrão é a configuração -addr

-peers Uma lista separada por vírgulas de membros do cluster, por exemplo, 127.0.0.1:2380,127.0.0.1:2381

-peer-addr O endereço IP publicado da comunicação do serviço de cluster, o padrão é 127.0.0.1:2380.

-peer-bind-addr O endereço de escuta da comunicação do serviço de cluster, o padrão é a configuração -peer-addr

A configuração acima também pode definir o arquivo de configuração, o padrão éetcd目录/etcd.conf

Operações de biblioteca de valor-chave


写 (colocar)

etcdctl put name "hello world"	//新增和更新都是put

Ler (obter)

etcdctl get name

Consulta por prefixo

etcdctl get name --prefix	//查找前缀为name的

Excluir (del)

etcdctl del name

Transação (txn)

As transações no etcd são executadas atomicamente e suportam apenas expressões como if ... then ... else ...

//先赋值
etcdctl put user1 bad

//开启事务
etcdctl txn --interactive
compares:
// 输入以下内容,注意=号两边要有空格,输入结束按两次回车
value("user1") = "bad"      

//如果 user1 = bad,则执行 get user1 
success requests (get, put, del):
get user1

//如果 user1 != bad,则执行 put user1 good
failure requests (get, put, del):
put user1 good

// 运行结果,执行 success
SUCCESS

user1
bad

Assistir

// 当 stock1 的数值改变( put 方法)的时候,watch 会收到通知,在这之前进程会阻塞
$ etcdctl watch stock1

// 新打开终端etcd 多台服务器集群
$ export ETCDCTL_API=3
$ etcdctl put stock1 1000

//在watch 终端显示
PUT
stock1
1000

$ etcdctl watch stock --prefix
$ etcdctl put stock1 10
$ etcdctl put stock2 20

Alugar

O lease pode definir o tempo de expiração do acesso

$ etcdctl lease grant 300	//创建一个300秒的租约
# lease 326963a02758b527 granted with TTL(300s)

$ etcdctl put sample value -- lease=326963a02758b527	//写入操作时将租约id为326963a02758b527的租约分配给sample
OK

$ etcdctl get sample

$ etcdctl lease keep-alive 326963a02758b520	//续约
$ etcdctl lease revoke 326963a02758b527		//手动释放租约
lease 326963a02758b527 revoked

# or after 300 seconds							  //自动释放租约
$ etcdctl get sample

O lease oferece várias funções:

  • Concessão: Atribuir um contrato de arrendamento.
  • Revogar: Liberar um contrato de arrendamento.
  • TimeToLive: obtenha o tempo TTL restante.
  • Locações: liste todas as locações no etcd.
  • KeepAlive: Renove automaticamente um contrato de arrendamento em um horário fixo.
  • KeepAliveOnce: Renove uma concessão uma vez.
  • Fechar: Parece que está fechando todas as locações estabelecidas pelo cliente atual.

Bloqueio distribuído (bloqueio)

Bloqueio distribuído, quando uma pessoa opera, a outra só pode ver, mas não operar

# 第一终端
$ etcdctl lock mutex1
mutex1/326963a02758b52d

# 第二终端
$ etcdctl lock mutex1

# 当第一个终端结束了,第二个终端会显示
mutex1/326963a02758b53

Eleição

O nó de eleição é o líder, apenas o nó líder tem permissão de gravação e o nó comum só tem permissão de leitura para garantir a consistência dos dados; o nó líder enviará periodicamente batimentos cardíacos para os nós comuns, e o novo líder será eleito automaticamente quando os nós comuns não podem receber a pulsação

$ etcdctl elect one p1

one/326963a02758b539
p1

# another client with the same name blocks
$ etcdctl elect one p2

//结束第一终端,第二终端显示
one/326963a02758b53e
p2

Monitoramento de status de cluster (endpoint)

Verificação de integridade do cluster

$ etcdctl --write-out=table endpoint status

$ etcdctl endpoint health

Instantâneo

Usado para salvar instantâneos do banco de dados etcd

etcdctl snapshot save my.db

Snapshot saved at my.db

etcdctl --write-out=table snapshot status my.db

Gestão de membros do cluster (Membro)

Usado para visualizar, adicionar, excluir, atualizar membros

export ENDPOINTS=127.0.0.1:2379,127.0.0.1:2479,127.0.0.1:2579	//windows下export换成set
etcdctl member list -w table	//成员列表-w可省略
etcdctl --endpoints=$ENDPOINTS member remove b9057cfdc8ff17ce	//删除成员
etcdctl --endpoints=$ENDPOINTS member add cd3 --peer-urls=http://127.0.0.1:2180	//添加成员cd3为成员名

Iniciar novo nó

etcd --name cd3 --listen-client-urls http://127.0.0.1:2179 --advertise-client-urls http://127.0.0.1:2179 --listen-peer-urls http://127.0.0.1:2180 --initial-advertise-peer-urls http://127.0.0.1:2180 --initial-cluster-state existing --initial-cluster cd2=http://127.0.0.1:2580,cd0=http://127.0.0.1:2380,cd3=http://127.0.0.1:2180,cd1=http://127.0.0.1:2480 --initial-cluster-token etcd-cluster-1

Go language operation etcd

conexão

Baixe o pacote de driver

go get github.com/coreos/etcd/clientv3

Serviço de conexão

cli, err := clientv3.New(clientv3.Config{
    
    
   Endpoints:   []string{
    
    "localhost:2379"},
   // Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}
   DialTimeout: 5 * time.Second,
})

Leia e escreva

Escreva

O primeiro parâmetro é goroutineo contexto Contexte os próximos dois parâmetros são chave e valor.

kv := clientv3.NewKV(cli)
putResp, err := kv.Put(context.TODO(),"/test/key1", "Hello etcd!")	
// PutResp: &{cluster_id:14841639068965178418 member_id:10276657743932975437 revision:3 raft_term:7  <nil>}

Consulta geral

getResp, err := kv.Get(context.TODO(), "/test/key1")

Voltar à estrutura

type RangeResponse struct {
    
    
	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
	// kvs is the list of key-value pairs matched by the range request.
	// kvs is empty when count is requested.
	Kvs []*mvccpb.KeyValue `protobuf:"bytes,2,rep,name=kvs" json:"kvs,omitempty"`
	// more indicates if there are more keys to return in the requested range.
	More bool `protobuf:"varint,3,opt,name=more,proto3" json:"more,omitempty"`
	// count is set to the number of keys within the range when requested.
	Count int64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
}

O campo Kvs salva todos os pares kv encontrados neste Get. Como o exemplo acima só obtém uma única chave, você só precisa julgar se len (Kvs) é igual a 1 para saber se a chave existe.

Pesquisa por prefixo

rangeResp, err := kv.Get(context.TODO(), "/test/", clientv3.WithPrefix())

Consulta de paginação

RangeResponse.MoreE funcionará Countquando usarmos withLimit()outras opções para prosseguir Get, o que é equivalente à consulta de virada de página.

operação op

Op significa literalmente "operação". Tanto Get quanto Put pertencem a Op, que são apenas APIs especiais abertas para simplificar o desenvolvimento do usuário.

O parâmetro Op é uma operação abstrata, que pode ser Put / Get / Delete ...; e OpResponse é um resultado abstrato, que pode ser PutResponse / GetResponse ...

O Op pode ser criado por alguns métodos definidos no Cliente:

  • função OpDelete (key string, opts… OpOption) Op
  • função OpGet (key string, opts… OpOption) Op
  • função OpPut (key, val string, opts… OpOption) Op
  • função OpTxn (cmps [] Cmp, thenOps [] On, elseOps [] On) On

Na verdade, não é diferente de chamar KV.Put e KV.GET diretamente.

cli, err := clientv3.New(clientv3.Config{
    Endpoints:   endpoints,
    DialTimeout: dialTimeout,
})
if err != nil {
    log.Fatal(err)
}
defer cli.Close()

ops := []clientv3.Op{
    clientv3.OpPut("put-key", "123"),
    clientv3.OpGet("put-key"),
    clientv3.OpPut("put-key", "456")}

for _, op := range ops {
    if _, err := cli.Do(context.TODO(), op); err != nil {
        log.Fatal(err)
    }
}

alugar

Crie um contrato de arrendamento

grantResp, err := lease.Grant(context.TODO(), 10)

Atribuir arrendamento

kv.Put(context.TODO(), "/test/vanish", "vanish in 10s", clientv3.WithLease(grantResp.ID))

Se o Lease tiver expirado antes do Put, essa operação Put retornará um erro e você precisará reatribuir o Lease neste momento

Renovar

keepResp, err := lease.KeepAliveOnce(context.TODO(), grantResp.ID)

Se o aluguel expirou antes da execução, ele precisa ser realocado. etcd não fornece uma API para implementar Put with Lease atômico, precisamos julgar err para realocar o Lease.

romances

txn := kv.Txn(context.TODO())

kv.Txn(context.TODO()).If(
 clientv3.Compare(clientv3.Value(k1), ">", v1),
 clientv3.Compare(clientv3.Version(k1), "=", 2)
).Then(
 clientv3.OpPut(k2,v2), clentv3.OpPut(k3,v3)
).Else(
 clientv3.OpPut(k4,v4), clientv3.OpPut(k5,v5)
).Commit()

Semelhante a clientv3.Value () \ usado para especificar atributos-chave, existem vários métodos:

  • função CreateRevision (key string) Cmp: A versão de criação de key = xxx deve atender ...
  • função LeaseValue (key string) Cmp: Lease ID com chave = xxx deve satisfazer ...
  • func ModRevision (key string) Cmp: A última versão modificada de key = xxx deve atender ...
  • func Value (string de chave) Cmp: O valor de criação de key = xxx deve satisfazer ...
  • func Version (key string) Cmp: Os tempos de atualização cumulativos de key = xxx devem atender ...

monitor

Watch é usado para monitorar as mudanças de uma determinada chave Watche retorna uma após a chamada WatchChan. Seu tipo é declarado da seguinte maneira:

type WatchChan <-chan WatchResponse

type WatchResponse struct {
    
    
    Header pb.ResponseHeader
    Events []*Event

    CompactRevision int64

    Canceled bool

    Created bool
}

Artigo de referência

https://juejin.im/post/5dba5bedf265da4d461eb8ff#heading-3

https://zhuanlan.zhihu.com/p/38300827

Acho que você gosta

Origin blog.csdn.net/C_jian/article/details/108325907
Recomendado
Clasificación