Banco de Dados

42
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

Transcript of Banco de Dados

Page 1: 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

Page 2: Banco de Dados

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

Page 3: Banco de Dados

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

Page 4: Banco de Dados

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.

Page 5: Banco de Dados

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

Page 6: Banco de Dados

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.

Page 7: Banco de Dados

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

Page 8: Banco de Dados

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:

Page 9: Banco de Dados

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,

Page 10: Banco de Dados

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

Page 11: Banco de Dados

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

Page 12: Banco de Dados

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

Page 13: Banco de Dados

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"}

Page 14: Banco de Dados

{"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

Page 15: Banco de Dados

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

Page 16: Banco de Dados

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.

Page 17: Banco de Dados

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>

Page 18: Banco de Dados

<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

Page 19: Banco de Dados

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

Page 20: Banco de Dados

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:

Page 21: Banco de Dados

<-! 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á

Page 22: Banco de Dados

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

Page 23: Banco de Dados

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

Page 24: Banco de Dados

é 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

Page 25: Banco de Dados

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

Page 26: Banco de Dados

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

Page 27: Banco de Dados

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

Page 28: Banco de Dados

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.

Page 29: Banco de Dados

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

Page 30: Banco de Dados

à 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

Page 31: Banco de Dados

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

Page 32: Banco de Dados

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

Page 33: Banco de Dados

í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.

Page 34: Banco de Dados

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?)