Banco de Dados
-
Upload
wagner-gomes -
Category
Documents
-
view
114 -
download
23
Transcript of Banco de Dados
Onde nasceu ?
Dados do Linkedln e análise da equipe
pesquisa, análise e
hadoop e dados gasoduto
pesquisar
gráfico social
Caltrain
chefe muito branda
dois vivas para o modelo de dados relacional
A visão relacional é um triunfo da ciência da computação, mas ...
colar juntos cordas para chegar a seus dados é bobagem
duro para construir estruturas de dados reutilizáveis
não escondem a hierarquia de memória!
bom: arquivos de sistemas API
ruim: SQL, alguns RPCs
por que é tão difícil?
Falhas em um sistema distribuído é muito mais complicada
Um pode falar com B não implica B pode conversar com um
Voldemort é um repositório de dados distribuído que é concebido como umarmazenamento de
chave-valor utilizado pelo LinkedIn para armazenamento de alta escalabilidade. É nomeado
após o fictício Harry Potter vilão Lord Voldemort .
Voldemort ainda está em desenvolvimento. Não é nem banco de dados de um objeto, nem um
banco de dados relacional. Ele não tentar satisfazer relações arbitrárias e
asACID propriedades, mas sim é um grande, distribuído, tolerante a falhas, tabela persistente
hash.
Vantagens
Voldemort oferece uma série de vantagens em relação a outras bases de dados:
Combina na memória cache com o sistema de armazenamento de modo que uma camada
de armazenamento em cache separado não é necessário (em vez do sistema de
armazenamento em si é apenas rápido)
É possível emular a camada de armazenagem, uma vez que é completamente
mockable. Isso faz com que o desenvolvimento e o teste de unidade simples, em que pode
ser feito contra um sistema de armazenamento de usar e deitar fora de memória sem a
necessidade de um cluster real ou sistema de armazenamento real
Lê e escreve escala horizontal
Simple API: A API decide replicação de dados e colocação e acomoda uma ampla gama
de aplicações específicas estratégias
Dados transparentes porcionamento: Este permite a expansão cluster sem reequilíbrio
todos os dados
Propriedades
O Voldemort armazenamento de dados distribuídos tem as seguintes propriedades: [ 1 ]
Colocação de dados: Suporte para conectáveis estratégias de posicionamento de dados
existe para apoiar coisas como distribuição em centros de dados que estão distantes.
A replicação de dados: Os dados são automaticamente replicadas ao longo de um grande
número de servidores.
Dados particionamento: Os dados são automaticamente dividida de modo que o servidor
contém apenas um subconjunto dos dados totais
Desempenho do nó único bem: 10-20k de operações por segundo pode ocorrer
dependendo das máquinas, a rede, o sistema de disco, eo fator de replicação de dados
Independência nó: Cada nó é independente de outros nós sem ponto central de falha ou
coordenação
Serialização Pluggable: Este permite que as chaves ricos e valores, incluindo listas e
tuplas com campos nomeados, bem como a integração com frameworks de serialização
comuns. Exemplos dessas estruturas são Avro, serialização de Java, Protocol Buffers, e
Thrift
Falhas transparentes: falhas do servidor são manipuladas de forma transparente, de modo
que o usuário não ver tais problemas
Controle de versão: Os itens de dados são versões para maximizar a integridade dos
dados em caso de falha, sem comprometer a disponibilidade do sistema
Valor-chave de armazenamento
Para habilitar alto desempenho e disponibilidade que permitem apenas muito
simples de valor-chave de acesso de dados. Ambas as chaves e os valores podem
ser objetos compostos complexos, incluindo listas ou mapas, mas nada-a-menos
as consultas apenas suportados são efetivamente o seguinte:
valor = store.get (chave)store.put (valor, chave)store.delete (chave)
Este não é de forma suficientemente boa para todos os problemas de
armazenamento, há uma variedade de trade-offs:
Contras
sem complexos filtros de consulta
tudo se junta deve ser feita no código
sem restrições de chave estrangeira
não desencadeia
Prós
apenas consultas eficientes são o desempenho possível, muito previsível
fácil de distribuir através de um cluster
de orientação a serviços muitas vezes não permite restrições de chaves
estrangeiras e forças de junta a ser feito em código de qualquer maneira
(porque chave se refere a dados mantidos por outro serviço)
utilizando um banco de dados relacional que você precisa de uma camada
de cache para escalar lê, a camada de cache normalmente obriga em
valores-chave de armazenamento de qualquer maneira
muitas vezes acabam com XML ou outros blobs desnormalizada para o
desempenho de qualquer maneira
separação limpa de armazenamento e lógica (SQL incentiva lógica
buisiness mistura com as operações de armazenamento para maior
eficiência)
nenhum objeto-relacional perder-jogo
Mais discussão dos detalhes do modelo de dados, será dada a seguir.
Arquitetura do Sistema
Cada camada no código implementa uma interface de armazenamento simples
que não colocar, obter e excluir. Cada uma dessas camadas é responsável por
executar uma função, como a comunicação TCP / IP, serialização, reconciliação
versão, entre os nós de roteamento, etc Por exemplo, a camada de roteamento é
responsável por tomar uma operação, digamos, um PUT, e delegando-a todos os
N réplicas de armazenamento em paralelo, ao manusear quaisquer falhas.
Mantendo cada uma destas camadas separadas significa que eles podem ser
misturados e combinados no tempo de execução para atender diferentes
necessidades. Por exemplo, podemos adicionar uma camada de compressão que
comprime valores de byte em qualquer nível abaixo do nível de serialização.Da
mesma forma que temos a flexibilidade de onde o roteamento inteligente de dados
para partições é feito. Isso pode ser feito no lado do cliente para "inteligentes"
clientes, ou pode ser feito no lado do servidor para permitir mudos, hardware
clientes com balanceamento de carga (http dizer escrita em Ruby). O que fazemos
é simplesmente uma questão de se a camada de rede fica acima ou abaixo da
camada de roteamento.
No diagrama acima, "Carregar Bal". indica um balanceador de carga de hardware
ou round-robin balanceador de carga de software e "Partition roteamento-
consciente" é o armazenamento de sistemas de roteamento interno. Obviamente
menos lúpulo é bom do ponto de vista de latência (desde, bem, há menos saltos),
agradável do ponto de vista de transferência (já que há menos potenciais
gargalos), mas requer a inteligência de roteamento para subir na pilha (por
exemplo, o cliente deve ser Java e usar a nossa biblioteca). Na final, a imagem
mais à direita os pedidos http-RPC para o serviço estão a ser encaminhados para
as máquinas que contêm os dados corretos (quando possível), para que, no caso
simples de um único replicado ler a necessidade máquina pode buscar
diretamente do local, bdb-processo.
Essa flexibilidade torna configurações de alto desempenho possível. O acesso ao
disco é o único grande desempenho atingido no armazenamento, o segundo é o
lúpulo de rede. O acesso ao disco pode ser evitado através do particionamento do
conjunto de dados e armazenamento em cache, tanto quanto possível. Lúpulo
rede exigem flexibilidade de arquitetura para eliminar. Note que, no diagrama
acima, podemos implementar 3-hop, 2-hop, e 1-hop serviços remotos usando
configurações diferentes. Esta permite um desempenho muito elevado para ser
alcançado quando é possível encaminhar chamadas directamente serviço para o
servidor apropriado.
Dados particionamento e replicação
Dados precisa ser particionado em um cluster de servidores de modo que nenhum
único servidor precisa manter o conjunto de dados completo. Mesmo quando os
dados podem caber em um único disco, o acesso ao disco para valores pequenos
é dominado por tempo de busca para particionamento tem o efeito de melhorar a
eficiência do cache, dividindo o conjunto "quente" de dados em pequenos pedaços
que podem (espero) ser totalmente em memória no servidor que armazena essa
partição. Isto significa que os servidores no cluster não são intercambiáveis, e os
pedidos devem ser encaminhados para um servidor que contém os dados
solicitados, e não apenas a qualquer servidor disponível de forma aleatória.
Da mesma forma os servidores regularmente não, tornar-se sobrecarregado, ou
são levadas em manutenção. Se existirem S servidores e cada servidor é
assumido falhar independentemente com probabilidade p em um determinado dia,
então a probabilidade de perda de pelo menos um servidor de um dia, será de 1 -
(1 - p ) s . É óbvio que este fato, não se pode armazenar dados em um único
servidor ou a probabilidade de perda de dados será inversamente proporcional ao
tamanho do cluster.
A maneira mais simples possível para alcançar este objetivo seria cortar os dados
em S partições (um por servidor) e armazene cópias de uma determinada
chave K em R servidores. Uma maneira de associar osR servidores com
chave K seria tomar um = K mod S e armazenar o valor em servidores um , um ,
um ...,um + r . Assim, para qualquer probabilidade p você pode escolher um fator
apropriado replicação R para alcançar uma probabilidade aceitavelmente baixo de
perda de dados.
Este sistema tem a propriedade interessante que qualquer pessoa pode calcular a
localização de um valor apenas por saber de sua chave, o que nos permite fazer
look-ups de uma forma peer-to-peer sem contato com um servidor central de
metadados que tem um mapeamento de todas as chaves aos servidores.
A desvantagem da abordagem acima ocorre quando um servidor é adicionado ou
retirado do cluster (dizer, porque nós compramos um novo hardware ou um
servidor está temporariamente fora do ar). Neste caso dpodem mudar e todos os
dados irão deslocar entre os servidores. Evento se d não muda carga não vai
distribuir uniformemente a partir de um único servidor removido / falha para o resto
do agrupamento.
Hashing consistente é uma técnica que evita esses problemas, e podemos usá-lo
para calcular a localização de cada tecla no cluster. Usando esta técnica voldemort
tem a propriedade de que, quando um servidor falhar carga irá distribuir
igualmente sobre todos os servidores restantes no cluster. Da mesma forma,
quando um novo servidor é adicionado a um conjunto de S servidores, apenas 1 /
( S +1) valores devem ser movidos para a nova máquina.
Para visualizar o método de hash consistente, podemos ver as possíveis inteiros
valores de hash como um anel começando com 0 e circulando em torno de 2 ^ 31-
1. Este anel é dividido em Q partições de tamanho igual, com Q >> S , e cada um
dos S servidores é atribuído Q / S destes. Uma chave é mapeada para o anel
usando uma função arbitrária hash, e então calcular uma lista de R servidores
responsáveis por esta chave, tendo os primeiros R nós únicos quando se mover
sobre as partições no sentido horário. O diagrama abaixo fotos um anel de hash
para servidores A , B , C , D . As setas indicam as teclas mapeadas no anel de
hash ea lista resultante de servidores que irá armazenar o valor para essa chave
seR = 3.
Formato de dados e consultas
Em um banco de dados relacional de dados é dividido em mesas 2D. O
equivalente aqui é uma "loja", não usamos a palavra tabela, pois os dados não é
necessariamente tabular (um valor pode conter listas e mapeamentos que não são
consideradas em um mapeamento rigoroso relacional). Cada chave é única para
uma loja, e cada chave pode ter, no máximo, um valor.
Consultas
Voldemort suporta semântica hashtable, para um único valor pode ser modificado
em um tempo e de recuperação é de chave primária. Isso faz com que a
distribuição através de máquinas particularmente fácil, já que tudo pode ser
dividido pela chave primária.
Note-se que, apesar de não apoiar um-muitos relações, fazemos listas de apoio
como valores que realiza a mesma coisa - por isso, é possível armazenar um
número razoável de valores associados a uma única tecla. Isto corresponde a um
java.util.Map onde o valor é um java.util.List. Na maioria dos casos
desnormalização é uma melhoria de desempenho enorme uma vez que existe
apenas um único conjunto de pesquisas em disco, mas para grandes
relacionamentos um-para-muitos (digamos que uns mapas chave para dezenas de
milhões de valores), que deve ser mantido no servidor e transmitido através de um
cursor preguiçosamente esta abordagem não é prático. Este caso (raro) deve ser
dividido em sub-consultas ou não tratadas a nível de aplicação.
A simplicidade dos procedimentos podem ser uma vantagem, uma vez que cada
uma tem um desempenho muito previsível, é fácil de quebrar o desempenho de
um serviço para o número de operações de armazenagem executa rapidamente e
estimar a carga. Em contraste consultas SQL são muitas vezes opaco, e os planos
de execução pode ser dependente dos dados, por isso pode ser muito difícil de
estimar se uma determinada consulta terá um bom desempenho com dados
realistas sob carga (especialmente para um novo recurso que não tem nem dados,
nem de carga).
Além disso, ter uma interface de operação de três permite transparentemente
zombar fora da camada de armazenamento de todo e teste de unidade usando
uma implementação de simulação-de armazenamento que é um pouco mais do
que um HashMap. Isso faz com que o teste de unidade exterior de um recipiente
ou ambiente muito mais prática.
Modelo de Dados e serialização
Serialização em Voldemort é conectável assim você pode usar um dos cozido em
serializers ou facilmente escrever a sua própria. No nível mais baixo do formato de
dados para Voldemort é apenas matrizes de bytes para ambas as chaves e
valores. Formatos de nível mais alto de dados são uma opção de configuração que
são definidos para cada loja - qualquer formato pode ser apoiado através da
implementação de uma classe Serializer que lida com a tradução entre bytes e
objetos. Isso garante que o cliente serializa os bytes corretamente.
Os seguintes tipos são suportados fora da caixa, inserindo o tipo apropriado na
configuração da loja:
json - Um binário, digitado JSON modelo de dados que suporta listas,
mapas, datas, valores booleanos e números de precisão diferentes. Este é
o tipo de serialização só que tem um mapeamento completo de bytes <->
objetos e de cordas <-> objetos. Isto significa que pode ser interagido com
como SQL (por exemplo, através do cliente de linha de comando). Nossa
utilização da produção atual utiliza uma digitado, compacto, esquema check
formato JSON-like, mas isso não tem nenhum estatuto especial, e para
outras aplicações de outros mecanismos de serialização pode ser melhor.
corda - Apenas armazena cordas primas. Útil para blobs XML.
java-serialização - Nosso velho amigo de serialização Java. Certifique-se
de entender a compatibilidade garante serialização java fornece antes de
armazenar muitos objetos java.
protobuf - buffers Protocolo é um formato de serialização de geração de
código do Google. Esta pode ser a melhor maneira de ir, se você não
precisa de acesso à linha de comando.
thrift - Thrift é outro formato de serialização geração de código.
avro-generic / avro específica / avro-reflexivo - Avro é outro sistema de
serialização de dados rich.
identidade - Isso efetivamente desativa serialialization, apenas dando-lhe
de volta o byte exata [].
String e serialização de identidade são bastante auto-explicativo. Documentação /
Tutorial para os formatos de serialização outros podem ser facilmente encontrados
na internet. Assim, o restante desta seção descreve a motivação por trás do tipo
json.
Tipo de serialização JSON Detalhes
Existem três estados que os dados podem residir, e nós queremos ser capazes de
traduzir entre todos eles:
Em estruturas de dados de memória: por exemplo, um objeto Usuário
Bytes para transmissão de persistência e de rede
Representação de texto: É essencial ser capaz de ter um DBA verificar
certos valores e fazer atualizações on-line sem escrever novo código
SQL, basicamente, em torno de padroniza o formato de consulta de texto e
programas de lidar com o mapeamento entre essas cordas e as estruturas de
dados internos do programa usa. Este é o problema de mapeamento objeto-
relacional clássico.
JSON é um excelente modelo de dados para armazenamento, pois suporta os
tipos comuns que são usados em todas as linguagens de programação (strings,
números, listas / matrizes e objetos / tabelas de hash), o problema é que ele é
inerentemente sem esquema. O uso mais comum para todo o problema é fazer
com que o armazenamento de N linhas, todos com o mesmo formato exacto (ou
seja, contendo as mesmas colunas), neste caso JSON é um desperdício, uma vez
que armazena o formato de dados em cada linha. Da mesma forma que queremos
ser capazes de verificar afirmações sobre a forma de os dados para evitar que
erros de digitação uma coluna para armazenar dados corrompidos. Para evitar
isso, devemos ser capazes de atribuir um esquema para a chave eo valor de cada
loja que descreve o que é permitido para armazenar lá e como traduzi-lo para e de
bytes. O esquema pode-se ser especificado em JSON, bem como, utilizando os
seguintes tipos:
int8, int16, int32, int64, float32, float64, objeto de data, string, objeto, bytes, boolean, array,
Por exemplo, se eu esperar uma loja para conter cadeias então eu posso
especificar o tipo de tabela já que
"String"
Note que esta definição de tipo é, em si JSON válido
O código java que busca dados irá retornar uma String
Se eu esperar a loja para conter uma lista de números inteiros, digamos, ids
membros, posso especificar o tipo
["Int32"]
O código java irá retornar uma List <Integer>.
Se eu esperar a loja para conter um objeto de usuário simples que eu poderia
definir o tipo
{"Fname": "string", "sobrenome": "string", "id": "int32", "e-mails": ["string"]}
Aqui, o código Java retornará uma <String,Object> mapa contendo cada uma das
teclas de dados, e o valor associado.
Aqui está uma lista completa de tipos permitidos:
tiposubestilos
armazenáveisbytes usados Tipo Java
exemplo
JSON
definição
do tipo de
exemplo
número
int8, int16, int32,
int64, float32,
float64 data,
8, 16, 32, 64,
32, 64, 32
Byte, Short,
Integer, Long
Float, duplo, data
1 "Int32"
corda cordas, bytes
2 +
comprimento
de corda ou
bytes
String, Byte [] "Olá" "String"
boolea
nboolean 1 Boolean verdadeiro "Boolean"
objeto objeto1 tamanho +
de conteúdos
Mapa
<String,Object>
{"Key1": 1,
"Key2": "2",
"key3":
false}
{"Nome":
"string",
"height":
"int16"}
ordem ordemtamanho *
sizeof (tipo)List <> [1, 2, 3] ["Int32"]
Neste sentido, a definição de tipo é um conjunto de restrições de padrão json que
fazem serialização eficiente (por meio da distribuição de fora campos repetidos e
armazenar números compacta) e permitir a checagem de dados básicos de
correção.
Note-se que mesmo que um valor pode ter todos esses campos diferentes que só
suportam consultas por chave definida da loja.
Para ajudar com a evolução do esquema esta implementação JSON inclui a
capacidade de versão do esquema para permitir a migração gradual dos
dados. Os dados serão sempre gravados usando o esquema mais recente, mas
será sempre ler usando qualquer esquema foi usado para escrever. Isso permite
que a migração de esquema para ter lugar sem derrubar o serviço que recebe os
dados.
Consistência e Versioning
Ao tomar simultânea múltipla escreve distribuídos em vários servidores (e talvez
vários centros de dados) de consistência de dados torna-se um problema difícil. A
solução tradicional para este problema é distribuído transações, mas estes são
ambos. Lenta (devido a muitas idas) e frágil como eles exigem que todos os
servidores de estar disponível para processar uma transacção Em particular,
qualquer algoritmo que deve falar com> 50% de servidores para garantir a
consistência torna-se bastante problemática se o aplicativo é executado em vários
centros de dados e, portanto, a latência para o cruzamento de dados do centro de
operações será extremamente alto.
Uma solução alternativa é a tolerar a possibilidade de inconsistência, e resolver
inconsistências em tempo de ler. Esse é o método utilizado aqui.
Aplicações costumam fazer uma leitura-modificação-atualizar seqüência ao
modificar dados. Por exemplo, se um usuário adiciona um endereço de e-mail à
sua conta, pode carregar o objeto de usuário, adicionar o e-mail, e em seguida,
escrever os novos valores de volta para o banco de dados. As transações em
bancos de dados são uma solução para este problema, mas não são uma opção
real quando a transação deve abranger cargas de várias páginas (que pode ou
não pode ser concluída, e que pode terminar em qualquer período de tempo
específico)
O valor para uma determinada chave é consistente se, na ausência de alterações,
todas as leituras de retorno que o mesmo valor de chave. No mundo só de leitura
de dados é criado de uma forma consistente e não mudou. Quando
acrescentamos tanto escreve, e replicação, encontramos problemas: agora
precisamos atualizar vários valores em várias máquinas e deixar as coisas em um
estado consistente. Na presença de falhas no servidor isso é muito difícil, na
presença de partições de rede é comprovadamente impossível (a partição é
quando, por exemplo, A e B podem alcançar um ao outro e C e D podem alcançar
um ao outro, mas A e B pode 't alcance C e D).
Existem vários métodos para alcançar a consistência com diferentes garantias e
compensações de desempenho.
Duas fases - Este é um protocolo de bloqueio que envolve duas rodadas de
coordenação entre as máquinas. É perfeitamente consistente falha, mas
não tolerantes, e muito lenta.
Paxos estilo de consenso - Este é um protocolo para chegar a um acordo
sobre um valor que é mais tolerante fracasso.
Leia-reparação - As duas primeiras abordagens evitar inconsistência
permanente. Esta abordagem envolve a escrita de todas as versões
inconsistentes, e depois para ler o tempo de detecção do conflito, e resolver
os problemas. Isso envolve pouca coordenação e é completamente falha
tolerante, mas pode exigir a lógica de aplicação adicional para resolver
conflitos.
Nós usamos versões e leitura de reparação. Isto tem uma das melhores garantias
de disponibilidade e maior eficiência (apenas W escreve ida e volta de rede são
necessários para réplicas N onde W pode ser configurado para ser inferior a
N). 2PC normalmente requer 2N roundtrips bloqueio. Variações Paxos variar um
pouco, mas são comparáveis aos 2PC.
Outra abordagem para atingir a consistência é usando Handoff sugeriu . Neste
método durante as gravações, se acharmos que os nós de destino são para baixo
nós armazenamos uma "dica" do valor atualizado em um dos nós vivos. Então,
quando esses nós para baixo voltar as "dicas" são empurrados para eles, tornando
os dados consistente. Muitos dos detalhes são emprestados do papel da
Amazônia abaixo
Aqui estão alguns bons textos sobre este assunto:
Consistência na Dynamo da Amazon
Paxos Made Simple
Duas fases
O significado é de consistência eventual (por CTO da Amazon, Werner
Vogels)
Controle de versão em um sistema distribuído
Um sistema de controle de versão simples é otimista bloqueio armazenamos um
balcão único ou "relógio" valor com cada pedaço de dados e só permitir
atualizações quando a atualização especifica o valor do relógio correta.
Isso funciona bem em um banco de dados centralizado, mas cai em um sistema
distribuído onde os servidores aparecem e desaparecem e replicação pode levar
tempo. Para isso o uso de um único valor não irá conter o suficiente da história
escrita para nos permitir jogar fora versões antigas. Considere a seguinte
seqüência de ações:
# Dois servidores ao mesmo tempo buscar o mesmo valor[Cliente 1] chegar (1234) => {"nome": "Jay", "email": "jay.kreps @ linkedin.com"}[Cliente 2] se (1234) => {"nome": "Jay", "email": "jay.kreps @ linkedin.com"}
# Cliente uma modifica o nome e faz um put[Cliente 1] colocar (1234, {"nome": "jay Kreps", "e-mail": "jay.kreps @ linkedin.com"})# 2 modifica o cliente de e-mail e faz um put[Cliente 2] colocado (1234, {"nome": "Jay", "email": "jay.kreps @ yahoo.com"})
# Agora temos as seguintes versões conflitantes:{"Nome": "Jay", "email": "jay.kreps @ linkedin.com"}{"Nome": "jay Kreps", "e-mail": "jay.kreps @ linkedin.com"}
{"Nome": "Jay", "email": "jay.kreps @ yahoo.com"}
Neste modelo os dois últimos escreve tornar irrelevante o valor original (desde que
acontecerá depois da original). No entanto não há nenhuma regra que irá dizer ao
servidor que ele pode jogar fora ou se muda para o e-mail ou a mudança de
nome. Então, nós queremos um sistema de controle de versão que permite
detectar substitui e jogar fora a versão antiga, mas também nos permite detectar
conflitos e deixar o cliente conciliar estes.
Uma resposta a isso é uma assim chamada versão vetor de relógio. Um relógio
vetor mantém um contador para cada servidor escrito, e nos permite calcular
quando duas versões estão em conflito, e quando uma versão bem-sucedida ou
precede outro.
Um relógio vetor é uma lista de servidor: pares de versão:
[1:45,2:3,5:55]
A versão indica que o servidor era o "mestre" para que o número de gravações.
Uma versão v1 consegue uma versão v2 se para todo i , v1 i > v2 i . Se
nem v1 > v2 nem v1 < v2 , entãov1 e v2 co-ocorrer, e estão em conflito. Aqui está
um exemplo simples de duas versões conflitantes:
[1:2,2:1][1:1,2:2]
Assim, nosso esquema de versões define uma ordem parcial sobre os valores que simples esquemas de bloqueio otimista definem uma ordem total .
Parâmetros de roteamento
Qualquer sistema persistente precisa responder à pergunta "onde está o meu
material?". Esta é uma pergunta muito fácil se tivermos um banco de dados
centralizado, pois a resposta é sempre "em algum lugar no servidor de banco de
dados". Num sistema de chave dividida existem várias máquinas que podem ter os
dados. Quando fazemos uma leitura precisamos ler a partir de pelo menos um
servidor para obter a resposta, quando fazemos uma gravação que precisamos
(finalmente) escrever a todos N das réplicas.
Existem, portanto, três parâmetros que importam:
N - O número de réplicas
R - O número de máquinas de ler a partir de
W - O número escreve bloquear para
Note que se R + W > N então temos a garantia de "ler nosso escreve". Se W = 0,
em seguida, as gravações são não-bloqueio e não há garantia de que quer o
sucesso. Puts e exclusões não são consistentes nem seja imediatamente
isolado. A semântica é esta: se uma operação de colocar / apagar sucede, sem
exceção, então é garantido que pelo menos W nós realizou a operação, no
entanto, se a gravação falhar (digamos, porque nós muito poucos conseguem
realizar a operação), então o Estado é indeterminado. Se pelo menos um posto /
apagar consegue, então o valor será eventualmente o novo valor, no entanto, se
nenhum conseguiu então o valor é perdido. Se o cliente quer garantir o estado
depois de uma operação de escrita não devem emitir outra gravação.
Camada de persistência
Apoiamos uma API simples para persistência e uso BDB edição Java como
padrão. Outros mecanismos de armazenamento suportados são MySQL, o
armazenamento em memória (utilizado para o teste de unidade) e nosso
mecanismo de armazenamento próprio costume de somente leitura (gerados
offline como um processo de lote em Hadoop). Para adicionar uma nova
implementação de persistência você precisa implementa colocar, obter, excluir e,
além de fornecer um iterador sobre os valores na loja local.
Suporte para lote computadorizada de dados - read-only lojas
Uma das necessidades mais intensivas de dados de armazenamento é armazenar
os dados do lote calculados sobre os membros e conteúdo do nosso
sistema. Estes postos de trabalho, muitas vezes lidar com as relações entre as
entidades (por exemplo, os usuários relacionados, ou artigos de notícias
relacionadas) e assim por N entidades podem produzir
até N 2 relacionamentos. Um exmaple no LinkedIn são as redes membros, que
estão na faixa 12TB se armazenado explicitamente para todos os
membros.Processamento em lote de dados é geralmente muito mais eficiente do
que o acesso aleatório, o que significa que se pode facilmente produzir mais dados
em lote computadorizada que podem ser facilmente acessados pelo sistema
vivo. Hadoop expande essa capacidade. Estamos no processo de open-sourcing
um. Voldemort persistência backend que suporta muito eficiente acesso somente
leitura que ajuda a ter um monte de dor de nossos criação, implantação e gestão
de grandes, somente leitura lote conjuntos de dados computadorizada
Grande parte da dor de lidar com computação lote vem do processo de "push",
que transfere dados de um data warehouse ou instância hadoop ao sistema
vivo. Em um db tradicional este, muitas vezes, significa a reconstrução do índice
no sistema ao vivo com os novos dados. Fazendo milhões de instruções SQL
INSERT ou UPDATE, geralmente não é de todo eficiente, e, normalmente, em um
db SQL os dados serão implantados como uma nova tabela e, em seguida, trocou
para substituir os dados atuais quando a nova tabela é completamente
construído. Isso é melhor do que fazer milhões de atualizações individuais, mas
isso ainda significa que o sistema vivo está agora construindo um índice GB de
muitos, para o novo conjunto de dados (ou Performa), ao mesmo tempo servindo
de tráfego ao vivo. Isso por si só pode levar horas ou dias, e pode destruir o
desempenho em consultas ao vivo. Algumas pessoas têm fixado este trocando no
nível de banco de dados (por exemplo, ter uma db online e offline, e depois troca),
mas isso requer esforço e significa apenas metade hardware do seu está sendo
utilizada. Voldemort corrige esse processo, tornando possível a Prebuild o próprio
índice offline (em Hadoop ou onde), e simplesmente empurrá-lo para fora aos
servidores ao vivo e transparente trocar.
Para mais detalhes sobre estas lojas lote computadorizada (chamado somente leitura lojas) ler esta .
Referências
Dynamo: altamente disponível Amazônia loja Key-Value - Este é o original!
Tempo, Clocks, ea Ordenação de Eventos em um Sistema Distribuído -
Este é o modelo para o sistema de controle de versões
Consistência eventual Revisited discussão muito interessante no Blog
Werner Vogels 'na interação com os desenvolvedores do sistema de
armazenamento e quais as vantagens e desvantagens significa em termos
práticos.
Conjectura de cerveja e da viabilidade de consistentes, disponíveis,
serviços partição tolerantes web - Consistência, Disponibilidade, Partição
tolerância escolher dois.
Berkeley DB desempenho - Uma visão um tanto tendenciosa do
desempenho bdb.
Google Bigtable - Para efeito de comparação, uma abordagem muito
diferente.
Um Fit Tamanho é tudo: uma idéia cujo tempo chegou e saiu - Papel muito
interessante pelo criador de Ingres, Postgres e Vertica
Tamanho único? - Parte 2, resultados comparativos - Benchmarks para ir
com o papel acima
Consistência na Dynamo da Amazon - Um bom post sobre Dynamo
Paxos Made Simple
Duas fases - Wikipédia descrição.
Configuração
Há três arquivos de configuração que a operação do servidor de controle:
cluster.xml - Este contém as informações sobre todos os nós (servidores,
por exemplo) no cluster, o que eles estão em nome de host, as portas que
eles usam, etc É exatamente o mesmo para todos os nós de
Voldemort. Não guarda parâmetros de ajuste ou diretórios de dados para os
nós, já que não é informação pública ao cluster, mas é específico para que
a configuração de nós em particular.
stores.xml - Este contém as informações sobre todas as lojas (tabelas, por
exemplo) no cluster. Isso inclui informações sobre o número necessário de
sucesso lê para manter a consistência, o número necessário de gravações,
bem como a forma como chaves e valores são serializados em bytes. É o
mesmo em todos os nós do cluster.
server.properties - Este contém os parâmetros de ajuste que controlam um
determinado nó. Isto inclui o ID do nó local para que ele saiba o que a
entrada em cluster.xml corresponde a si mesma, também o tamanho do
pool de threads, bem como qualquer configuração necessária para o
mecanismo de persistência local, tais como BDB ou mysql. Este arquivo é
diferente em cada nó.
Finalmente, há uma variável de ambiente, VOLDEMORT_HOME, que controla o
diretório no qual dados e configuração residem. Você pode ver um exemplo de
como a configuração é Definiu no. Config / subdiretório do projeto Isto inclui
configurações de exemplo que você pode modificar com suas especificidades
próprias.
Configuração de cluster
Aqui está um exemplo cluster.xml para um cluster de 2 nós com 8 partições de
dados. Nós também temos opcionais "zona" campos que permitem mapear os nós
para determinados grupos lógicos (datacenter, rack, etc) chamadas zonas:
<cluster> <-! O nome é apenas para ajudar os usuários a identificar este cluster do gui -> <name> mycluster </ name> <Zone> <zone-id> 0 </ zona-id> <proximity-list> 1 </ proximidade lista-> <Zone> <Zone> <zone-id> 1 </ zona-id>
<proximity-list> 0 </ proximidade lista-> <Zone> <servidor> <-! O ID de nó é único, um início ID seqüencial com 0 que identifica cada servidor no cluster -> <id> 0 </ id> <host> vldmt1.prod.linkedin.com </ host> <http-port> 8081 </ http-port> <socket-port> 6666 </ socket porta-> <admin-port> 6667 </ admin porta-> <-! Uma lista de partições de dados atribuídos a este servidor -> <partitions> 0,1,2,3 </ partições> <zone-id> 0 </ zona-id> </ Server> <servidor> <id> 1 </ id> <host> vldmt2.prod.linkedin.com </ host> <http-port> 8081 </ http-port> <socket-port> 6666 </ socket porta-> <admin-port> 6667 </ admin porta-> <partitions> 4,5,6,7 </ partições> <zone-id> 1 </ zona-id> </ Server> <Cluster />
Uma coisa que é importante entender é que as partições não são partições
estáticas de servidores, mas eles são um mecanismo para particionar o espaço da
chave de tal forma que cada tecla é estaticamente mapeado para uma partição de
dados em particular. O que isto significa é que um determinado cluster pode
suportar muitas lojas cada uma com replicação diferentes fatores, o fator de
replicação não é codificado no projeto do cluster. Isto é importante, uma vez que
alguns dados é mais importante do que os outros dados, e o correcto equilíbrio
entre o desempenho e consistência de uma loja pode ser diferente da outra loja.
Outro ponto importante a lembrar é que o número de partições de dados não
podem ser alterados.Fazemos apoiar uma redistribuição online (reequilíbrio) de
partições. Em outras palavras, a inclusão de novos resultados em gânglios
movendo propriedade de divisórias, mas o número total de partições irá sempre
permanecer o mesmo, assim como o mapeamento de chave para partição. Isto
significa que é importante dar um bom número de partições para começar. O
script aqui vai gerar esta parte da configuração para você.
Note-se que a configuração é atualmente arquivos simples por isso é importante
que os dados em cluster.xml e stores.xml ser exatamente o mesmo em cada
servidor, e que as IDs de nós e partições não pode ser alterado, uma vez que pode
significar que os clientes vão pensar seus dados devem estar no nó X, quando na
verdade ele foi armazenado no nó Y . Esta limitação será removida como a
configuração é movida em voldemort si.
Configuração da loja
Aqui é um stores.xml exemplos de uma loja chamada de teste, que requer apenas
uma única leitura e escrita e usa bdb para persistência:
<stores> <store> <name> teste </ nome> <replication-factor> 2 </ replicação fator-> <preferred-reads> 2 </ preferencial lê-> <required-reads> 1 </ requerido lê-> <preferred-writes> 2 </ preferencial-escreve> <required-writes> 1 </ requerido-escreve> <persistence> bdb </ persistence> <routing> cliente </ routing> <routing-strategy> consistente de roteamento
</ rota estratégia> <key-serializer> corda <type> tipo </> <schema-info> utf8 </ esquema info-> </ Key serializador-> <value-serializer> <type> json </ type> <schema-info version="1"> [{"id": "int32",
"nome": "string"}] </ esquema info-> <compression>
<type> gzip <type> <Compressão />
</ Value serializador-> </ Loja></ Lojas>
Cada um desses parâmetros merece uma discussão rápida:
Nome - O nome da loja. Esta é a seqüência em que os clientes serão
capazes de conectar e operar sobre esta loja. É equivalente ao nome da
tabela no SQL.
replicação factor - Este é o número total de vezes que os dados são
armazenados. Cada colocar ou apagar operação deve, eventualmente,
acertar esta muitos nós. Um factor de replicação de nsignifica que pode ser
possível tolerar até n - 1 falhas de nó sem perda de dados.
preferido-lê (opcional)-O número de sucesso lê o cliente irá tentar fazer
antes de retornar um valor para a aplicação. O padrão a ser igual a leituras
necessária
necessário-lê -O número mínimo de leituras que podem ter sucesso sem
lançar uma exceção.Considere um caso em que o factor de replicação é 5,
leituras preferida é 4, e lê-se necessário é 2.Se três dos cinco nós são
operacionais, então o cliente pode experimentar todos os nós para tentar
chegar a 4 preferido lê, mas uma vez que apenas três são sensíveis
permitirá a leitura para completar. Havia apenas um sido sensível teria
jogado uma exceção, já que era menor do que a garantia de consistência
solicitado para esta tabela (e que poderia significar retornar dados
obsoletos).
preferido-escreve (opcional)-O número de sucesso escreve o cliente tenta
bloquear antes de voltar para o sucesso. O padrão é exigido-escreve
necessário-escreve - O menor número de gravações que podem ter
sucesso sem o cliente voltar uma exceção.
persistência - O backend de persistência utilizada pela loja. Atualmente,
esse poderia ser um dos bdb, mysql , memória , readonly , e de cache . A
diferença entre o cache e memória é que a memória vai jogar e
OutOfMemory exceção se torna maior do que a pilha da JVM enquanto o
cache irá descartar dados.
roteamento - Determina a política de roteamento. Apoiamos
tanto cliente (Client lado de roteamento) e servidor (encaminhamento do
lado do servidor).
encaminhamento estratégia - Determina como armazenamos as
réplicas. Atualmente nós suportamos três roteamento-estratégias
- consistente de roteamento (padrão), zona de roteamento etodo-
roteamento .
serializador-chave - O tipo de serialização usado para ler e
gravar chaves . O tipo pode ser json ,java-
serialização , corda , protobuff , parcimônia , ou identidade (ou seja, bytes-
primas). O esquema info-dá informações para o serializador sobre como
realizar o mapeamento (por exemplo, o esquema descrito no JSON aqui ).
valor serializador- - O tipo de serialização usado para ler e
escrever valores . Os tipos suportados são os mesmos que para as
chaves. No exemplo acima, destacam-se ainda "compressão" o
subelemento que atualmente suporta 'gzip' e 'lzf "compressão. Os
subelementos são os mesmos que para a chave serializador, exceto que o
serializador o valor pode ter vários esquemas-infos com versões
diferentes. A versão mais recente é a usada para gravar dados, mas os
dados é sempre lido com a versão que foi escrito com. Isto permite a
evolução do esquema gradual. Controle de versão é suportada apenas pelo
serializador JSON como formatos de serialização outros têm os seus
sistemas de controle de versão próprios. Aqui estão algumas serializers
exemplo:
<-! Uma serializador que serializa cordas simples na codificação UTF8 ->
<value-serializer> corda <type> tipo </> <schema-info> utf8 </ esquema info-> </ Value serializador-> <-! Uma serializador que serializa dados formato
binário JSON com o esquema dado. Cada valor é um List <Map <String, ?>> onde
as chaves "id" e "nome" e os valores são um ID inteiro de 32 bits e um nome de
cadeia. -> <value-serializer> <type> json </ type> <schema-info> [{"id": "int32", "nome":
"string"}] </ esquema info-> </ Value serializador-> <-! Uma serializador que serializa objetos protocolo
tampão de determinada classe. -> <value-serializer> <type> protobuff </ type> <schema-info> java =
com.something.YourProtoBuffClassName </ esquema info-> </ Value serializador-> <-! Uma serializador que serializa objetos poupança
geradas através de um dos seguintes protocolos - 'binário', 'json' ou
'simples-json'. Suporte atual para clientes Java apenas. -> <value-serializer> thrift <type> tipo </> <schema-info> java =
com.something.YourThriftClassName, protocol = binário </ esquema info->
</ Value serializador-> <-! Serialização Avro - ou 'avro-generic', 'avro
específica' ou 'avro-reflexivo' -> <value-serializer> <type> avro-generic </ type> <schema-info> {"nome": "tipo", "tipo": "enum",
"símbolos": ["foo", "bar"]} </ esquema info-> </ Value serializador->
retenção dias (opcional) - Este parâmetro opcional permite que você defina
uma propriedade de retenção para seus dados. Em seguida, todos os dias,
em um momento especificado nos servidores, um trabalho programado será
executado para apagar todos os dados que têm timestamp> retenção
dias. Isso é útil para manter seus dados aparadas.
retenção-scan-acelerador taxa (opcional) - Se retenção dias é especificado
esta é a taxa em que nós vamos examinar as tuplas para excluir dados.
Se você pretende usar a zona de roteamento de estratégia, precisamos estender a
definição loja de dizer como é para replicar zonas wrt. Aqui está um exemplo de
uma definição loja com enabled 'zona de roteamento ".
<stores> <store> <name> teste </ nome> ...
<routing-strategy> zona de roteamento </ rota estratégia> <- Este número deve ser total do indivíduo zona de replicação do fator -> <replication-factor> 2 </ replicação fator->
<zone-replication-factor> <replication-factor zone-id="0"> 1 </
replicação fator-> <replication-factor zone-id="1"> 1 </
replicação fator-> </ Zona-replicação fator-> <zone-count-reads> 0 </ zona-count-lê> <zone-count-writes> 0 </ zona-count-escreve> <hinted-handoff-strategy> proximidade handoff
</ insinuou-handoff estratégia> ...
</ Loja></ Lojas>
A mudança importante aqui é a introdução de zona de replicação fator que deve conter um fator de replicação que você quer em cada zona. Outros parâmetros:
zona de contagem * - O número de zonas que deseja bloquear para durante
lê / escreve, antes de retornar a solicitação. O número 0 significa que
vamos bloquear pelo menos por um pedido do local,única zona. O
número 1 significa que vamos bloquear pelo menos por um pedido de uma
outra zona.
sugeriu-handoff estratégia (opcional) - Outro mecanismo de consistência
que nós adicionamos recentemente é sugerido handoff . Podemos ativar
esse recurso em uma base por loja. Este parâmetro define a estratégia que
usaria para decidir qual vivemos nós a escrever a nossa "dica" para. As
várias opções são qualquer handoff- , entrega consistente e proximidade
handoff- .
Por nó de configuração
Nós armazenamos por nó de configuração baseada no arquivo server.properties. A
maioria das propriedades têm padrões sensatos (espero). O arquivo nua mínimo
deve ter a seguinte propriedade.
# A identificação da * este nó de cluster * particular (diferente para cada nó no cluster)
node.id = 0Aqui está uma lista de todas as opções de configuração suportadas:
nome omissão descrição
node.id nenhum
O identificador seqüencial
exclusivo para este
servidor no cluster
(começa com 0)
voldemort.home nenhum
O diretório base para
Voldemort. Também pode
ser especificado através
do VOLDEMORT_HOME
variável de ambiente ou
através de uma opção de
linha de comando.
data.directory$ {Voldemort.home} /
dados
O diretório onde os dados
são armazenados
voldemort
metadata.directory$ {} Voldemort.home /
config
O diretório onde voldemort
configuração é
armazenada
BDB lojas configuração
enable.bdb.engine verdadeiroSe o motor BDB ser
ativado?
bdb.cache.size 200MB
O cache BDB que é
partilhada por todas as
tabelas BDB. Maior é
melhor.
bdb.write.transactions falso
Deve ser imediatamente
transações escrito para o
disco?
bdb.flush.transactions falso Quando a transação foi
escrito para o disco
devemos forçar o disco
para limpar o cache do
sistema operacional. Esta
é uma operação
relativamente cara.
bdb.data.directory $ {Data.directory} / bdb
O diretório onde o meio
ambiente está localizado
BDB
bdb.max.logfile.size 1GBO tamanho de um arquivo
de registro individual
bdb.btree.fanout 512
O tamanho fanout para a
btree. Maior fanout mais
effienciently suporta
'btrees' maiores.
bdb.checkpoint.interval.bytes 20 * 1024 * 1024
Quantas vezes (em bytes)
devemos posto o log de
transações? Checkpoints
fazer inicialização e
desligamento mais rápido.
bdb.checkpoint.interval.ms 30000
Quantas vezes em ms
devemos posto o log de
transações
bdb.one.env.per.store falsoUse um ambiente de BDB
para cada loja
bdb.cleaner.threads 1Número de tópicos mais
limpas BDB
MySQL armazena configuração
enable.mysql.engine falso
Devemos ativado o
mecanismo de
armazenamento
mysql? Se o fizer, irá criar
um conjunto de ligação
que irá ser utilizado para a
instância mysql
mysql.user raizO nome de usuário para
usuário mysql
mysql.passwordA senha para o usuário
mysql
mysql.host localhostO anfitrião da instância
mysql
mysql.port 3306 A porta da instância mysql
mysql.database voldemortO nome do banco de
dados mysql
Somente leitura configuração lojas
enable.readonly.engine falso
Devemos permitir que o
motor de armazenamento
readonly?
readonly.backups 1
O número de cópias de
segurança dos dados para
manter em torno de
reversão.
readonly.search.strategy BinarySearchStrategy
Nome da classe de
estratégia de pesquisa a
ser usado ao mesmo
tempo encontrar a
chave.Apoiamos
BinarySearchStrategy e
InterpolationSearchStrateg
y
readonly.data.directory$ {Data.directory} /
somente leitura
O diretório para
armazenar arquivos de
dados somente leitura.
readonly.delete.backup.ms 0
Milissegundo esperamos
antes de apagar dados
antigos. Útil para diminuir
IO durante swap.
Configuração de armazenamento de Slop
slop.enable verdadeiro
Queremos iniciar um
mecanismo de
armazenamento de água
suja + ter o trabalho
habilitado?
slop.store.engine bdb
O mecanismo de
armazenamento que
devemos usar para
armazenar mensagens
misdelivered que precisam
ser redirecionado?
slop.pusher.enable verdadeiro Ativar o trabalho
empurrador slop que
empurra cada
'slop.frequency.ms' ms
(Pré-requisito -
slop.enable = true)
slop.read.byte.per.sec 10 * 1000 * 1000 Slop max ler rendimento
slop.write.byte.per.sec 10 * 1000 * 1000Slop máximo escrever
rendimento
pusher.typeStreamingSlopPusherJo
b
Tipo de trabalho a ser
usado para empurrar os
slops
slop.frequency.ms 5 * 60 * 1000Freqüência em que vamos
tentar empurrar os slops
Reequilíbrio configuração
enable.rebalancing verdadeiroPermitir reequilibrar
serviço?
max.rebalancing.attempts 3
Número de tentativas do
rebalancer lado do
servidor faz para buscar
dados
rebalancing.timeout.seconds 10 * 24 * 60 * 60
Vez que damos para o
lado do servidor
reequilíbrio para concluir a
cópia de dados
max.parallel.stores.rebalancin
g3
Lojas para reequilíbrio em
paralelo
rebalancing.optimization verdadeiro
Devemos executar o
nosso otimização
reequilíbrio para não
partição lojas
conscientes?
Configuração de retenção
retention.cleanup.first.start.ho
ur0
Hora em que deseja iniciar
o trabalho de limpeza
primeira retenção
retention.cleanup.period.hours 24
Execute o trabalho de
retenção de limpar cada n
horas
Configuração fofocas
enable.gossip falsoAtivar fofoca para
sincronizar o estado
gossip.interval.ms 30 * 1000 Ativar gossup cada ms n
Serviço de administração
admin.enable verdadeiroHabilitar o serviço de
administração?
admin.max.threads 20
O número máximo de
linhas utilizadas por
serviços de
administração. Usado por
BIO (ou seja, se
enable.nio.connector =
false)
admin.core.threadsmax (1, $
{admin.max.threads} / 2)
O número de segmentos
para manter viva pelo
serviço de administração,
mesmo quando
ocioso. Usado por BIO (ou
seja, se
enable.nio.connector =
false)
nio.admin.connector.selectorsmax (8, número de
processadores)
Número de threads seletor
para operações de
administração. Usado por
NIO (ou seja, se
enable.nio.connector =
true)
Núcleo Voldemort configuração do servidor
enable.nio.connector falsoAtivar NIO no lado do
servidor
nio.connector.selectorsmax (8, número de
processadores)
Número de threads seletor
para operações
normais. Usado por NIO
(ou seja, se
enable.nio.connector =
true)
max.threads 100 O número máximo de
threads o servidor pode
usar (Usado por HTTP e
BIO - enable.nio.connector
= false - único serviço)
core.threadsmax (1, $
{max.threads} / 2)
O número de segmentos
para manter viva mesmo
quando ocioso (Usado por
HTTP e BIO -
enable.nio.connector =
false - único serviço)
socket.timeout.ms 4000
O SO_TIMEOUT
soquete. Essencialmente
a quantidade de tempo de
bloquear em uma
operação de rede de baixo
nível antes de lançar um
erro.
routing.timeout.ms 5000
A quantidade total de
tempo para esperar por
respostas adequadas de
todos os nós antes de
lançar um erro.
stream.read.byte.per.sec 10 * 1000 * 1000
Max transferência de
leitura permitida quando
os fluxos de dados de
serviços de Admin
stream.write.byte.per.sec 10 * 1000 * 1000
Max rendimento gravação
permitida quando os fluxos
de dados de serviços de
Admin
http.enable verdadeiroAtivar o servidor de dados
HTTP?
socket.enable verdadeiroAtivar o servidor de dados
tomada?
jmx.enable verdadeiroPermitir o monitoramento
JMX?
enable.verbose.logging verdadeiroRegistrar cada operação
em todas as lojas.
enable.stat.tracking verdadeiro
Acompanhar as
estatísticas de carga nas
lojas.
scheduler.threads 6
Número de tópicos para
usar para trabalhos
programados
BDB Gestão
O armazenamento de chaves de valor subjacente é também importante para a
configuração e gestão da operação. Se BDB é usado, então toda a configuração é
feita através do arquivo server.properties. Se o MySQL é usado então
administração mysql habitual deve ser feito.
A Oracle tem um writeup que dá uma boa visão da parte operacional da BDB.
Configuração do cliente
As definições acima foram todos para o servidor. É importante configurar
correctamente o cliente também.Segue uma lista de opções de configuração para
os clientes:
nome omissão descrição
max_connections 50
O número máximo
permitido de ligação
para cada nó voldemort
max_threads 5
O número máximo de
segmentos de clientes
(usada pelo pool de
thread do cliente)
max_queued_requests 50
O número máximo de
operações de nós na fila
antes de ações do
cliente será bloqueado
(usada pelo pool de
thread do cliente)
thread_idle_ms 100000
A quantidade de tempo
para manter um
segmento de cliente
inativo vivo (usada pelo
pool de thread do
cliente)
connection_timeout_ms 500 Definir o tempo máximo
permitido para bloquear
à espera de uma ligação
gratuita
socket_timeout_ms 5000
Máxima quantidade de
tempo que o socket irá
bloquear a espera por
atividade de rede
routing_timeout_ms 15000
Definir o tempo limite
para todas as operações
de bloqueio para
completar em todos os
nós. O número de
operações de bloqueio
pode ser configurado
usando o preferido as
leituras e preferenciais
escreve-configuração
para a loja.
seletores 8
Número de seletores
utilizado para pedidos de
multiplexação em nosso
cliente NIO
socket_buffer_size 64 * 1024
Defina o tamanho do
buffer de socket (em
bytes) de usar tanto para
tomada de lê e escreve
soquete
enable_jmx verdadeiroPermitir o
monitoramento JMX
enable_pipeline_routed_store verdadeiro
Use a loja novo oleoduto
encaminhado para o
lado cliente de
roteamento
max_bootstrap_retries 2
Número de vezes que
vai tentar se conectar a
url do bootstrap
bootstrap_urls Parâmetro obrigatório
Separados por vírgula
lista de URLs para usar
servidores como de
bootstrap
serializer_factory_class Fábrica serializador com Personalizado
suporte para avro, pb,
java, etc
serializador nome da
classe fábrica
client_zone_id 0
Zona ID onde o cliente
reside.Usado para fazer
a decisão mais
inteligente de
roteamento em caso de
"zona de roteamento '
Detector de falha configs
failuredetector_implementationBannagePeriodFailureD
etector
Nome da classe do
detector de falha que o
cliente irá
utilizar.Apoiamos
BannagePeriodFailureD
etector e
ThresholdFailureDetecto
r
failuredetector_bannage_period 30000
BannagePeriodFailureD
etector: O número de
milissegundos este nó é
considerado como
'proibido'
failuredetector_threshold_count
minimum10
ThresholdFailureDetecto
r: Número mínimo de
falhas que devem
ocorrer antes que o
índice de sucesso é
verificado contra o limiar
failuredetector_threshold_interv
al10000
ThresholdFailureDetecto
r: intervalo de
milissegundos para o
qual o limite é válido, é
'reset' após esse período
é excedido
failuredetector_threshold 80
ThresholdFailureDector:
A representação
percentual inteiro do
limiar que devem ser
cumpridos ou excedidos
Algumas sugestões adicionais
JVM Configurações
No LinkedIn mantemos dois conjuntos de clusters, somente leitura e de leitura e escrita. Os cachos de leitura e escrita são clusters usando lojas BDB e têm características totalmente diferentes daquelas JVM usando somente leitura lojas. Aqui é o que usamos no LinkedIn para nossas leitura-gravação lojas:
# Min, max, tamanho total de JVM JVM_SIZE = "-server-Xms22g Xmx22g"
# Novos Tamanhos Geração JVM_SIZE_NEW = "-XX: NewSize = 2048m-XX: MaxNewSize =
2048m"
# Tipo de coletor de lixo para usarJVM_GC_TYPE = "-XX: + UseConcMarkSweepGC-XX: +
UseParNewGC"
# Ajustando opções para o coletor de lixo acimaJVM_GC_OPTS = "-XX: CMSInitiatingOccupancyFraction =
70-XX: SurvivorRatio = 2"
# JVM atividade GC configurações de logJVM_GC_LOG = "-XX: + PrintTenuringDistribution-XX: +
PrintGCDetails-XX: + PrintGCDateStamps-Xloggc: $ LOG_DIR / gc.log"Esta é a configuração em uma caixa de RAM 32GB com um tamanho de cache BDB de 10GB e 3 tópicos mais limpas. Há duas coisas importantes aqui: (1) cache BDB deve caber na pilha ou então ele não vai funcionar (obviamente), (2) você deve usar a marca concorrente e varredura gc ou então o GC pausas da coleta de tais monte um grande causará períodos sem resposta (isso não acontece no primeiro ou, se arrasta para cima e depois, eventualmente, entra em uma espiral de morte gc pausa).
Para os clusters de somente leitura que usamos as mesmas configurações de JVM
GC, exceto o tamanho da pilha é definido para um valor menor.
# Min, max, tamanho total de JVM JVM_SIZE = "-server-Xms4096m-Xmx4096m"
Isso é feito porque, no caso de somente leitura lojas contamos com o cache da página OS e realmente não queremos que a nossa pilha da JVM para ocupar espaço.
Publicar / Assinar APISistemas de armazenamento tornaram-se muito mais especializado nos últimos anos com
cada sistema de fornecimento de conhecimentos em determinadas áreas-Hadoop e
armazéns de dados proprietários fornecer capacidades de processamento em lote, os
índices de pesquisa fornecem suporte para consultas complexas texto classificados, e uma
variedade de bancos de dados distribuídos surgiram. Voldemort é um sistema de valores-
chave especializada, mas os mesmos dados armazenados no Voldemort pode precisar de
ser indexados por pesquisa, agitaram mais em Hadoop, ou processados por outro
sistema. Cada um desses sistemas tem a possibilidade de subscrever as mudanças que
acontecem em Voldemort e obter um fluxo de tais mudanças que eles podem processar
em sua própria maneira especializada.
Na verdade nós até mesmo Voldemort poderia subscrever um ao outro como um
mecanismo rápido catch-up para a recuperação de falhas.
Amazônia tem implementado essa funcionalidade como uma "árvore Merkle" estrutura de
dados em seu sistema que permite que nós Dynamo de comparar os seus conteúdos de
forma rápida e pegar até diferenças que eles perderam, mas isso não é a única
abordagem. Poderia ser um simples índice secundário que implementa um contador
específico do nó lógico que rastreia número de modificação para cada chave.
A API que seria fornecido seria algo como getAllChangesSince (ChangeNumber int), e
esta api daria a última alteração para cada chave.
Interface operacional
Um dos problemas principais para um sistema prático distribuído é saber o estado do
sistema. Voldemort tem um rudimentar GUI que fornece informações básicas. Este projeto
seria fazer uma primeira taxa de gestão de GUI e funcionalidades de controle
correspondente a ser capaz de conhecer o desempenho ea disponibilidade de cada nó do
sistema, bem como realizar operações mais intensas como iniciar / parar os nós, a
restauração de replicação, o reequilíbrio, etc .
Scala Voldemort Shell
Voldemort vem com um shell de texto muito simples. A melhor maneira de construir uma
coisa é integrar completamente uma língua com um intérprete e fornecer um conjunto de
comandos administrativos pré-definidos como funções no shell. Scala tem uma sintaxe
flexível e integra-se facilmente com o Java de modo que seria uma boa escolha para tal
uma casca.
Suporte para LevelDB mecanismo de armazenamento
Desde Voldemort suporta um interface do mecanismo de armazenamento conectável, nós
definitivamente queremos tentar outras soluções. Por exemplo, temos um Krati mecanismo
de armazenamento baseado em contrib. Outro mecanismo de armazenamento que é
pegar um impulso do Google é LevelDB . A primeira fase deste projeto exigiria a
construção de JNA / JNI ligações para o mecanismo de armazenamento seguido pela
integração com Voldemort.
DESCANSAR baseado APIAlém dos já existentes Ruby / Python clientes com um RESTO baseada API iria aumentar
a adoção entre a comunidade web. Um bom v1 poderia derivar idéias existentes bem sabe
sistemas como Riak
Memcache suporte ao protocolo
Um projeto fácil seria a de fornecer a mesma API como Memcache.
Pedido de ajuda Duplex
O trabalho preliminar foi feito para apoiar os nossos pedidos de impressão duplex
soquete. Isso seria minimizar o impacto da latência de rede em centros de dados. Alguns
pensamentos iniciais podem ser encontrados aqui
Apoio Maven
Queremos adicionar a capacidade de empurrar frascos em um repositório Maven central.
Melhor sistema de configuração
Os XML arquivos podem ficar realmente fora de controle, uma vez que aumenta o
tamanho de cluster. Migrando do XML para YAML iria aliviar este problema um pouco.
No longo prazo, gostaríamos de chegar a um melhor sistema de configuração (Explore
Zookeeper?)