ProxySQL é um dos melhores proxies disponíveis para MySQL. Ele introduziu uma grande quantidade de opções para administradores de banco de dados. Tornou possível moldar o tráfego do banco de dados atrasando, armazenando em cache ou reescrevendo consultas em tempo real. Ele também pode ser usado para criar um ambiente no qual os failovers não afetarão os aplicativos e serão transparentes para eles. Já abordamos os recursos mais importantes do ProxySQL em postagens anteriores do blog:
- Como usar ClusterControl e ProxySQL para consultas de cache
- Como construir um firewall SQL com ClusterControl e ProxySQL
- Como implantar um cluster ProxySQL
- Como implantar facilmente o ambiente de replicação MySQL com ProxySQL para alta disponibilidade
Temos até um tutorial cobrindo ProxySQL mostrando como ele pode ser usado em configurações MySQL e MariaDB.
Recentemente, o ProxySQL 2.0.3 foi lançado, sendo uma versão de patch para a série 2.0. Bugs estão sendo corrigidos e a linha 2.0 parece começar a ganhar a tração que merece. Nesta postagem do blog, gostaríamos de discutir as principais mudanças introduzidas no ProxySQL 2.0.
Leituras causais usando GTID
Todos que tiveram que lidar com o atraso de replicação e lutaram com cenários de leitura após gravação que são afetados pelo atraso de replicação definitivamente ficarão muito felizes com esse recurso. Até agora, em ambientes de replicação MySQL, a única maneira de garantir leituras causais era ler do mestre (e não importa se você usa replicação assíncrona ou semisíncrona). Outra opção era ir para Galera, que tinha uma opção para impor leituras causais desde, tipo, sempre (primeiro costumava ser wsrep-causal-reads e agora é wsrep-sync-wait). Muito recentemente (em 8.0.14) a replicação do MySQL Group obteve um recurso semelhante. A replicação regular, porém, por si só, não pode lidar com esse problema. Felizmente, o ProxySQL está aqui e nos traz uma opção para definir com base na regra de consulta com qual hostgroup lê que corresponde a essa regra de consulta deve ser consistente. A implementação vem com o leitor de log binário ProxySQL e pode funcionar com o formato de log binário ROW para MySQL 5.7 e mais recente. Apenas Oracle MySQL é suportado devido à falta de funcionalidade necessária no MariaDB. Esse recurso e seus detalhes técnicos foram explicados no blog oficial do ProxySQL.
SSL para conexões de front-end
O ProxySQL sempre teve suporte para conexão SSL de back-end, mas faltava criptografia SSL para as conexões provenientes de clientes. Isso não foi grande coisa, dado que o padrão de implantação recomendado era colocar o ProxySQL nos nós do aplicativo e usar um soquete Unix seguro para conectar o aplicativo ao proxy. Isso ainda é uma recomendação, especialmente se você usa ProxySQL para consultas de cache (soquetes Unix são mais rápidos que conexão TCP, mesmo locais e com cache é bom evitar a introdução de latência desnecessária). O que é bom é que, com o ProxySQL 2.0, há uma escolha agora, pois introduziu o suporte SSL para conexões de entrada. Você pode habilitá-lo facilmente definindo mysql-have_ssl como 'true'. A ativação do SSL não traz um impacto inaceitável no desempenho. Ao contrário, conforme resultados do blog oficial do ProxySQL, a queda de desempenho é muito baixa.
Suporte nativo para Galera Cluster
O Galera Cluster tem sido suportado pelo ProxySQL quase desde o início, mas até agora foi feito através do script externo que (normalmente) foi chamado do agendador interno do ProxySQL. Cabia ao script garantir que a configuração do ProxySQL fosse adequada, que o gravador (ou gravadores) fosse detectado e configurado corretamente no grupo de hosts dos gravadores. O script foi capaz de detectar os diferentes estados que o nó Galera pode ter (Primário, não-Primário, Sincronizado, Doador/Dessincronizado, Aderindo, Junto) e marcar o nó de acordo como disponível ou não. A questão principal é que o roteiro original nunca foi concebido como outra coisa senão a prova de conceito escrita em Bash. No entanto, à medida que foi distribuído junto com o ProxySQL, começou a ser aprimorado, modificado por colaboradores externos. Outros (como Percona) procuraram criar seus próprios scripts, empacotados com seu software. Algumas correções foram introduzidas no script do repositório ProxySQL, algumas foram introduzidas na versão Percona do script. Isso gerou confusão e mesmo que todos os scripts comumente usados tratassem de 95% dos casos de uso, nenhum dos populares realmente cobriu todas as diferentes situações e variáveis que o cluster Galera pode acabar usando. Felizmente, o ProxySQL 2.0 vem com suporte nativo para Galera Cluster. Isso faz com que o ProxySQL suporte internamente a replicação MySQL, MySQL Group Replication e agora Galera Cluster. A forma como é feito é muito semelhante. Gostaríamos de abordar a configuração desse recurso, pois pode não ficar claro à primeira vista.
Assim como na replicação do MySQL e no MySQL Group Replication, uma tabela foi criada no ProxySQL:
mysql> show create table mysql_galera_hostgroups\G
*************************** 1. row ***************************
table: mysql_galera_hostgroups
Create Table: CREATE TABLE mysql_galera_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0),
offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0),
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1,
writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0,
max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0,
comment VARCHAR,
UNIQUE (reader_hostgroup),
UNIQUE (offline_hostgroup),
UNIQUE (backup_writer_hostgroup))
1 row in set (0.00 sec)
Existem inúmeras configurações para configurar e vamos analisá-las uma a uma. Primeiro de tudo, existem quatro grupos de hosts:
- Writer_hostgroup - conterá todos os escritores (com read_only=0) até a configuração ‘max_writers’. Por padrão, é apenas um escritor
- Backup_writer_hostgroup - contém os escritores restantes (read_only=0) que sobraram depois que 'max_writers' foi adicionado ao writer_hostgroup
- Reader_hostgroup - contém leitores (read_only=1), também pode conter gravadores de backup, conforme a configuração "writer_is_also_reader"
- Offline_hostgroup - contém nós que foram considerados inutilizáveis (offline ou em um estado que os impossibilita de lidar com o tráfego)
Então temos configurações restantes:
- Ativo - se a entrada em mysql_galera_hostgroups está ativa ou não
- Max_writers - quantos nós no máximo podem ser colocados no writer_hostgroup
- Writer_is_also_reader - se definido como 0, os escritores (read_only=0) não serão colocados em reader_hostgroup. Se definido como 1, os escritores (read_only=0) serão colocados em reader_hostgroup. Se definido como 2, os nós de backup_writer_hostgroup serão colocados em reader_hostgroup. Este é um pouco complexo, portanto, apresentaremos um exemplo posteriormente nesta postagem do blog
- Max_transactions_behind - com base em wsrep_local_recv_queue, a fila máxima aceitável. Se a fila no nó exceder max_transactions_behind, determinado nó será marcado como SHUNNED e não estará disponível para o tráfego
A principal surpresa pode ser o manuseio dos leitores, que é diferente de como o script incluído no ProxySQL funcionava. Em primeiro lugar, o que você deve ter em mente é o fato de que o ProxySQL usa read_only=1 para decidir se o nó é um leitor ou não. Isso é comum em configurações de replicação, não tão comum no Galera. Portanto, provavelmente, você desejará usar a configuração ‘writer_is_also_reader’ para configurar como os leitores devem ser adicionados ao reader_hostgroup. Vamos considerar três nós Galera, todos eles têm read_only=0. Também temos max_writers=1, pois queremos direcionar todas as gravações para um nó. Configuramos mysql_galera_hostgroups da seguinte forma:
SELECT * FROM mysql_galera_hostgroups\G
*************************** 1. row ***************************
writer_hostgroup: 10
backup_writer_hostgroup: 30
reader_hostgroup: 20
offline_hostgroup: 40
active: 1
max_writers: 1
writer_is_also_reader: 0
max_transactions_behind: 0
comment: NULL
1 row in set (0.00 sec)
Vamos a todas as opções:
writer_is_also_reader=0
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
3 rows in set (0.00 sec)
Esse resultado é diferente do que você veria nos scripts - lá você teria os nós restantes marcados como leitores. Aqui, como não queremos que os escritores sejam leitores e como não há nó com read_only=1, nenhum leitor será configurado. Um gravador (conforme max_writers), nós restantes em backup_writer_hostgroup.
writer_is_also_reader=1
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 20 | 10.0.0.101 |
| 20 | 10.0.0.102 |
| 20 | 10.0.0.103 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
6 rows in set (0.00 sec)
Aqui queremos que nossos escritores atuem como leitores, portanto, todos eles (ativos e backup) serão colocados no reader_hostgroup.
escritor_is_também_leitor=2
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 20 | 10.0.0.101 |
| 20 | 10.0.0.102 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
5 rows in set (0.00 sec)
Esta é uma configuração para aqueles que não querem que seu gravador ativo lide com leituras. Nesse caso, apenas os nós do backup_writer_hostgroup serão usados para leituras. Lembre-se também de que o número de leitores mudará se você definir max_writers para algum outro valor. Se definimos como 3, não haveria gravadores de backup (todos os nós terminariam no grupo de hosts do gravador), portanto, novamente, não haveria nós no grupo de hosts do leitor.
Obviamente, você desejará configurar as regras de consulta de acordo com a configuração do grupo de hosts. Não vamos passar por esse processo aqui, você pode conferir como pode ser feito no blog do ProxySQL. Se você quiser testar como funciona em um ambiente Docker, temos um blog que aborda como executar o cluster Galera e o ProxySQL 2.0 no Docker.
Outras alterações
O que descrevemos acima são as melhorias mais notáveis no ProxySQL 2.0. Existem muitos outros, conforme o changelog. Vale a pena mencionar as melhorias em torno do cache de consulta (por exemplo, adição de PROXYSQL FLUSH QUERY CACHE) e a mudança que permite que o ProxySQL conte com super_read_only para determinar mestre e escravos na configuração da replicação.
Esperamos que esta breve visão geral das alterações no ProxySQL 2.0 o ajude a determinar qual versão do ProxySQL você deve usar. Por favor, tenha em mente que o branch 1.4, mesmo que não receba nenhum novo recurso, ele ainda é mantido.