Cursos gratuitos – Data Science Academy

Abaixo, alguns cursos gratuitos da Data Science Academy

Curso Gratuito de Microsoft Power BI (Carga Horária: 54 Horas):
Clique aqui
Curso Gratuito de Fundamentos de Big Data (Carga Horária: 8 Horas): 
Clique aqui
Curso Gratuito de Python Fundamentos para Análise de Dados (Carga Horária: 54 Horas):
Clique aqui
Curso Gratuito de Introdução a Ciência de Dados (Carga Horária: 8 Horas):
Clique aqui
Curso Gratuito de Fundamentos de Inteligência Artificial (Carga Horária: 8 Horas): 
Clique aqui

Exemplo de Modelagem Cassandra

Escolher o modelo de dados certo é a parte mais difícil de usar o Cassandra. Se você tiver um histórico relacional, o CQL parecerá familiar, mas a maneira como você o utiliza pode ser muito diferente. O objetivo deste post é explicar as regras básicas que você deve ter em mente ao projetar seu esquema para o Cassandra. Se você seguir essas regras, obterá um bom desempenho imediato. Melhor ainda, seu desempenho deve ser dimensionado linearmente à medida que você adiciona nós ao cluster.

Não-objetivos

Os desenvolvedores que vêm de um background relacional geralmente carregam regras sobre modelagem relacional e tentam aplicá-las a Cassandra. Para evitar perder tempo com regras que realmente não importam com o Cassandra, quero destacar algumas não- metas:

Minimize o número de gravações

As gravações em Cassandra não são gratuitas, mas são muito baratas. O Cassandra é otimizado para alta taxa de transferência, e quase todas as gravações são igualmente eficientes [1] . Se você pode realizar gravações extras para melhorar a eficiência de suas consultas de leitura, quase sempre é uma boa compensação. As leituras tendem a ser mais caras e são muito mais difíceis de ajustar.

Minimize a duplicação de dados

Desnormalização e duplicação de dados é um fato da vida com Cassandra. Não tenha medo disso. Geralmente, o espaço em disco é o recurso mais barato (comparado à CPU, memória, IOPs de disco ou rede), e Cassandra é arquitetada em torno desse fato. Para obter as leituras mais eficientes, você geralmente precisa duplicar os dados.

Além disso, a Cassandra não tem o JOIN s, e você não quer realmente usá-los de maneira distribuída.

Objetivos Básicos

Estas são as duas metas de alto nível para seu modelo de dados:

  1. Espalhar dados uniformemente ao redor do cluster
  2. Minimize o número de partições lidas

Há outras metas menores a serem lembradas, mas estas são as mais importantes. Na maioria das vezes, vou me concentrar no básico de alcançar esses dois objetivos.Existem outros truques que você pode usar, mas você deve saber como avaliá-los primeiro.

Regra 1: espalhar dados uniformemente em torno do cluster

Você deseja que todos os nós do cluster tenham aproximadamente a mesma quantidade de dados. Cassandra torna isso fácil, mas não é um dado. As linhas são espalhadas pelo cluster com base em um hash da chave de partição , que é o primeiro elemento da PRIMARY KEY . Então, a chave para espalhar dados uniformemente é esta: escolha uma boa chave primária . Vou explicar como fazer isso daqui a pouco.

Regra 2: Minimizar o número de partições lidas

Partições são grupos de linhas que compartilham a mesma chave de partição. Quando você emite uma consulta de leitura, deseja ler as linhas do menor número possível de partições.

Por que isso é importante? Cada partição pode residir em um nó diferente. O coordenador geralmente precisará emitir comandos separados para separar nós para cada partição solicitada. Isso adiciona muita sobrecarga e aumenta a variação na latência. Além disso, mesmo em um único nó, é mais caro ler de várias partições do que de uma única, devido à maneira como as linhas são armazenadas.

Regras conflitantes?

Se é bom minimizar o número de partições das quais você lê, por que não colocar tudo em uma única partição grande? Você acabaria violando a Regra nº 1, que é espalhar dados uniformemente pelo cluster.

O ponto é que esses dois objetivos geralmente estão em conflito, então você precisa tentar equilibrá-los.

Modelo em torno de suas consultas

A maneira de minimizar as leituras de partição é modelar seus dados para atender às suas consultas. Não modele em torno de relações. Não modele em torno de objetos.Modelo em torno de suas consultas. Veja como você faz isso:

Etapa 1: determine quais consultas devem ser suportadas

Tente determinar exatamente quais consultas você precisa dar suporte. Isso pode incluir muitas considerações que você pode não pensar no início. Por exemplo, você pode precisar pensar sobre:

  • Agrupamento por um atributo
  • Ordenação por um atributo
  • Filtrando com base em algum conjunto de condições
  • Impondo exclusividade no conjunto de resultados
  • etc …

As alterações em apenas um desses requisitos de consulta geralmente garantirão uma alteração do modelo de dados para máxima eficiência.

Etapa 2: tente criar uma tabela onde você possa satisfazer sua consulta lendo (aproximadamente) uma partição

Na prática, isso geralmente significa que você usará aproximadamente uma tabela por padrão de consulta. Se você precisar oferecer suporte a vários padrões de consulta, geralmente precisará de mais de uma tabela.

Para colocar isso de outra forma, cada tabela deve pré-construir a “resposta” para uma consulta de alto nível que você precisa dar suporte. Se você precisa de diferentes tipos de respostas, geralmente precisa de tabelas diferentes. É assim que você otimiza para leituras.

Lembre-se, a duplicação de dados está bem. Muitas de suas tabelas podem repetir os mesmos dados.

Aplicando as regras: exemplos

Para mostrar alguns exemplos de um bom processo, vou orientá-lo no design de um modelo de dados para alguns problemas simples.

Exemplo 1: pesquisa de usuário

O requisito de alto nível é “nós temos usuários e queremos procurá-los”. Vamos seguir os passos:

Etapa 1 : Determinar quais consultas específicas para suporte 
Digamos que queremos ser capazes de procurar um usuário pelo nome de usuário ou pelo e-mail. Com o método de pesquisa, devemos obter o conjunto completo de detalhes do usuário.

Etapa 2 : tente criar uma tabela onde você possa satisfazer sua consulta lendo (aproximadamente) uma partição 
Como queremos obter todos os detalhes para o usuário com o método de pesquisa, é melhor usar duas tabelas:

1234567891011CREATE TABLE users_by_username (username text PRIMARY KEY,email text,age int) CREATE TABLE users_by_email (email text PRIMARY KEY,username text,age int)

Agora, vamos verificar as duas regras para este modelo:

Espalha os dados uniformemente? Cada usuário recebe sua própria partição, então sim. 
Partições mínimas são lidas? Nós só temos que ler uma partição, então sim.

Agora, vamos supor que tentamos otimizar para os não- objetivos e, em vez disso, criamos esse modelo de dados:

12345678910111213141516CREATE TABLE users (id uuid PRIMARY KEY,username text,email text,age int) CREATE TABLE users_by_username (username text PRIMARY KEY,id uuid) CREATE TABLE users_by_email (email text PRIMARY KEY,id uuid)

Esse modelo de dados também distribui os dados de maneira uniforme, mas há uma desvantagem: agora temos que ler duas partições, uma de users_by_username (ou users_by_email ) e outra de usuários . Portanto, as leituras são aproximadamente duas vezes mais caras.

Exemplo 2: grupos de usuários

Agora o requisito de alto nível mudou. Os usuários estão em grupos e queremos que todos os usuários entrem em um grupo.

Etapa 1 : Determinar quais consultas específicas para suporte 
Queremos obter as informações completas do usuário para cada usuário em um grupo específico. Ordem dos usuários não importa.

Etapa 2 : tente criar uma tabela onde você possa satisfazer sua consulta lendo (aproximadamente) uma partição 
Como podemos encaixar um grupo em uma partição? Podemos usar um PRIMARY KEY composto para isso:

1234567CREATE TABLE groups (groupname text,username text,email text,age int,PRIMARY KEY (groupname, username))

Observe que a PRIMARY KEY tem dois componentes: groupname , que é a chave de particionamento, e username , que é chamado de chave de clustering. Isso nos dará uma partição por nome de grupo . Dentro de uma determinada partição (grupo), as linhas serão ordenadas por nome de usuário . Buscar um grupo é tão simples quanto fazer o seguinte:

1SELECT * FROM groups WHERE groupname = ?

Isso satisfaz o objetivo de minimizar o número de partições que são lidas, porque precisamos apenas ler uma partição. No entanto, ele não funciona tão bem com o primeiro objetivo de espalhar uniformemente os dados ao redor do cluster. Se tivermos milhares ou milhões de pequenos grupos com centenas de usuários cada, teremos uma distribuição bastante uniforme. Mas se houver um grupo com milhões de usuários, todo o fardo será suportado por um nó (ou um conjunto de réplicas).

Se quisermos distribuir a carga de maneira mais uniforme, há algumas estratégias que podemos usar. A técnica básica é adicionar outra coluna à PRIMARY KEY para formar uma chave de partição composta. Aqui está um exemplo:

12345678CREATE TABLE groups (groupname text,username text,email text,age int,hash_prefix int,PRIMARY KEY ((groupname, hash_prefix), username))

A nova coluna, hash_prefix , contém um prefixo de um hash do nome de usuário. Por exemplo, pode ser o primeiro byte do hash módulo quatro. Juntamente com groupname , essas duas colunas formam a chave de partição composta. Em vez de um grupo residindo em uma partição, ela agora está espalhada em quatro partições.Nossos dados estão mais uniformemente distribuídos, mas agora temos que ler quatro vezes mais partições. Este é um exemplo dos dois objetivos conflitantes. Você precisa encontrar um bom equilíbrio para seu caso de uso específico. Se você fizer um monte de leituras e grupos não ficarem muito grandes, talvez mudar o valor do módulo de quatro para dois seria uma boa escolha. Por outro lado, se você fizer muito poucas leituras, mas qualquer grupo pode crescer muito, mudar de quatro para dez seria uma escolha melhor.

Existem outras maneiras de dividir uma partição, que abordarei no próximo exemplo.

Antes de prosseguirmos, deixe-me apontar algo sobre esse modelo de dados: estamos duplicando as informações do usuário muitas vezes, uma vez para cada grupo. Você pode ser tentado a tentar um modelo de dados como esse para reduzir a duplicação:

123456789101112CREATE TABLE users (id uuid PRIMARY KEY,username text,email text,age int) CREATE TABLE groups (groupname text,user_id uuid,PRIMARY KEY (groupname, user_id))

Obviamente, isso minimiza a duplicação. Mas quantas partições precisamos ler? Se um grupo tiver 1000 usuários, precisamos ler 1001 partições. Isso é provavelmente 100 vezes mais caro para ler do que nosso primeiro modelo de dados. Se as leituras precisam ser eficientes, isso não é um bom modelo. Por outro lado, se as leituras são extremamente raras, mas as atualizações das informações do usuário (digamos, o nome de usuário) são extremamente comuns, esse modelo de dados pode realmente fazer sentido. Certifique-se de levar em consideração sua proporção de leitura / atualização ao projetar seu esquema.

Exemplo 3: grupos de usuários por data de associação

Suponha que continuemos com o exemplo anterior de grupos, mas precisemos adicionar suporte para obter os usuários X mais recentes em um grupo.

Podemos usar uma tabela semelhante à última:

12345678CREATE TABLE group_join_dates (groupname text,joined timeuuid,username text,email text,age int,PRIMARY KEY (groupname, joined))

Aqui estamos usando um timeuuid (que é como um timestamp, mas evita colisões) como a coluna de clustering. Dentro de um grupo (partição), as linhas serão ordenadas no momento em que o usuário ingressou no grupo. Isso nos permite obter os usuários mais novos em um grupo da seguinte forma:

1234SELECT * FROM group_join_datesWHERE groupname = ?ORDER BY joined DESCLIMIT ?

Isso é razoavelmente eficiente, pois estamos lendo uma fatia de linhas de uma única partição. No entanto, em vez de sempre usar o DESC associado ao ORDER BY , o que torna a consulta menos eficiente, podemos simplesmente inverter a ordem de cluster:

12345678CREATE TABLE group_join_dates (groupname text,joined timeuuid,username text,email text,age int,PRIMARY KEY (groupname, joined)) WITH CLUSTERING ORDER BY (joined DESC)

Agora podemos usar a consulta um pouco mais eficiente:

123SELECT * FROM group_join_datesWHERE groupname = ?LIMIT ?

Como no exemplo anterior, poderíamos ter problemas com os dados sendo distribuídos uniformemente ao redor do cluster, caso algum grupo ficasse muito grande. Nesse exemplo, dividimos as partições de forma aleatória, mas, nesse caso, podemos utilizar nosso conhecimento sobre os padrões de consulta para dividir as partições de uma maneira diferente: por um intervalo de tempo.

Por exemplo, podemos dividir partições por data:

123456789CREATE TABLE group_join_dates (groupname text,joined timeuuid,join_date text,username text,email text,age int,PRIMARY KEY ((groupname, join_date), joined)) WITH CLUSTERING ORDER BY (joined DESC)

Estamos usando uma chave de partição composta novamente, mas desta vez estamos usando a data de associação. Cada dia, uma nova partição será iniciada. Ao consultar os usuários mais novos do X, primeiro consultaremos a partição de hoje, depois a de ontem e assim por diante, até que tenhamos usuários X. Talvez tenhamos que ler várias partições antes que o limite seja atingido.

Para minimizar o número de partições que você precisa consultar, tente selecionar um intervalo de tempo para dividir as partições que geralmente permitem que você consulte apenas uma ou duas partições. Por exemplo, se normalmente precisamos dos dez usuários mais novos, e os grupos geralmente adquirem três usuários por dia, devemos dividir por intervalos de quatro dias em vez de um único dia [2] .

Resumo

As regras básicas de modelagem de dados cobertas aqui aplicam-se a todas as versões (atualmente) existentes do Cassandra e são muito prováveis ​​de se aplicarem a todas as versões futuras. Outros problemas de modelagem de dados menores, como lidar com marcas de exclusão , também podem precisar ser considerados, mas esses problemas têm maior probabilidade de mudar (ou serem atenuados) por versões futuras do Cassandra.

Além das estratégias básicas abordadas aqui, alguns dos recursos mais extravagantes do Cassandra, como coleções , tipos definidos pelo usuário e colunas estáticas , também podem ser usados ​​para reduzir o número de partições que você precisa ler para satisfazer uma consulta. Não se esqueça de considerar essas opções ao projetar seu esquema.

Fonte: https://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling

Cassandra e Docker – Ubuntu

Este post apresenta a instalação e utilização do Apache Cassandra, usando Docker.

Baixando a Imagem Docker

$ sudo docker pull cassandra

Esse comando efetuará o download da última versão do Cassandra (latest)

Verificando a Imagem

$ sudo docker images

Resultado

REPOSITORY TAG     IMAGE ID      CREATED     SIZE
cassandra latest 8ea89760ce2b 5 weeks ago 323MB

Subindo o Cassandra

$ sudo docker run --name node1 -d cassandra:lastest

Resultado

f451246389a40761b5a70cbb2d665801f3b2356afcd3abf6ee9a7aa4bd1fe064

Baixando o Cassandra

$ sudo docker stop f451246389a40761b5a70cbb2d665801f3b2356afcd3abf6ee9a7aa4bd1fe064

Removendo

$ sudo docker rm node1

Verificando processos

$ docker exec -it node1 nodetool status

Ferramenta shell CQL

Dentro do container é possível executar o cqlsh.

$ docker exec -it node1 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh>

Criando Keyspace

cqlsh> CREATE KEYSPACE myspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};

Criando uma tabela

CREATE TABLE myspace.exam (
patient_id int,
id int,
date timeuuid,
details text,
PRIMARY KEY (patient_id, id));

Inserindo dados

INSERT INTO exam (patient_id,id,date,details) values (1,1,now(),'first exam patient 1');
INSERT INTO exam (patient_id,id,date,details) values (1,2,now(),'second exam patient 1');
INSERT INTO exam (patient_id,id,date,details) values (2,1,now(),'first exam patient 2');
INSERT INTO exam (patient_id,id,date,details) values (3,1,now(),'first exam patient 3');

Consultando dados

cqlsh:patient> select * from exam where patient_id=1;

Instalando MySQL no Ubuntu usando Docker

Baixando a Imagem

$ sudo docker pull mysql/mysql-server:latest

Rodando o MySQL

$ sudo docker run -it –name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql

Verificando Logs

$ sudo docker logs mysql

Parando o MySQL

$ sudo docker stop mysql

Reiniciando o MySQL

$ sudo docker start mysql

Removendo o MySQL

$ sudo docker rm mysql

Forma alternativa

$ sudo docker run -d –name=mysql-server -p 3306:3306 -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql

Listando imagens

$ sudo docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest ecac195d15af 23 hours ago 516MB
mongo latest 0e120e3fce9a 3 months ago 449MB
amazon/dynamodb-local latest 7984b9b533e7 5 months ago 613MB

$ sudo docker rmi ecac195d15af

Instalando ELK no Ubuntu

Este post apresenta de forma fácil, a instalação do ELK no Ubuntu.

Baixando a imagem Docker

Para baixar a imagem ELK, execute o comando abaixo.

$ sudo docker pull sebp/elk:latest

Subindo a imagem ELK

Para subir a aplicação, execute o comando abaixo.

$ sudo docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk

OBS: Se apresentar erro de memória, execute o comando abaixo.

$ sudo sysctl -w vm.max_map_count=262144

Esse comando é uma solução temporária, ao reiniciar o sistema, volta o valor padrão.

Para configurar a memória de forma definitiva, utilize o comando:

$ sudo gedit /etc/sysctl.conf

Adicionar a linha abaixo e salvar o arquivo.

vm.max_map_count=262144

Após subir a aplicação, pode-se testar os ambientes.

Elasticsearch:

http://localhost:9200

Kibana:

http://localhost:5601

Para a imagem

$ sudo docker ps

Resultado:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b1600afd168 sebp/elk “/usr/local/bin/star…” 15 minutes ago Up 14 minutes 0.0.0.0:5044->5044/tcp, 0.0.0.0:5601->5601/tcp, 0.0.0.0:9200->9200/tcp, 9300/tcp elk

Para com o id do container

$ sudo docker stop 7b1600afd168

Remover o nome elk

$ sudo docker rm elk

 

Instalando Docker Compose no Ubuntu

Este post demonstra como instalar o Docker Compose no Ubuntu.

Procedimento via curl

Faça o download conforme o comando abaixo

$ sudo curl -L “https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)” -o /usr/bin/docker-compose

Altere as permissões para executar o arquivo

$ sudo chmod +x /usr/bin/docker-compose

Verifique a instalação

$ docker-compose -v

 

Docker – Principais Aplicações

Este post tem por objetivo, demonstrar de forma fácil, as principais aplicações do Docker.

Elasticsearch

Baixando a imagem

$ sudo docker pull docker.elastic.co/elasticsearch/elasticsearch:6.4.3

Rodando a imagem

$ sudo docker run -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” docker.elastic.co/elasticsearch/elasticsearch:6.4.3

Logstash

Baixando a imagem

$ sudo docker pull docker.elastic.co/logstash/logstash:6.4.3

Rodando a imagem

$ sudo docker run –rm -it -v ~/pipeline/:/usr/share/logstash/pipeline/ docker.elastic.co/logstash/logstash:6.4.3

Kibana

Baixando a imagem

$ sudo docker pull docker.elastic.co/kibana/kibana:6.4.3

Rodando a imagem

$ sudo docker run -dt -p 5601:5601 -e “ELASTICSEARCH_URL=http://elastic:9200” –network=elastic docker.elastic.co/kibana/kibana:6.4.3

Informações Adicionais

Docker & Elastic

Fonte: https://www.docker.elastic.co

MongoDB – Principais Comandos

Este post tem objetivo de demonstrar os principais comandos do MongoDB.

Banco de dados

> show dbs

Lista os bancos existentes.

> use [NOME_DO_BANCO]

Define o banco como ativo. Significa que todas as demais operações serão aplicadas no banco ativo.

Collections (Coleções)

> show collections

Lista todas as collections existentes no banco ativo.

> db.[COLLECTION].find()

Lista todos os registros na Collection informada.

> db.getCollectionInfos()

Retorna toda a informação das Collections (nome, tipo, índices, etc).

> db.[COLLECTION].help()

Apresenta todos os métodos permitidos na Collection.

> db.runCommand ( { compact: '[COLLECTION]', paddingFactor: 1.1 } )

Efetua a compressão e defragmentação da Collection. O paddingFactor padrão é 1.0.

Interagindo SpringData com MongoDB

Introdução

Este post apresenta de forma simples, como interarir com MongoDB, usando SpringData.

Pré-requisitos

Para efetuar os testes, é necessario estar com o MongoDB rodando. Veja como instalar e executar o MongoDB aqui.

Interface MongoRepository

O MongoRepository é implementado com muitas APIs para armazenar e recuperar dados. Podemos usar o MongoRepository com operações CRUD genéricas completas da interface CrudRepository, e métodos adicionais da interface PagingAndSortingRepository para paginação e ordenação. O MongoRepository também estende o QueryByExampleExecutor para permitir a execução da consulta por exemplo.

Criar projeto SpringBoot

Criar o projeto usando Spring Initializr ou STS (SpringSource Tool Suite)

Arquivo Maven e Dependências

O arquivo de configuração (pom.xml) deve ter a configuração do SpringBoot e dependência do spring-boot-starter-data-mongodb.

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.5.7.RELEASE</version>
</parent>

<groupId>br.com.whs.springmongodb</groupId>
<artifactId>spring-mongodb</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>spring-mongodb</name>

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb</artifactId>
   </dependency>
</dependencies>

Classes do Projeto

Classe de Entidade

São as classes responsáveis pelo mapeamento da persistência no banco de dados.

Utilizam 2 anotações:

  • @Document – identifica o objeto de domínio da persistência no MongoDB
  • @Id – determina o Identificador do documento (neste caso da collection)

Classe Repository

As classes deve estender (extends) a classe MongoRepository.

Classe Service

Possuem função de fachada entre as classes Web e o Repository.

Classe Controller

Neste caso, utilizamos essas classes para atender as chamadas REST.

Classe Application

Esta é a classe responsável pelo funcionamento do SpringBoot. Como os valores de configuração foram mantidos, ele rodará sob o Tomcat (embedded) na porta 8080.

Rodando a aplicação

Pode rodar a aplicação de 2 formas:

  • Rodando a classe SpringMongoDBApplication (Run / Run As / Java Application)
  • Executando o comando $ mvn tomcat:run

Postman

Para rodar os testes, utilizamos o Postman, uma poderosa ferramenta para testar endpoints e APIs.

Adicionar User

Configurar o Postman, da seguinte forma:

  • Method: POST
  • URL: http://localhost:8080/user
  • Body: raw
  • Tipo: JSON (application/json)
  • Exemplo:
{
  "name": "lfchaim",
  "profile": [
    {
      "name": "admin"
    },
    {
      "name": "dev"
    }
  ],
  "age": 36,
  "email": "lfchaim@gmail.com"
}

Listar User

A listagem, sem parâmetros, retornará todos os registros do banco (collection: user).

Configuração:

  • Method: GET
  • URL: http://localhost:8080/user

O projeto completo pode ser baixado no Github.