banco de dados incorporável pudge 500 linhas em golang

pudge é um banco de dados de chave / valor incorporável escrito na biblioteca padrão Go.

imagem

Vou me debruçar sobre as diferenças fundamentais das soluções existentes.

Sem Estado

pudge.Set("../test/test", "Hello", "World") 

O Puj criará automaticamente o banco de dados de teste, incluindo subdiretórios, ou o abrirá. Não há necessidade de armazenar o estado da tabela e você pode armazenar valores com segurança em aplicativos multithread. Pooj é thread-safe.

Typefree

No puj, você pode escrever bytes, seqüências de caracteres, números ou estruturas. Sem se preocupar com a conversão de dados em sua representação binária.

  type Point struct { X int Y int } for i := 100; i >= 0; i-- { p := &Point{X: i, Y: i} db.Set(i, p) } var point Point db.Get(8, &point) log.Println(point) 

Sistema de consulta

Puj oferece a capacidade de extrair chaves em uma ordem específica, incluindo seleção com um limite, recuo, classificação e seleção por prefixo.

  keys, _ := db.Keys(7, 2, 0, true) 

O código acima é semelhante à consulta SQL:

 select keys from db where key>7 order by keys asc limit 2 offset 0 

Observe que a classificação das chaves é "preguiçosa". Por outro lado, as chaves são armazenadas na memória e são executadas rapidamente.

Paralelismo

Pooj, como a maioria dos bancos de dados modernos, usa um modelo de leitura sem bloqueio, mas a gravação em um arquivo bloqueia todas as operações. Mas você pode criar / abrir arquivos em tempo real, minimizando o número de bloqueios. Não há erro "banco de dados já aberto" no puja. Exemplo de uso no roteador http:

 func write(c *gin.Context) { var err error group := c.Param("group") counter := c.Param("counter") db, err := pudge.Open(group, cfg) if err != nil { renderError(c, err) return } _, err = db.Counter(counter, 1) if err != nil { renderError(c, err) return } c.String(http.StatusOK, "%s", "ok") } 

Motores

Apesar de seu tamanho pequeno, o puj suporta dois modos de armazenamento de dados. Na memória e no disco. Por padrão, o puj armazena apenas dados (valores) no disco. Mas, se desejar, você pode ativar o modo de armazenamento de dados na memória. Nesse caso, eles serão liberados para o disco mediante solicitação ou quando o banco de dados for fechado.

Status

Pooja é usado tanto em projetos domésticos quanto em produção, no gráfico abaixo - o número de solicitações para o servidor http com base no puja e o número de solicitações é superior a 20 ms



Nesse caso, o puja é ativado no modo de sincronização completa e, no momento do fsync, ocorrem atrasos significativos (mais de 20 ms). Felizmente, porém, não existem tantos em termos percentuais.

Na página do projeto , você pode encontrar mais links com exemplos de integração do puja em vários projetos.

Velocidade

No repositório com benchmark'y, você pode comparar o puj com outros bancos de dados:

Teste 1


 Number of keys: 1000000 Minimum key size: 16, maximum key size: 64 Minimum value size: 128, maximum value size: 512 Concurrency: 2 
pogreb
goleveldb
parafuso
badgerdb
pudge
slowpoke
pudge (mem)
1 milhão (Put + Get), segundos
187
38.
126
34
23
23
2
1M Put, ops / s
5336
34743
8054
33539
47298
46789
439581
1M de obtenção, ops / s
1782423
98406
499871
220597
499172
445783
1652069
FileSize Mb
568
357
552
487
358
358
358

Pooja é muito bem equilibrado na proporção entre velocidade de gravação e velocidade de leitura. Que não é um banco de dados altamente especializado, otimizado para leitura ou gravação. Em alta velocidade de leitura - é mantida uma velocidade de gravação bastante alta. O que, no entanto, pode ser aumentado ainda mais, paralelizando as gravações em arquivos diferentes (como é feito nos mecanismos da LSM Tree).

Links para os bancos de dados usados ​​no teste:

  • pogreb Armazenamento de valores-chave incorporado para cargas de trabalho pesadas de leitura, escritas em Go
  • goleveldb Banco de dados de chave / valor LevelDB no Go.
  • bolt Um banco de dados de chave / valor incorporado para o Go.
  • DB rápido do valor-chave no Go
  • slowpoke Armazenamento de chave / valor de baixo nível no Go puro (baseado em pudge)
  • pudge Armazenamento rápido e simples de chave / valor escrito usando a biblioteca padrão da Go

Eles me pediram para comparar com memcache e redis, mas como a maior parte do tempo é gasta em interfaces de rede ao interagir com dados de banco de dados, isso não é totalmente justo. Embora, por outro lado, o puja vença devido ao multithreading, apesar de gravar dados no disco.

Desenvolvimento adicional

  • Transações Seria conveniente combinar solicitações de gravação para o pool, com reversão automática em caso de erro.
  • Capacidade de limitar a vida útil da chave (como TTL no memcache / cassandra etc.)
  • A falta de um servidor. É conveniente incorporar o puja nos microsserviços existentes, mas provavelmente um servidor separado aparecerá. Como parte de um projeto separado.
  • Versão para celular. Para uso no Android, iOS e como um plugin para o Flutter.

Source: https://habr.com/ru/post/pt439216/


All Articles