ProxySQL-用于多路分解连接的工具

您好,我叫Alexander Yakovlev,我在Citimobil工作并运营。今天,我将向您介绍一个非常有趣的ProxySQL产品-它是一种高性能的MySQL Proxy,可以完成很多事情-通过掩码捕获和杀死请求,借助它您可以搜索sql注入,复制负载等等。我将谈论我们与他的经历。
迟来的情况是,任何大型IT项目(其开发都是从一对服务器开始的)都面临着以下情况。想象一下,该项目最初只有一个数据库-主服务器。逐渐地,一群奴隶被加入其中。然后他们引入了分片。

一天,负载突然增加了十倍。例如,因为您的主要竞争对手已经倒下,而客户却赶到了您。此时,您似乎可以通过添加Web服务器来简单地扩展负载。但是完成此操作后,就会出现不愉快的情况。

考虑一个向导的示例。假设您有50个Web服务器,每200个php-fpm进程。然后,将有50 * 200个连接到达主服务器,然后以50 * 200 /个从服务器到达每个从服务器(当然,如果在roproxy中配置了roundrobin)-参见下图。当然,到主服务器的一万个连接是很多,但仍然可以承受,如果有200个网站,则连接的数量将更多,一个连接=一个线程。
我们遇到了这个瓶颈。

图片

然后我们开始争论:与向导的连接始终安装在代码中,但是所有fpm进程是否都必须这样做?可能不是。我们注意到,与主服务器的大量持久连接只是简单地挂起。他们决定我们需要解复用。

图片

为此,我们提请注意一种名为ProxySQL的产品。它像普通的反向代理一样工作:建立连接,并根据配置中指定的某些规则重新分配流量。

我们在所有Web服务器上安装了ProxySQL,并在应用程序配置中指定对主数据库的调用在地址127.0.0.1处进行。如果以前每台Web服务器上的200名FPM工作人员意味着从这台机器到主数据库的200条连接,那么情况已经改变了。这200个连接来自ProxySQL,而50-70个连接则在不同时间断开。也就是说,ProxySQL可以重用现有的连接。

由于多路分解,我们在所有主机上将连接数减少了3-10倍,请参阅下面其中一个主机的当前连接图。

图片

多亏了ProxySQL,我们摆脱了上述瓶颈。但这不是我们使用此工具改进的唯一工作流程。
我们还没有完成第二个过程,但是非常接近完成。我们计划使用ProxySQL在测试环境中复制实际负载。这是检查战斗流量的新功能所必需的。

如何实施?该应用程序转到ProxySQL,并通过两条路径发送流量:进入战斗数据库以使该应用程序正常运行,以及到达测试环境以检查负载下的新功能。

ProxySQL的功能是有它的配置,在我们的案例中是通过puppet推出的(对于puppet,有一个ProxySQL模块),但是还有运行时区域的概念,以便进行更改(添加服务器,添加用户,删除服务器和用户) ),则不需要通常的重新启动/重新加载。一切都通过ProxySQL控制台完成,例如这样。

mysql -ulogin -ppassword -h 127.0.0.1 -P6032 -e "INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('sm_username','pass',1);;LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS TO DISK;"

当然,更详细地,在官方文档proxysql.com/documentation中。

感谢您的关注。

解决上述问题的配置,请参见下文。

我们的配置

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="user:pass"
    mysql_ifaces="0.0.0.0:6032"
    refresh_interval=2000
    web_enabled=true
    web_port=6080
    stats_credentials="stats:admin"
}

mysql_variables =
{
    threads = 1000
    max_connections = 2000
    default_query_delay= 0
    default_query_timeout=1
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.7.22"
    connect_timeout_server=10000
    monitor_history=60000
    monitor_connect_interval=200000
    monitor_ping_interval=200000
    ping_interval_server_msec=5000
    ping_timeout_server=200
    commands_stats=true
    sessions_sort=true
    monitor_username="root"
    monitor_password="password"
    monitor_galera_healthcheck_interval=200
    monitor_galera_healthcheck_timeout=80
}

mysql_servers =
(
  {
    address = "ip_real_mysql_server",
    port = 3306,
    max_connections = 10000,
    host_group = 1,
  })
mysql_users =
(
  {
    username = "user",
    password = "pass",
    default_hostgroup = 1,
    transaction_persistent = 0,
    active = 1,
  })

All Articles