Postgres – PG_Pool2 Sharding Cache

Não vou entrar na discussão se o pgbouncer ou o pg_pool2 é isso ou aquilo, melhor ou pior, cada um tem suas qualidades e cada um sabe onde aperta o calo.

A ideia desse post é mostrar que é possível montar uma estrutura de shard de cache para o pg_pool2 para poder ter balanceamento do pool e conseguir alguma consistência do cache ganhar proveito com isso.

Começando pelo básico… O pg_pool2 tem uma configuração de cache, ele pode usar um serviço próprio ou o memcached (com tanta opção por aí eles continuam batendo nisso). Ele faz um controle até que bom do cache, invalida se alguma tabela sofre DML, não faz cache se vc escolher algum schema ou tabela específica, no final ele é bem honesto não garante 100% mas tenta entregar alguma coisa.

Qual seria a vantagem desse cache? se sua aplicação é mais antiga, você não tem como alterar o fonte ou seus devs são preguiçosos e não entendem o porque de usar um cache você consegue fazer isso de forma precária no meio do caminho, diminuindo a carga de consultas repetitivas contra seu banco de dados.

Existem outras formas de resolver? Até que sim, mas nesse post só vai ter essa.

Como vamos trabalhar com uma configuração de dois #poolers de conexão, cada #pooler vai executar dois serviços do #memcached.

O serviço na porta padrão 11211 vai trabalhar como um proxy de conexão enquanto o serviço executando na porta 11212 vai ser o serviço que vai realmente hospedar a chave valor.

Como o serviço do #pgpool é responsável por criar, consultar e apagar as chaves ele precisa ser capaz de invalidar uma chave devido a uma operação de DML/DDL que passe por ele, se cada pool tiver seu próprio #memcached um não sabe que o outro existe e não tem como invalidar uma possível chave que possa gerar inconsistência.

O serviço de #proxy do #memcached que vamos usar é o do próprio #memcached
https://docs.memcached.org/features/proxy/examples/

mas precisamos ajustar o arquivo de configuração para executar a subida do serviço em uma porta diferente da porta padrão, neste caso vamos fazer a configuração para usar a porta 11212.

arquivo de configuração do memcached:

# memcached default config file
# 2003 - Jay Bonci <jaybonci@debian.org>
# This configuration file is read by the start-memcached script provided as
# part of the Debian GNU/Linux distribution.

# Run memcached as a daemon. This command is implied, and is not needed for the
# daemon to run. See the README.Debian that comes with this package for more
# information.
-d
# Log memcached's output to /var/log/memcached
logfile /var/log/memcached.log

# Be verbose
-v

# Be even more verbose (print client commands as well)
-vv

# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default
# Note that the daemon will grow to this size, but does not start out holding this much
# memory
#-m 64
-m 12288
# Default connection port is 11211
-p 11212

# Run the daemon as root. The start-memcached will default to running as root if no
# -u command is present in this config file
-u memcache

# Specify which IP address to listen on. The default is to listen on all IP addresses
# This parameter is one of the only security measures that memcached has, so make sure
# it's listening on a firewalled interface.
#-l 127.0.0.1
-l 0.0.0.0
# Limit the number of simultaneous incoming connections. The daemon default is 1024
# -c 1024

# Lock down all paged memory. Consult with the README and homepage before you do this
# -k

# Return error when memory is exhausted (rather than removing items)
# -M

# Maximize core file limit
# -r

# Use a pidfile
-P /var/run/memcached/memcached.pid

agora para o ajuste de configuração de proxy, vamos fazer o seguinte:

instalar dependências

apt-get install gcc make libevent-dev

baixar a versão compilável

wget https://memcached.org/latest

copiar, remover a versão baixada que ficou com um nome estranho e descompactar

cp latest memcached-1.6.39.tar.gz
rm latest
tar xzvf memcached-1.6.39.tar.gz

acessar o diretório e configurar a nova versão

cd memcached-1.6.39.tar.gz
./configure --enable-proxy

executar o make, make test e make install (esse processo demora)

make
make test
make install

confirmar que foi habilitado o proxy

memcached --help | grep proxy

criar um arquivo mc1proxy.lua com o seguinte conteúdo

pools{
    main = {
        backends = {
            "127.0.0.1:11212",
            "OUTRO_IP:11212",
        }
    }
}


routes{
    default = route_direct{
        child = "main"
    }
}

**Esse OUTRO_IP é o IP usado no outro nó do instance group do #pgbouncer

iniciar os serviços do #memcached nos 2 ou mais nós, na porta 11212

Baixar o protocolo de roteamento no diretório do #memcached

wget https://raw.githubusercontent.com/memcached/memcached-proxylibs/main/lib/routelib/routelib.lua

iniciar o serviço para ver se tudo funciona

memcached -o proxy_config=routelib,proxy_arg=mc1proxy.lua -p 11211 -u root

até esse momento os serviços devem estar rodando.
para testar executar telnet no IP do servidor do pgbouncer na porta 11211

telnet IP_BOUNCER 11211

a tela deve ficar escura, executar o comando

watch proxyevents

caso alguma coisa não esteja funcionando ele vai começar a colocar na tela as mensagens de erro
para parar pressione CTRL + ]

Então, basicamente, o seu NLB vai fazer sua aplicação acessar um dos pools, esse pool vai acessar o endereço local na porta padrão do memcached que é o proxy e quando ele fizer cache de alguma consulta ele vai fazer o shard desse cache em algum memcached.

Bonus 1

O script abaixo é para ser usado na GCP, ele deve ser colocado na secret para ser carregado na maquina caso você use Instance Groups, para ter flexibilidade em adicionar ou remover maquinas do pool.

A ideia dele é ser executado de forma cíclica a cada X minutos ou segundos, ele vai identificar se existe maquina nova no pool de maquinas do Instance Group, adicionar, remover ou não fazer nada no arquivo Lua do proxy e recarregar o serviço caso precise.

https://github.com/bigleka/gcp/blob/main/gcp_memcached_balancer.sh

AWS – VPN Server

Existem vários motivos para você querer rotear sua saída de internet por outro local ao invés do seu ISP de costume, privacidade? segurança? acesso a outros conteúdos de mídia?

O motivo em si é irrelevante, hoje contamos com diversos serviços de VPN pagos e gratuitos muito bons por aí, mas da pra confiar neles? uma VPN é basicamente um contrato de mão dupla, você confia em uma ponta enquanto a outra ponta confia em você, é estabelecido um canal de criptografia entre essas duas pontas e os dados podem ou não ser roteados através desse canal, em uma visão simplista uma análise de tráfego ou scan de rede pode partir de uma das pontas para “analisar” o que encontra-se do outro lado, por isso, mesmo uma VPN meia-boca costuma ter firewall restringindo quem e da onde pode vir o tráfego, mas em dispositivos de celular isso é quase impossível.

Claro que existem serviços honestos de VPN por aí, pagos ou gratuitos, mas por que ariscar se você pode montar um para você,,, e de graça,,,

Pra começar é simples, crie uma conta na AWS.

Depois vamos usar o serviço de Marketplace:

Procure por OpenVPN Access Server

Escolha a opção de Continue to Subscribe

Aceite os termos

Muitos termos

é só esperar para ele ativar o serviço na sua conta

Basicamente terminada a subscrição agora vamos iniciar uma máquina EC2 com o OpenVPN, escolha o local onde você vai hospedar a máquina EC2, basicamente qualquer lugar do mundo dentro da nuvem da AWS serve.

eu disse que era grátis? foi mesmo,,, você tem que alterar o tipo de máquina que vai ser usada para hospedar o OpenVPN para o modelo t2.micro

nessa parte onde você troca a máquina.

Aqui vem um detalhe, esse ambiente é grátis por 1 ano, se você já usou esse serviço de EC2 da AWS alguma vez e não aparecer a que vai ser grátis então chegou até aqui a toa, eles vão te cobrar, mas cabaçada sua de não prestar atenção nos termos de uso dos serviços deles…

VPC e Subnet a sua escolha, o que importa são as regras de firewall e o IP valido que vai ser criado para a máquina.

Como você está criado a máquina através de um template, ele já vem com um conjunto de regras pré definidas.

Essa parte é importante, salve a chave para que você tenha acesso a essa máquina através de SSH.

Basicamente após clicar em “Launch” a AWS vai criar a máquina, na região, com regras de firewall e o OpenVPN para você.

Mas não acabou por aqui, afinal, você vai querer acessar essa VPN.

Para acessar essa VPN antes você vai precisar configurar ela, nada tão complicado,,, apenas preste atenção nos detalhes, eles são a grande diferença

Após a máquina iniciar, você terá um endereço de IP válido e uma entrada de DNS. Se você não esqueceu de liberar o seu IP lá na regra de firewall você deve conseguir acessar esse servidor.

Antes de sair tentando acessar pelo Browser e configurar as coisas, você precisa logar no servidor e aceitar aqueles contratos, que como TODOS fazemos lemos até o fim um a um,,,, um a um,,,

Para acessar o servidor não precisa de nenhuma ferramenta especial (caso você esteja usando pelo menos o Windows 10), nos Linux e Mac’s da vida o ssh vem por padrão, no Windows 10 pra cima também, se você está usando alguma coisa mais antiga, procura algum cliente de SSH.

Para acessar esse novo servidor você vai abrir o prompt/terminal/posh o raio que quiser e basicamente digitar:

ssh -i "aquele_arquivo_de_chave" ec2user@IP_ou_FQDN
se não der certo tenta como root mesmo
ssh -i "aquele_arquivo_de_chave" root@IP_ou_FQDN

Se tudo deu certo, deve aparecer a licença, leia com cuidado, tudinho, tintim por tintim,,, e se achar que está tudo bem aceita a licença.

Na primeira vez que você faz login no Servidor de Acesso, um assistente de configuração é executado para permitir que você configure os parâmetros de inicialização antes de poder acessar a interface web administrativa. Neste assistente, você especifica alguns detalhes da rede e define um usuário administrador.

Se você optar por usar o usuário openvpn padrão como usuário administrador, certifique-se de definir uma senha para ele antes de acessar a interface web de administração. Para definir uma senha, use o seguinte comando shell:

sudo senha openvpn

Para acessar a interface web, abra o endereço IP público que você atribuiu e faça login como o usuário administrador que você configurou. A URL da interface da web tem o seguinte formato: https://xxx.xxx.xxx.xxx/admin.

O login abre a página Visão geral do status, conforme mostrado na imagem a seguir. É aqui que você obtém a visão geral do status do dispositivo VPN. Você também pode usar este portal para ajustar a VPN, alterar as configurações de rede e gerenciar permissões e autenticação do usuário.

Por padrão, a VPN é configurada para funcionar no modo NAT (tradução de endereço de rede) da Camada 3. Nesse modo, os clientes VPN são atribuídos a uma sub-rede privada cujos IPs são atribuídos dinamicamente a partir do pool padrão 172.27.224.0/20 (CIDR), conforme mostrado na imagem a seguir.

Você pode alterar esse pool de IPs, mas esteja ciente de que o novo deve ser diferente das outras sub-redes utilizadas na sua rede. Você também pode configurar outra sub-rede privada usada para atribuir endereços IP estáticos a usuários específicos designados na página Permissões do usuário.

Para roteamento de rede, a opção padrão é Sim, usando NAT, conforme mostrado na imagem a seguir.

Para testar a VPN

Normalmente você precisa baixar um cliente VPN para os testes, a principal vantagem do OpenVPN é ele ter clientes para todos os SO’s e Mobiles do mercado.

baixe o cliente correto, ajuste a configuração de IP que você está usando como IP público e terá uma VPN saindo pelo lugar do mundo onde você fez deploy da maquina.

AWS – Redshift – Carregar dados S3

A algum tempo atrás fiz um trabalho que teoricamente parecia simples, extrair dados de um banco transacional e mandar para um Redshift para análilse.

Claro que após bater cabeça alguns minutos entendi que imporar dados diretamente para o Redshift iria ser no mínimo conturbado e instável.

Fazendo uma análise das opções vi que a AWS disponibilizou um método muito parecido com o do SQL Server para importar arquivos diretamente para dentro do banco mas claro ao invés de fazer isso através de um servidor, é possível fazer isso através do S3.

A forma mais simples é basicamente:

copy tabela_destino
from 'S3://bucket/arquivo'
iam_role 'arn:aws:iam::01234567890:role/MinhaRegraDoRedshift'

Se o arquivo for muito grande e foi dividido ele tem que terminar com um numeral incremental 1 2 3 4 …

Se o arquivo for compactado, o comando de COPY tem que ser incrementado com GZIP.

Para mais informações tem esse link da AWS abaixo:

https://docs.aws.amazon.com/pt_br/redshift/latest/dg/t_loading-tables-from-s3.html

para monitorar essa importação você pode usar o

https://docs.aws.amazon.com/redshift/latest/dg/r_STV_LOAD_STATE.html

AWS – Redshift – Lock e Block

Por incrível que pareça o Redshift sofre com problemas de Lock e Block da mesma forma que um banco transacional qualquer.

Como qualquer post sobre nuvem, até o momento dessa publicação, o Redshift não tem uma interface que monitora Lock e Block, ela monitora conexões ativas, querys em execução mas não lock e block.

A query para monitorar o Redshift é a seguinte:

select a.txn_owner, a.txn_db, a.xid, a.pid, a.txn_start, a.lock_mode, a.relation as table_id,nvl(trim(c."name"),d.relname) as tablename, a.granted,b.pid as blocking_pid ,datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' as txn_duration
from svv_transactions a 
left join (select pid,relation,granted from pg_locks group by 1,2,3) b 
on a.relation=b.relation and a.granted='f' and b.granted='t' 
left join (select * from stv_tbl_perm where slice=0) c 
on a.relation=c.id 
left join pg_class d on a.relation=d.oid
where  a.relation is not null;

e para dar um kill no processo

select pg_terminate_backend(PID);

o resultado deve vir como “1”

No link abaixo tem mais informações:

https://aws.amazon.com/pt/premiumsupport/knowledge-center/prevent-locks-blocking-queries-redshift/