
Nós somos o departamento de desenvolvimento de tecnologias de varejo. Certa vez, a gestão nos desafiou a acelerar cálculos volumosos utilizando Apache Ignite em conjunto com o MSSQL, mostrando um site com ilustrações maravilhosas e exemplos de código Java. Gostei imediatamente do site, , cuja descrição promete maravilhas: você não precisa implantar manualmente seu código Java ou Scala em cada nó da grade e reimplantá-lo toda vez que mudar. Ao longo do trabalho, percebi que Zero Deployment tem peculiaridades de uso, cujas características quero compartilhar. Abaixo, reflexões e detalhes da implementação.
1. Definição da Tarefa
A essência da tarefa é a seguinte. Há um catálogo de pontos de venda SalesPoint e um catálogo de produtos Sku (Stock Keeping Unit). O ponto de venda tem um atributo "tipoLoja" com valores "pequena" e "grande". A cada ponto de venda, é conectado (carregado do SGBD) um sortimento (lista de produtos do ponto de venda) e é fornecida a informação de que, a partir da data especificada, o produto indicado
é excluído do sortimento ou adicionado ao sortimento.
É necessário organizar um cache particionado dos pontos de venda e armazenar nele informações sobre os produtos conectados um mês à frente. A compatibilidade com o sistema em produção exige que o nó cliente Ignite carregue os dados, calcule um agregado do tipo (tipoLoja, códigoProduto, dia, número_de_pontos_de_venda) e o exporte de volta ao SGBD.
2. Estudo da Literatura
Ainda não tenho experiência, então começo do básico. Ou seja, com uma revisão das publicações.
O artigo de 2016 contém um link para a documentação do projeto Apache Ignite e ainda critica a clareza dessa documentação. Li algumas vezes, a clareza não se estabelece. Recorro ao tutorial oficial , que
que promete otimisticamente "Você estará funcionando em um instante!". Estou analisando as configurações de variáveis de ambiente, assistindo a dois vídeos sobre Apache Ignite Essentials, que para minha tarefa específica não foram muito úteis. Consigo iniciar o Ignite a partir da linha de comando com o arquivo padrão "example-ignite.xml", montando o primeiro aplicativo com o Maven. O aplicativo funciona e utiliza Zero Deployment, que beleza!
Continuo lendo e o exemplo já usa affinityKey (criado anteriormente através de consulta SQL), e ainda aplica o misterioso BinaryObject:
IgniteCache people
= ignite.cache("Person").withKeepBinary(); Li : formato binário — algo como reflexão, acesso a campos de objeto pelo nome. Pode ler o valor de um campo sem a desserialização completa do objeto (economia de memória). Mas por que usar BinaryObject em vez de Person, já que existe o Zero Deployment? Por que IgniteCache é traduzido para IgniteCache? Ainda não está claro.
Estou adaptando a Aplicação de Cálculo para o meu caso. A chave primária do dicionário de pontos de venda no MSSQL é definida como [id] [int] NOT NULL, estou criando o cache por analogia.
IgniteCache salesPointCache=ignite.cache("spCache")No arquivo de configuração xml, indico que o cache é particionado.
O particionamento por pontos de venda pressupõe que o agregado necessário será construído em cada nó do cluster para os registros presentes no salesPointCache, e então o nó cliente realizará a soma final.
Estou lendo o tutorial. , estou fazendo por analogia. Em cada nó do cluster, inicio IgniteRunnable(), mais ou menos assim:
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}Adiciono a lógica de agregação e exportação, executo em um conjunto de dados de teste. Localmente, no servidor de desenvolvimento, tudo funciona.
Inicio dois servidores de teste CentOs, especifico os endereços IP no default-config.xml, executo em cada um.
./bin/ignite.sh config/default-config.xmlAmbos os nós Ignite são iniciados e se veem. Especifico os endereços necessários no arquivo de configuração xml da aplicação cliente, ela é iniciada, adiciona um terceiro nó à topologia e imediatamente o número de nós volta a ser dois. No log está registrado "ClassNotFoundException: model.SalesPoint" na linha
SalesPoint sp=salesPointCache.get(spId);O StackOverflow diz que a causa do erro é que os servidores CentOs não possuem a classe personalizada SalesPoint. Chegamos aqui. Como assim "você não precisa implantar manualmente seu código Java em cada nó" e assim por diante? Ou "seu código Java" — isso não diz respeito ao SalesPoint?
Provavelmente perdi alguma coisa — começo a procurar novamente, ler e buscar mais uma vez. Após algum tempo, sinto que li tudo sobre o assunto, nada novo foi encontrado. Enquanto buscava, encontrei algumas observações interessantes.
, Arquiteto Principal na GridGain Systems, no StackOverflow, abril de 2016:
As classes de modelo não são implantadas em pares, mas você pode usar a flag withKeepBinary() no cache e consultar BinaryObjects. Dessa forma, você evitará a desserialização no lado do servidor e não obterá ClassNotFoundException.Outra opinião respeitável: , Diretor de gerenciamento de produtos, GridGain Systems.
Artigo no Habr referencia três artigos de Denis Magda: , , Anos 2016-2017. No segundo artigo, Denis sugere iniciar o nó do cluster através do MaintenanceServiceNodeStartup.jar. Você também pode usar o início com uma configuração xml e linha de comando, mas nesse caso, precisa manualmente colocar as classes do usuário em cada nó do cluster implantado:
É isso. Inicie o nó usando o arquivo MaintenanceServiceNodeStartup ou passe maintenance-service-node-config.xml para os scripts ignite.sh/bat do Apache Ignite. Se você preferir o último, então, certifique-se de construir um arquivo jar que contenha todas as classes dos diretórios java/app/common e java/services/maintenance. O jar deve ser adicionado ao classpath de cada nó onde o serviço pode ser implantado.De fato, é isso. Aqui está, afinal, para que serve esse misterioso formato binário!
3. SingleJar
Denis ficou em primeiro lugar na minha classificação pessoal, na minha opinião, é o tutorial mais útil de todos os disponíveis. Em seu no GitHub está contido um exemplo totalmente pronto de configuração de nós do cluster, que compila sem qualquer complicação extra.
Estou seguindo seu exemplo e obtendo um único arquivo jar que inicia "data node" ou "client node" dependendo do argumento da linha de comando. A construção inicia e funciona. Zero Deployment derrotado.
A transição de megabytes de dados de teste para dezenas de gigabytes de dados de produção mostrou que o formato binário existe por uma razão. Foi necessário otimizar o uso de memória nos nós, e aqui o BinaryObject foi muito útil.
4. Conclusões
A primeira crítica que encontrei sobre a falta de clareza na documentação do projeto Apache Ignite se mostrou válida, desde 2016, pouco mudou. Para um novato, é difícil montar um protótipo funcional com base no site e/ou repositório.
Ao final do trabalho realizado, fiquei com a impressão de que o Zero Deployment funciona, mas apenas em nível sistêmico. Aproximadamente assim: o BinaryObject é utilizado para ensinar os nós remotos do cluster a trabalhar com classes do usuário; o Zero Deployment é um mecanismo interno
do próprio Apache Ignite e distribui objetos do sistema pelo cluster.
Espero que minha experiência seja útil para os novos usuários do Apache Ignite.
Fonte: habr.com
