Tornando-se social com o Azure Cosmos DB

APLICA-SE A: NoSQL MongoDB Cassandra Gremlin Tabela

Viver em uma sociedade massivamente interconectada significa que, em algum momento da vida, você se torna parte de uma rede social. Você usa as redes sociais para manter contato com amigos, colegas, familiares ou, às vezes, para compartilhar sua paixão com pessoas com interesses comuns.

Como engenheiros ou desenvolvedores, você deve ter se perguntado como essas redes armazenam e interconectam seus dados. Ou você pode até ter sido encarregado de criar ou arquitetar uma nova rede social para um nicho de mercado específico. É aí que surge a pergunta significativa: como todos esses dados são armazenados?

Suponha que você esteja criando uma nova e brilhante rede social onde seus usuários podem postar artigos com mídia relacionada, como fotos, vídeos ou até mesmo música. Os usuários podem comentar as postagens e dar pontos para classificações. Haverá um feed de posts que os usuários verão e interagirão na página de destino principal do site. Este método não parece complexo à primeira vista, mas por uma questão de simplicidade, vamos parar por aí. (Você pode se aprofundar em feeds de usuário personalizados afetados por relacionamentos, mas isso vai além do objetivo deste artigo.)

Então, como você armazena esses dados e onde?

Você pode ter experiência em bancos de dados SQL ou ter uma noção de modelagem relacional de dados. Você pode começar a desenhar algo da seguinte maneira:

Diagrama ilustrando um modelo relacional relativo

Uma estrutura de dados perfeitamente normalizada e bonita... Isso não escala.

Não me interpretem mal, trabalhei com bases de dados SQL toda a minha vida. Eles são ótimos, mas como todos os padrões, práticas e plataformas de software, não são perfeitos para todos os cenários.

Por que o SQL não é a melhor escolha nesse cenário? Vejamos a estrutura de um único post. Se eu quisesse mostrar o post em um site ou aplicativo, eu teria que fazer uma consulta com... juntando oito mesas (!) apenas para mostrar um único post. Agora imagine um fluxo de posts que carregam dinamicamente e aparecem na tela, e você pode ver para onde estou indo.

Você pode usar uma enorme instância SQL com poder suficiente para resolver milhares de consultas com muitas junções para servir seu conteúdo. Mas por que você, quando existe uma solução mais simples?

A estrada NoSQL

Este artigo orienta você a modelar os dados da sua plataforma social com o banco de dados NoSQL do Azure Azure Cosmos DB de forma econômica. Ele também informa como usar outros recursos do Azure Cosmos DB, como a API para Gremlin. Usando uma abordagem NoSQL , armazenando dados, em formato JSON e aplicando desnormalização, o post anteriormente complicado pode ser transformado em um único documento:

{
    "id":"ew12-res2-234e-544f",
    "title":"post title",
    "date":"2016-01-01",
    "body":"this is an awesome post stored on NoSQL",
    "createdBy":User,
    "images":["https://myfirstimage.png","https://mysecondimage.png"],
    "videos":[
        {"url":"https://myfirstvideo.mp4", "title":"The first video"},
        {"url":"https://mysecondvideo.mp4", "title":"The second video"}
    ],
    "audios":[
        {"url":"https://myfirstaudio.mp3", "title":"The first audio"},
        {"url":"https://mysecondaudio.mp3", "title":"The second audio"}
    ]
}

E pode ser obtido com uma única consulta e sem junções. Esta consulta é muito simples e direta e, em termos orçamentais, requer menos recursos para alcançar um melhor resultado.

O Azure Cosmos DB garante que todas as propriedades sejam indexadas com sua indexação automática. A indexação automática pode até ser personalizada. A abordagem sem esquema nos permite armazenar documentos com estruturas diferentes e dinâmicas. Talvez amanhã você queira que os posts tenham uma lista de categorias ou hashtags associadas a eles? O Azure Cosmos DB tratará os novos Documentos com os atributos adicionados sem trabalho extra exigido por nós.

Os comentários numa publicação podem ser tratados como outras publicações com uma propriedade principal. (Essa prática simplifica o mapeamento de objetos.)

{
    "id":"1234-asd3-54ts-199a",
    "title":"Awesome post!",
    "date":"2016-01-02",
    "createdBy":User2,
    "parent":"ew12-res2-234e-544f"
}

{
    "id":"asd2-fee4-23gc-jh67",
    "title":"Ditto!",
    "date":"2016-01-03",
    "createdBy":User3,
    "parent":"ew12-res2-234e-544f"
}

E todas as interações sociais podem ser armazenadas em um objeto separado como contadores:

{
    "id":"dfe3-thf5-232s-dse4",
    "post":"ew12-res2-234e-544f",
    "comments":2,
    "likes":10,
    "points":200
}

Criar feeds é apenas uma questão de criar documentos que podem conter uma lista de IDs de postagem com uma determinada ordem de relevância:

[
    {"relevance":9, "post":"ew12-res2-234e-544f"},
    {"relevance":8, "post":"fer7-mnb6-fgh9-2344"},
    {"relevance":7, "post":"w34r-qeg6-ref6-8565"}
]

Você pode ter um fluxo "mais recente" com posts ordenados por data de criação. Ou você pode ter um fluxo "mais quente" com aqueles posts com mais curtidas nas últimas 24 horas. Você pode até mesmo implementar um fluxo personalizado para cada usuário com base em lógica, como seguidores e interesses. Seria ainda uma lista de posts. É uma questão de como construir essas listas, mas o desempenho de leitura permanece sem obstáculos. Depois de adquirir uma dessas listas, você emite uma única consulta ao Azure Cosmos DB usando a palavra-chave IN para obter páginas de postagens de cada vez.

Os fluxos de feed podem ser criados usando os processos em segundo plano dos Serviços de Aplicativo do Azure: Webjobs. Depois que uma postagem é criada, o processamento em segundo plano pode ser acionado usando Filas de Armazenamento do Azure e Webjobs acionados usando o SDK de Webjobs do Azure, implementando a propagação de postagem dentro de fluxos com base em sua própria lógica personalizada.

Pontos e curtidas em uma postagem podem ser processados de forma diferida usando essa mesma técnica para criar um ambiente eventualmente consistente.

Os seguidores são mais complicados. O Azure Cosmos DB tem um limite de tamanho de documento e a leitura/gravação de documentos grandes pode afetar a escalabilidade do seu aplicativo. Então você pode pensar em armazenar seguidores como um documento com esta estrutura:

{
    "id":"234d-sd23-rrf2-552d",
    "followersOf": "dse4-qwe2-ert4-aad2",
    "followers":[
        "ewr5-232d-tyrg-iuo2",
        "qejh-2345-sdf1-ytg5",
        //...
        "uie0-4tyg-3456-rwjh"
    ]
}

Essa estrutura pode funcionar para um usuário com alguns milhares de seguidores. Se alguma celebridade se juntar às fileiras, no entanto, essa abordagem levará a um tamanho de documento grande, e pode eventualmente atingir o limite de tamanho do documento.

Para resolver esse problema, você pode usar uma abordagem mista. Como parte do documento Estatísticas do Usuário, você pode armazenar o número de seguidores:

{
    "id":"234d-sd23-rrf2-552d",
    "user": "dse4-qwe2-ert4-aad2",
    "followers":55230,
    "totalPosts":452,
    "totalPoints":11342
}

Você pode armazenar o gráfico real de seguidores usando a API do Azure Cosmos DB para Gremlin para criar vértices para cada usuário e bordas que mantêm as relações "A-follows-B". Com a API para Gremlin, você pode obter os seguidores de um determinado usuário e criar consultas mais complexas para sugerir pessoas em comum. Se você adicionar ao gráfico as Categorias de Conteúdo que as pessoas gostam ou gostam, você pode começar a tecer experiências que incluem descoberta de conteúdo inteligente, sugerindo conteúdo que as pessoas que você segue gostam ou encontrar pessoas com as quais você pode ter muito em comum.

O documento Estatísticas do usuário ainda pode ser usado para criar cartões na interface do usuário ou visualizações rápidas de perfil.

O padrão "Ladder" e a duplicação de dados

Como você deve ter notado no documento JSON que faz referência a uma postagem, há muitas ocorrências de um usuário. E você teria adivinhado certo, essas duplicatas significam que as informações que descrevem um usuário, dada essa desnormalização, podem estar presentes em mais de um lugar.

Para permitir consultas mais rápidas, você incorre em duplicação de dados. O problema com este efeito colateral é que, se por alguma ação, os dados de um usuário mudam, você precisa encontrar todas as atividades que o usuário já fez e atualizá-las todas. Não parece prático, certo?

Você vai resolvê-lo identificando os principais atributos de um usuário que você mostra em seu aplicativo para cada atividade. Se você mostra visualmente uma postagem em seu aplicativo e mostra apenas o nome e a imagem do criador, por que armazenar todos os dados do usuário no atributo "createdBy"? Se para cada comentário você apenas mostrar a foto do usuário, você realmente não precisa do resto das informações do usuário. É aí que algo que eu chamo de "padrão Ladder" se envolve.

Tomemos as informações do usuário como exemplo:

{
    "id":"dse4-qwe2-ert4-aad2",
    "name":"John",
    "surname":"Doe",
    "address":"742 Evergreen Terrace",
    "birthday":"1983-05-07",
    "email":"john@doe.com",
    "twitterHandle":"\@john",
    "username":"johndoe",
    "password":"some_encrypted_phrase",
    "totalPoints":100,
    "totalPosts":24
}

Ao olhar para essas informações, você pode detetar rapidamente quais são informações críticas e quais não são, criando assim uma "Escada":

Diagrama de um padrão de escada

A menor etapa é chamada de UserChunk, a informação mínima que identifica um usuário e é usada para duplicação de dados. Ao reduzir o tamanho dos dados duplicados para apenas as informações que você "mostrará", você reduz a possibilidade de atualizações massivas.

A etapa do meio é chamada de usuário. São os dados completos que serão usados na maioria das consultas dependentes de desempenho no Azure Cosmos DB, as mais acessadas e críticas. Inclui as informações representadas por um UserChunk.

O maior é o Usuário Estendido. Ele inclui as informações críticas do usuário e outros dados que não precisam ser lidos rapidamente ou têm uso eventual, como o processo de login. Esses dados podem ser armazenados fora do Azure Cosmos DB, no Banco de Dados SQL do Azure ou nas Tabelas de Armazenamento do Azure.

Por que você dividiria o usuário e até armazenaria essas informações em lugares diferentes? Porque do ponto de vista do desempenho, quanto maiores os documentos, mais caras são as consultas. Mantenha os documentos finos, com as informações certas para fazer todas as suas consultas dependentes do desempenho para a sua rede social. Armazene as outras informações extras para eventuais cenários, como edições de perfil completo, logins e mineração de dados para análises de uso e iniciativas de Big Data. Você realmente não se importa se a coleta de dados para mineração de dados for mais lenta, porque está sendo executada no Banco de Dados SQL do Azure. Você teme, no entanto, que seus usuários tenham uma experiência rápida e fina. Um usuário armazenado no Azure Cosmos DB teria esta aparência:

{
    "id":"dse4-qwe2-ert4-aad2",
    "name":"John",
    "surname":"Doe",
    "username":"johndoe"
    "email":"john@doe.com",
    "twitterHandle":"\@john"
}

E um Post ficaria como:

{
    "id":"1234-asd3-54ts-199a",
    "title":"Awesome post!",
    "date":"2016-01-02",
    "createdBy":{
        "id":"dse4-qwe2-ert4-aad2",
        "username":"johndoe"
    }
}

Quando uma edição surge onde um atributo de bloco é afetado, você pode encontrar facilmente os documentos afetados. Basta usar consultas que apontem para os atributos indexados, como SELECT * FROM posts p WHERE p.createdBy.id == "edited_user_id", e atualizar os blocos.

Os usuários gerarão, felizmente, muito conteúdo. E você deve ser capaz de fornecer a capacidade de pesquisar e encontrar conteúdo que pode não estar diretamente em seus fluxos de conteúdo, talvez porque você não segue os criadores, ou talvez você esteja apenas tentando encontrar aquele post antigo que você fez há seis meses.

Como você está usando o Azure Cosmos DB, pode implementar facilmente um mecanismo de pesquisa usando o Azure AI Search em poucos minutos sem digitar nenhum código, além do processo de pesquisa e da interface do usuário.

Porque é que este processo é tão fácil?

O Azure AI Search implementa o que eles chamam de Indexadores, processos em segundo plano que se conectam em seus repositórios de dados e adicionam, atualizam ou removem automaticamente seus objetos nos índices. Eles dão suporte a indexadores do Banco de Dados SQL do Azure, indexadores de Blobs do Azure e, felizmente, indexadores do Azure Cosmos DB. A transição de informações do Azure Cosmos DB para o Azure AI Search é simples. Ambas as tecnologias armazenam informações no formato JSON, então você só precisa criar seu índice e mapear os atributos de seus documentos que deseja indexar. Está feito! Dependendo do tamanho dos seus dados, todo o seu conteúdo estará disponível para ser pesquisado em poucos minutos pela melhor solução de Pesquisa como Serviço em infraestrutura de nuvem.

Para obter mais informações sobre o Azure AI Search, visite o Guia do Mochileiro para Pesquisar.

Os conhecimentos subjacentes

Depois de armazenar todo esse conteúdo que cresce e cresce a cada dia, você pode encontrar pensando: O que posso fazer com todo esse fluxo de informações dos meus usuários?

A resposta é simples: coloque-o a trabalhar e aprenda com ele.

Mas o que você pode aprender? Alguns exemplos fáceis incluem análise de sentimento, recomendações de conteúdo com base nas preferências de um usuário ou até mesmo um moderador de conteúdo automatizado que garante que o conteúdo publicado pela sua rede social seja seguro para a família.

Agora que eu te viciei, você provavelmente vai pensar que precisa de algum PhD em ciências matemáticas para extrair esses padrões e informações de bancos de dados e arquivos simples, mas você estaria errado.

O Azure Machine Learning é um serviço de nuvem totalmente gerenciado que permite criar fluxos de trabalho usando algoritmos em uma interface simples de arrastar e soltar, codificar seus próprios algoritmos em R ou usar algumas das APIs já criadas e prontas para usar, como: Análise de Texto, Moderador de Conteúdo ou Recomendações.

Para obter qualquer um desses cenários de Aprendizado de Máquina, você pode usar o Azure Data Lake para ingerir as informações de diferentes fontes. Você também pode usar o U-SQL para processar as informações e gerar uma saída que pode ser processada pelo Azure Machine Learning.

Outra opção disponível é usar os serviços de IA do Azure para analisar o conteúdo de seus usuários, não apenas você pode entendê-los melhor (analisando o que eles escrevem com a API de Análise de Texto), mas também pode detetar conteúdo indesejado ou maduro e agir de acordo com a API de Visão Computacional. Os serviços de IA do Azure incluem muitas soluções prontas para uso que não exigem nenhum tipo de conhecimento de Machine Learning para serem usadas.

Uma experiência social à escala planetária

Há um último, mas não menos importante, artigo importante que devo abordar: escalabilidade. Quando você projeta uma arquitetura, cada componente deve ser dimensionado por conta própria. Eventualmente, você precisará processar mais dados, ou você vai querer ter uma cobertura geográfica maior. Felizmente, realizar ambas as tarefas é uma experiência completa com o Azure Cosmos DB.

O Azure Cosmos DB oferece suporte ao particionamento dinâmico pronto para uso. Ele cria automaticamente partições com base em uma determinada chave de partição, que é definida como um atributo em seus documentos. A definição da chave de partição correta deve ser feita em tempo de design. Para obter mais informações, consulte Particionamento no Azure Cosmos DB.

Para uma experiência social, você deve alinhar sua estratégia de particionamento com a maneira como você consulta e escreve. (Por exemplo, leituras dentro da mesma partição são desejáveis e evitam "pontos de acesso" espalhando gravações em várias partições.) Algumas opções são: partições baseadas em uma chave temporal (dia/mês/semana), por categoria de conteúdo, por região geográfica ou por usuário. Tudo realmente depende de como você consultará os dados e mostrará os dados em sua experiência social.

O Azure Cosmos DB executará suas consultas (incluindo agregações) em todas as partições de forma transparente, para que você não precise adicionar nenhuma lógica à medida que seus dados crescem.

Com o tempo, você acabará crescendo em tráfego e seu consumo de recursos (medido em RUs ou Unidades de Solicitação) aumentará. Você lerá e escreverá com mais frequência à medida que sua base de usuários crescer. A base de usuários começará a criar e ler mais conteúdo. Portanto, a capacidade de dimensionar sua taxa de transferência é vital. Aumentar as suas RUs é fácil. Você pode fazer isso com alguns cliques no portal do Azure ou emitindo comandos por meio da API.

Dimensionamento e definição de uma chave de partição

O que acontece se as coisas continuarem a melhorar? Suponha que os utilizadores de outro país/região ou continente reparem na sua plataforma e comecem a utilizá-la. Que grande surpresa!

Mas espere! Você logo percebe que a experiência deles com sua plataforma não é a ideal. Eles estão tão longe da sua região operacional que a latência é terrível. Você obviamente não quer que eles desistam. Se ao menos houvesse uma maneira fácil de ampliar seu alcance global? Tem!

O Azure Cosmos DB permite replicar seus dados globalmente e de forma transparente com alguns cliques e selecionar automaticamente entre as regiões disponíveis do seu código de cliente. Esse processo também significa que você pode ter várias regiões de failover.

Quando você replica seus dados globalmente, precisa ter certeza de que seus clientes podem aproveitá-los. Se você estiver usando um frontend da Web ou acessando APIs de clientes móveis, poderá implantar o Gerenciador de Tráfego do Azure e clonar seu Serviço de Aplicativo do Azure em todas as regiões desejadas, usando uma configuração de desempenho para dar suporte à sua cobertura global estendida. Quando seus clientes acessarem seu frontend ou APIs, eles serão roteados para o Serviço de Aplicativo mais próximo, que, por sua vez, se conectará à réplica local do Azure Cosmos DB.

Adicionar cobertura global à sua plataforma social

Conclusão

Este artigo lança alguma luz sobre as alternativas de criar redes sociais completamente no Azure com serviços de baixo custo. ele fornece resultados, incentivando o uso de uma solução de armazenamento multicamadas e distribuição de dados chamada "Ladder".

Diagrama de interação entre os serviços do Azure para redes sociais

A verdade é que não há bala de prata para este tipo de cenários. É a sinergia criada pela combinação de excelentes serviços que nos permite criar grandes experiências: a velocidade e a liberdade do Azure Cosmos DB para fornecer uma excelente aplicação social, a inteligência por detrás de uma solução de pesquisa de primeira classe como o Azure AI Search, a flexibilidade dos Serviços de Aplicações do Azure para alojar nem sequer aplicações independentes de linguagem, mas processos em segundo plano poderosos e o Armazenamento do Azure expansível e a Base de Dados SQL do Azure para armazenar grandes quantidades de dados e o poder analítico do Azure Machine Learning para criar conhecimento e inteligência que podem fornecer feedback aos seus processos e ajudar-nos a fornecer o conteúdo certo aos utilizadores certos.

Próximos passos

Para saber mais sobre casos de uso do Azure Cosmos DB, consulte Casos de uso comuns do Azure Cosmos DB.