读写分离是一种常见的数据库优化策略,通过将读操作和写操作分发到不同的服务器来提高系统性能。以下是使用Nginx实现读写分离的几种方法:
http {
upstream write_servers {
server 192.168.1.101:3306; # 主数据库(写)
}
upstream read_servers {
server 192.168.1.102:3306; # 从数据库1(读)
server 192.168.1.103:3306; # 从数据库2(读)
server 192.168.1.104:3306; # 从数据库3(读)
}
server {
listen 80;
# 写操作路由到主库
location /write {
proxy_pass http://write_servers;
}
# 读操作路由到从库
location /read {
proxy_pass http://read_servers;
}
}
}
对于MySQL等数据库协议,可以在TCP层实现读写分离:
stream {
upstream mysql_master {
server 192.168.1.101:3306; # 主库
}
upstream mysql_slaves {
server 192.168.1.102:3306; # 从库1
server 192.168.1.103:3306; # 从库2
}
server {
listen 3306;
# 根据SQL语句判断读写
proxy_pass $upstream;
# 简单的SQL解析(示例)
set $upstream mysql_master;
if ($query ~* "^SELECT") {
set $upstream mysql_slaves;
}
}
}
Nginx Plus提供了更高级的数据库负载均衡功能:
stream {
upstream mysql_cluster {
zone tcp_mem 64k;
server 192.168.1.101:3306; # 主库
server 192.168.1.102:3306; # 从库1
server 192.168.1.103:3306; # 从库2
}
server {
listen 3306;
proxy_pass mysql_cluster;
proxy_connect_timeout 1s;
# 根据SQL语句路由
health_check match=read_only;
}
match read_only {
send "SELECT 1;\r\n";
expect ~* "1";
}
}
使用OpenResty可以编写更复杂的路由逻辑:
http {
lua_package_path "/path/to/lua/scripts/?.lua;;";
upstream backend_master {
server 192.168.1.101:3306;
}
upstream backend_slave {
server 192.168.1.102:3306;
server 192.168.1.103:3306;
}
server {
listen 80;
location / {
access_by_lua_file /path/to/router.lua;
proxy_pass http://backend;
}
}
}
router.lua示例:
local method = ngx.req.get_method()
if method == "POST" or method == "PUT" or method == "DELETE" then
ngx.var.backend = "backend_master"
else
ngx.var.backend = "backend_slave"
end
以上配置可以根据实际业务需求进行调整和扩展。对于生产环境,建议进行充分的测试和性能评估。