galera cluster_nginScript 系列:通过 TCP 负载均衡和 Galera 集群来扩展 MySQL

本文详细介绍了如何使用NGINXPlus进行TCP负载均衡,特别是在MySQL数据库场景中的应用。通过配置stream上下文,设置轮询或最少连接数算法来平衡数据库连接。此外,还讨论了NGINXPlus的健康检查和高可用性特性,以及日志和诊断功能,以确保服务稳定性和故障排查效率。
摘要由CSDN通过智能技术生成

NGINX Plus 在R5版本里就引入了 TCP 的负载均衡,在随后的版本里不断地添加新特性,包括支持UDP 的负载均衡。在这篇文章里,我们将探讨 NGINX Plus 是如何实现 TCP 负载均衡的。

为了了解 NGINX Plus 的特性,我们使用了一个简单的测试环境,这个环境包含了应用程序所必需的组件,包括一个可伸缩的数据库。

(点击放大图像)

ec15ef25998b816711ca855e33b314b7.png

MySQL 负载均衡测试环境

在这个环境里,NGINX Plus 作为数据库服务器的反向代理,监听 MySQL 的 3306 端口。反向代理为客户端提供了一个简单的接口,后端的 MySQL 节点可以自由伸缩(甚至离线),不会对客户端有任何影响。我们使用MySQL 命令行工具作为客户端,在测试环境里充当前端应用。

本文所描述的很多特性在开源的 NGINX 和 NGINX Plus 里都有提供。不过,为了简单起见,我们通篇使用 NGINX Plus,有些在 NGINX 里没有的特性我们会明确指明。

我们将探讨如下几个应用场景。

  • TCP 负载均衡

  • 高可用和健康检查

  • 日志和诊断

  • 并发写入

TCP 负载均衡

在为应用程序配置负载均衡之前,需要了解应用程序是如何连接到数据库的。我们使用 MySQL 命令行工具 mysql 连接到 Galera 集群,运行查询,然后关闭连接。不过,在实际当中,很多应用框架使用连接池来减小延迟,有效利用数据库的资源。

TCP 的负载均衡是在 stream context 里配置的,所以我们在 nginx.conf 文件里增加了一个 stream 配置块来配置我们的 MySQL 负载均衡。

stream { include stream.conf; }

我们的 TCP 负载均衡配置与主配置文件是分开的。我们在相同的目录创建 stream.conf 文件。要注意,在默认情况下,conf.d 目录被保留用于 http context 配置,如果在这里添加 stream 配置是不会生效的。

upstream galera_cluster { server 127.0.0.1:33061; # node1 server 127.0.0.1:33062; # node2 server 127.0.0.1:33063; # node3 zone tcp_mem 64k;}server { listen 3306; # MySQL 默认端口  proxy_pass galera_cluster;}

首先,我们定义了一个 upstream 组,名字叫作 galera_cluster,包含了 Galera 集群里的三个 MySQL 节点。在我们的测试环境里,可以分别通过本地的不同端口访问它们。

zone 指令指定了一些内存,NGINX Plus 的工作线程用它来维护负载均衡的状态。server{}配置块定义了 NGINX Plus 是如何处理客户端的。NGINX Plus 监听 MySQL 的默认端口 3306,并将流量转向到 Galera 集群。

为了验证配置的正确性,我们可以使用 MySQL 客户端来获取它所连接的 MySQL 节点的机器名。

$ echo "SHOW VARIABLES WHERE Variable_name = 'hostname'" | mysql --protocol=tcp --user=nginx --password=plus -N 2> /dev/nullhostname node1

我们可以重复同样的命令,来验证负载均衡是否正常。

$ !!;!!;!!hostname node2hostname node3hostname node1

这足以说明轮询负载均衡算法是正常的。不过,如果我们的应用程序使用连接池来访问数据库,那么就有可能导致每个节点的连接数不均衡。另外,我们无法保证每一个连接的负载是均等的,因为处理查询的连接有可能很空闲也有可能很忙。另一种负载均衡算法叫作最少连接数(Least Connections),可以使用 least_conn 指令来配置。

upstream galera_cluster { server 127.0.0.1:33061; # node1 server 127.0.0.1:33062; # node2 server 127.0.0.1:33063; # node3 zone tcp_mem 64k; least_conn;}

现在,如果有客户端连接到数据库,NGINX Plus 会选择集群里具有最少连接数的节点。

高可用和健康检查

在集群里进行负载均衡的最大好处是它可以提供高可用性。基于上述的配置,如果一个新的 TCP 连接建立失败,NGINX Plus 就把这台服务器标记为“down”,并停止向它发送 TCP 数据包。

除了能够探测到宕机的服务器,NGINX Plus 还能自动进行自发的健康检查。因此,在客户端发送请求到那些不可用的服务器之前,NGINX Plus 能够提前检测到它们(这个特性只在 NGINX Plus 里提供)。另外,我们可以通过应用程序级别的健康检测来测试服务器的可用性。我们向每一台服务器发送请求,如果服务器返回响应,说明它运行正常。我们在配置里添加了一些内容。

upstream galera_cluster { server 127.0.0.1:33061; # node1 server 127.0.0.1:33062; # node2 server 127.0.0.1:33063; # node3 zone tcp_mem 64k; least_conn;}match mysql_handshake { send x00; expect ~* x00x00; # 用于过滤握手响应数据包中的空值 }server { listen 3306; # MySQL 默认端口  proxy_pass galera_cluster; proxy_timeout 2s; health_check match=mysql_handshake interval=20 fails=1 passes=2;}

在这个例子里,match 配置块定义了初始化一个 MySQL 握手协议需要的请求和响应数据。server 配置块里的 health_check 指令使用了由 match 配置块定义的模式,并确保 NGINX Plus 只会向可用的服务器发起 MySQL 连接。我们每 20 秒执行一次健康检查,如果连接服务器失败一次,就把这个服务器从 TCP 负载均衡池里移除,如果连续两次健康检查成功,那么就重新把服务器放回负载均衡池。

日志和诊断

NGINX Plus 提供了灵活的日志,所有的 TCP 和 UDP 处理过程都可以被记录下来,用于调试和离线分析。对于使用了 TCP 协议的系统,比如 MySQL,NGINX Plus 会在每次连接关闭之后记录一条日志。log_format 指令指定哪些值可以出现在日志里。我们可以选择出现在 Stream 模块里的任意可用变量值。我们在 stream.conf 文件最上面的 stream context 里定义日志格式。

log_format mysql '$remote_addr [$time_local] $protocol $status $bytes_received ' '$bytes_sent $upstream_addr $upstream_connect_time ' '$upstream_first_byte_time $upstream_session_time $session_time';

在 server 配置块里使用 access_log 指令来启用日志,并指定日志文件的路径和之前配置过的日志格式的名字。

server { ... access_log /var/log/nginx/galera_access.log mysql;}

这样的配置将生成如下格式的日志。

$ tail -3 /var/log/nginx/galera_access.log192.168.91.1 [16/Nov/2016:17:42:18 +0100] TCP 200 369 1611 127.0.0.1:33063 0.000 0.003 12.614 12.614192.168.91.1 [16/Nov/2016:17:42:18 +0100] TCP 200 369 8337 127.0.0.1:33061 0.001 0.001 11.181 11.181192.168.91.1 [16/Nov/2016:17:42:19 +0100] TCP 200 369 1611 127.0.0.1:33062 0.001 0.001 10.460 10.460

通过 nginScript 使用高级日志

nginScript 是 NGINX 的"原生"可编程配置语言。它是为 NGINX 和 NGINX Plus 专门实现的 JavaScript,也是专门为服务器端的使用场景而设计的。

在 Stream 模块里,可以通过 nginScript 访问请求和响应消息里的数据包。也就是说,我们可以查看从客户端发出的 SQL 查询请求,并从中抽取有用的元素,比如 SQL 的 SELECT 或 UPDATE 方法。nginScript 可以把这些值变成普通的 NGINX 变量。在这个例子里,我们的 JavaScript 代码被放在 /etc/nginx/sql_method.js 文件里。

var method = "-"; // 全局变量 var client_messages = 0;function getSqlMethod(s) { if ( !s.fromUpstream ) { client_messages++; if ( client_messages == 3 ) { // SQL 语句出现在第 3 个数据包里  var query_text = s.buffer.substr(1,10).toUpperCase(); var methods = ["SELECT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值