Uma camada de proxy entre aplicativos e bancos de dados normalmente consiste em vários nós de proxy para alta disponibilidade. Isso não é diferente para ProxySQL. ProxySQL, assim como outros proxies modernos, pode ser usado para construir lógica complexa para consultas de roteamento. Você pode adicionar regras de consulta para enviar consultas a hosts específicos, pode armazenar consultas em cache, adicionar e remover servidores de back-end ou gerenciar usuários que têm permissão para se conectar ao ProxySQL e MySQL. No entanto, vários nós ProxySQL na camada de proxy apresentam outro problema - sincronização entre instâncias distribuídas. Quaisquer regras ou outras lógicas precisam ser sincronizadas entre as instâncias, para garantir que elas se comportem da mesma maneira. Mesmo que nem todos os proxies estejam lidando com tráfego, eles ainda funcionam como standby. Caso eles precisem assumir o trabalho, você não quer surpresas se a instância usada não tiver as alterações de configuração mais recentes.
É bastante complicado garantir isso manualmente - fazer as alterações manualmente em todos os nós. Você pode utilizar ferramentas como Ansible, Chef ou Puppet para gerenciar configurações, mas o processo de sincronização precisa ser codificado e testado. O ClusterControl pode ajudá-lo aqui por meio de uma opção para sincronizar configurações entre instâncias do ProxySQL, mas também pode configurar e gerenciar os outros componentes necessários para alta disponibilidade, por exemplo, IP virtual. Mas a partir da versão 1.4.2, o ProxySQL oferece um mecanismo nativo de clustering e sincronização de configuração. Nesta postagem do blog, discutiremos como configurá-lo com uma combinação de ações executadas na interface de administração de linha de comando do ClusterControl e ProxySQL.
Em primeiro lugar, vamos dar uma olhada em um ambiente de replicação típico implantado pelo ClusterControl.
Como você pode ver na captura de tela, esta é uma configuração de replicação do MySQL com três instâncias do ProxySQL. A alta disponibilidade do ProxySQL é implementada por meio do Keepalived e do IP virtual que é sempre atribuído a um dos nós do ProxySQL. Há algumas etapas que precisamos seguir para configurar o clustering ProxySQL. Primeiro, temos que definir qual usuário o ProxySQL deve usar para trocar informações entre os nós. Vamos definir um novo em cima do usuário administrativo existente:
Em seguida, precisamos definir esse usuário nas configurações admin-cluster_password e admin-cluster_username.
Isso foi feito em apenas um dos nós (10.0.0.126). Vamos sincronizar essa alteração de configuração com os nós ProxySQL restantes.
Como dissemos, o ClusterControl permite que você sincronize a configuração entre os nós ProxySQL com apenas algumas etapas. Quando o trabalho terminou de sincronizar 10.0.0.127 com 10.0.0.126, há apenas o último nó que precisamos sincronizar.
Depois disso, precisamos fazer uma pequena alteração na interface de linha de comando administrativa do ProxySQL, que normalmente é acessível na porta 6032. Temos que criar entradas na tabela 'proxysql_servers' que definiriam os nós em nosso cluster ProxySQL.
mysql> INSERT INTO proxysql_servers (hostname) VALUES ('10.0.0.126'), ('10.0.0.127'), ('10.0.0.128');
Query OK, 3 rows affected (0.00 sec)
mysql> LOAD PROXYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> SAVE PROXYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.01 sec)
Depois de carregar a alteração no tempo de execução, o ProxySQL deve começar a sincronizar os nós. Há alguns lugares onde você pode rastrear o estado do cluster.
mysql> SELECT * FROM stats_proxysql_servers_checksums;
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| hostname | port | name | version | epoch | checksum | changed_at | updated_at | diff_check |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
| 10.0.0.128 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_query_rules | 2 | 1539772933 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_servers | 4 | 1539772933 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_users | 2 | 1539772933 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.128 | 6032 | proxysql_servers | 2 | 1539773835 | 0x8EB13E2B48C3FDB0 | 1539773835 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_query_rules | 3 | 1539773719 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_servers | 5 | 1539773719 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_users | 3 | 1539773719 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.127 | 6032 | proxysql_servers | 2 | 1539773812 | 0x8EB13E2B48C3FDB0 | 1539773813 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | admin_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_query_rules | 1 | 1539770578 | 0x3FEC69A5C9D96848 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_servers | 3 | 1539771053 | 0x3659DCF3E53498A0 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_users | 1 | 1539770578 | 0xDD5F0BB01235E930 | 1539773546 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | mysql_variables | 0 | 0 | | 0 | 1539773916 | 0 |
| 10.0.0.126 | 6032 | proxysql_servers | 2 | 1539773546 | 0x8EB13E2B48C3FDB0 | 1539773546 | 1539773916 | 0 |
+------------+------+-------------------+---------+------------+--------------------+------------+------------+------------+
18 rows in set (0.00 sec)
A tabela stats_proxysql_servers_checksums contém, entre outros, uma lista de nós no cluster, tabelas que são sincronizadas, versões e checksum da tabela. Se a soma de verificação não estiver alinhada, o ProxySQL tentará obter a versão mais recente de um par de cluster. Informações mais detalhadas sobre o conteúdo desta tabela podem ser encontradas na documentação do ProxySQL.
Outra fonte de informação sobre o processo é o log do ProxySQL (por padrão está localizado em /var/lib/proxysql/proxysql.log).
2018-10-17 11:00:25 [INFO] Cluster: detected a new checksum for mysql_query_rules from peer 10.0.0.126:6032, version 2, epoch 1539774025, checksum 0xD615D5416F61AA72 . Not syncing yet …
2018-10-17 11:00:27 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 3. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected a peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025, diff_check 4. Own version: 2, epoch: 1539772933. Proceeding with remote sync
2018-10-17 11:00:28 [INFO] Cluster: detected peer 10.0.0.126:6032 with mysql_query_rules version 2, epoch 1539774025
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 started
2018-10-17 11:00:28 [INFO] Cluster: Fetching MySQL Query Rules from peer 10.0.0.126:6032 completed
2018-10-17 11:00:28 [INFO] Cluster: Loading to runtime MySQL Query Rules from peer 10.0.0.126:6032
2018-10-17 11:00:28 [INFO] Cluster: Saving to disk MySQL Query Rules from peer 10.0.0.126:6032
Como você pode ver, temos aqui informações de que uma nova soma de verificação foi detectada e o processo de sincronização está em andamento.
Vamos parar por um momento aqui e discutir como o ProxySQL lida com atualizações de configuração de várias fontes. Em primeiro lugar, o ProxySQL rastreia as somas de verificação para detectar quando uma configuração foi alterada. Ele também armazena quando aconteceu - esses dados são armazenados como um carimbo de data/hora, portanto, têm uma resolução de um segundo. ProxySQL tem duas variáveis que também impactam como as mudanças estão sendo sincronizadas.
Cluster_check_interval_ms - determina com que frequência o ProxySQL deve verificar as alterações de configuração. Por padrão é 1000ms.
Cluster_mysql_servers_diffs_before_sync - nos diz quantas vezes uma verificação deve detectar uma alteração de configuração antes que ela seja sincronizada. A configuração padrão é 3.
Isso significa que, mesmo que você faça uma alteração de configuração no mesmo host, se você fizer isso com menos de 4 segundos, os nós ProxySQL restantes podem não conseguir sincronizá-lo porque uma nova alteração aparecerá antes da anterior foi sincronizado. Isso também significa que, se você fizer alterações na configuração em várias instâncias do ProxySQL, deverá fazê-las com pelo menos 4 segundos de intervalo entre elas, caso contrário, algumas das alterações serão perdidas e, como resultado, as configurações divergirão. Por exemplo, você adiciona Server1 em Proxy1 e, após 2 segundos, adiciona Server2 em Proxy2 . Todos os outros proxies rejeitarão a alteração no Proxy1 porque detectarão que o Proxy2 tem uma configuração mais recente. 4 segundos após a alteração no Proxy2, todos os proxies (incluindo o Proxy1) puxarão a configuração do Proxy2.
Como a comunicação dentro do cluster não é síncrona e se um nó ProxySQL no qual você fez as alterações falhar, as alterações podem não ser replicadas no prazo. A melhor abordagem é fazer a mesma alteração em dois nós ProxySQL. Dessa forma, a menos que ambos falhem exatamente ao mesmo tempo, um deles poderá propagar a nova configuração.
Também vale a pena notar que a topologia de cluster ProxySQL pode ser bastante flexível. No nosso caso temos três nós, todos com três entradas na tabela proxysql_servers. Esses nós formam o cluster onde você pode gravar em qualquer nó e as alterações serão propagadas. Além disso, é possível adicionar nós externos que funcionariam em modo “somente leitura”, o que significa que eles sincronizariam apenas as alterações feitas no cluster “core”, mas não propagariam as alterações realizadas diretamente em si mesmos. Tudo o que você precisa no novo nó é ter apenas os nós de cluster “core” configurados em proxysql_servers e, como resultado, ele se conectará a esses nós e obterá as alterações de dados, mas não será consultado pelo restante do cluster para suas alterações de configuração. Essa configuração pode ser usada para criar uma fonte de verdade com vários nós no cluster e outros nós ProxySQL, que apenas obtêm a configuração do cluster “núcleo” principal.
Além de tudo isso, o cluster ProxySQL suporta a reintegração automática dos nós - eles sincronizarão sua configuração durante a inicialização. Ele também pode ser facilmente dimensionado adicionando mais nós.
Esperamos que esta postagem de blog forneça uma visão de como o cluster ProxySQL pode ser configurado. O cluster ProxySQL será transparente para o ClusterControl e não afetará nenhuma das operações que você deseja executar na interface do usuário do ClusterControl.