O Netflix recentemente apresentou o Hollow, uma biblioteca e um conjunto de ferramentas Java para processar datasets em memória que não são caracterizados como "big data." Como datasets podem conter metadata para e-commerce e motores de busca, ou no caso do Netflix, metadata sobre filmes e shows de TV. Soluções tradicionais para processar estes datasets requerem o uso de banco de dados ou serialização, mas normalmente sofrem de problemas de confiabilidade e latência. O guia de inicialização do Hollow resume os conceitos principais e a nomenclatura:
O Hollow gerencia datasets que são fornecidos por um simples producer, e disseminados somente com permissão de leitura para um ou vários consumers. Um dataset muda ao longo do tempo. A linha de tempo para um dataset em mudança pode ser dividida em discretos estados de dados, no qual cada um é um snapshot completo dos dados em um determinado ponto no tempo.
O producer e os consumer manipulam os datasets através de um state engine que transita entre os estados dos dados. Um producer usa um write state engine e um consumer usa um read state engine.
O Hollow substitui o framework anterior de dados em memória do Netflix, o Zeno. Os datasets agora são representados com uma codificação compacta, de tamanho fixo, fortemente tipada. Essa codificação minimiza o rastro dos datasets e os registros codificados são "agrupados dentro de pedaços reutilizáveis da memória que são armazenados na heap da JVM para evitar impactar o comportamento do GC em servidores muito ocupados."
Começando
Como ponto de partida, considere o seguinte POJO:
public class Movie { long id; String title; int releaseYear; public Movie(long id,String title,int releaseYear) { this.id = id; this.title = title; this.releaseYear = releaseYear; } }
Um simples dataset baseado no POJO acima pode ser populado como:
Listmovies = Arrays.asList( new Movie(1,"The Matrix",1999), new Movie(2,"Beasts of No Nation",2015), new Movie(3,"Goodfellas",1990), new Movie(4,"Inception",2010) ); O Hollow traduz a lista de filmes para o novo layout de codificação como mostrado a seguir:
Mais detalhes sobre essa codificação podem ser encontrados na seção Advanced Topics no website do Hollow.
O Producer
A primeira instância de um producer disponibiliza um estado dos dados inicial de um dataset (filmes neste exemplo) e consumers são notificados em onde encontrar esse conjunto de dados. Alterações subsequentes no conjunto de dados são sistematicamente publicados e comunicadas para os consumers.
Um producer usa um HollowWriteStateEngine como gerenciador para um dataset:
HollowWriteStateEngine writeEngine = new HollowWriteStateEngine();
Um HollowObjectMapper popula um HollowWriteStateEngine:
HollowObjectMapper objectMapper = new HollowObjectMapper(writeEngine); for(Movie movie : movies) { objectMapper.addObject(movie); }
O HollowObjectMapper é thread safe e também pode ser executado em paralelo.
O producer escreve o dataset (também conhecido como blob) em um determinado output stream:
OutputStream os = new BufferedOutputStream(new FileOutputStream(snapshotFile)); HollowBlobWriter writer = new HollowBlobWriter(writeEngine); writer.writeSnapshot(os);
Gerando uma API para Consumers
Uma API cliente gera o código Java necessário com base no modelo de dados e deve ser executado antes de escrever o código inicial do consumer:
HollowAPIGenerator codeGenerator = new HollowAPIGenerator( "MovieAPI", // um nome para a API "org.redlich.hollow.consumer.api.generated", // o path para os arquivos da API gerados stateEngine); // o state engine codeGenerator.generateFiles(apiCodeFolder);
O Consumer
Uma vez que o consumer é notificado de que um dataset foi publicado, o consumer usa um HollowWriteReadEngine para manipular o dataset:
HollowReadStateEngine readEngine = new HollowReadStateEngine();
Um HollowBlobReader consome um blob do producer dentro de um HollowReadStateEngine:
HollowBlobReader reader = new HollowBlobReader(readEngine); InputStream is = new BufferedInputStream(new FileInputStream(snapshotFile)); reader.readSnapshot(is);
Os dados dentro do dataset podem ser acessados através da API gerada:
MovieAPI movieAPI = consumer.getAPI(); for(MovieHollow movie : movieAPI.getAllMovieHollow()) { System.out.println(movie._getId() + ", " + movie._getTitle()._getValue() + ", " + movie._getReleaseYear()); }
O seguinte saída será exibida:
1, "The Matrix", 1999 2, "Beasts of No Nation", 2015 3, "Goodfellas", 1990 4,"Inception", 2010
Todo o projeto Hollow pode ser encontrado no GitHub.
A InfoQ recentemente apresentou uma entrevista detalhada com Drew Koszewnik, engenheiro de software senior na Netflix e contribuidor líder do Hollow, sobre os detalhes específicos da implementação do Hollow.
Ótimo post
by Michell Matheus Sarno Silva,
Ótimo post
by Michell Matheus Sarno Silva,
Seu comentário está aguardando aprovação dos moderadores. Obrigado por participar da discussão!
Leitura fácil de entender parabéns!