自学内容网 自学内容网

架构学习第四周--高可用与NoSQL数据库

目录

一、HAProxy介绍

二、HAProxy基本使用

2.1,HAProxy调度算法

2.2,HAProxy高级用法

三、高可用Keepalived介绍

3.1,Keepalived介绍

3.2,Keepalived单主架构实现

3.3,脑裂

四、Keepalived实例--实现单主架构的LVS-DR模型

五、实例--通过Keepalived实现HAProxy高可用

六、NoSQL数据库Redis

6.1,Redis简介

6.2,Redis持久化

6.3,Redis使用介绍

七、实例--构建Redis主从哨兵模式

7.1,主从复制优化

7.2,常见主从复制故障

7.3,实例--构筑主从哨兵模式

八、实例--三节点Redis集群搭建

一、HAProxy介绍

        负载均衡(Load Balance),简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展

        HAProxy是使用C语言开发的开源软件,具有高并发(一万以上)、高性能的TCPHTTP负载均衡器,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计。

#包安装HAProxy

root@ubuntu-test1:~# apt-get install --no-install-recommends software-properties-common
root@ubuntu-test1:~# add-apt-repository ppa:vbernat/haproxy-2.8
root@ubuntu-test1:~# apt-get install haproxy=2.8.\*
 

#编译安装HAProxy

#编译安装Lua

root@ubuntu-test1:~# apt update && apt -y install gcc make libssl-dev libpcre3 libpcre3-dev zlib1g-dev libreadline-dev libsystemd-dev                            #安装依赖包

root@ubuntu-test1:~# wget http://www.lua.org/ftp/lua-5.3.5.tar.gz              #下载新版源码
root@ubuntu-test1:~# tar xf lua-5.3.5.tar.gz -C /usr/local/src/;cd /usr/local/src/
root@ubuntu-test1:/usr/local/src/lua-5.3.5# make linux test                           #编译安装

root@ubuntu-test1:/usr/local/src/lua-5.3.5# cd ~
root@ubuntu-test1:~# export PATH=$PATH:/usr/local/src/lua-5.3.5/src

root@ubuntu-test1:~# lua -v
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio

#编译安装HAProxy

root@ubuntu-test1:~# wget http://www.haproxy.org/download/2.8/src/haproxy-2.8.0.tar.gz

root@ubuntu-test1:~# mkdir /home/apps/
root@ubuntu-test1:~# tar xf haproxy-2.8.0.tar.gz
root@ubuntu-test1:~# cd haproxy-2.8.0/

root@ubuntu-test1:~/haproxy-2.8.0# make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_PROMEX=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.3.5/src/ LUA_LIB=/usr/local/src/lua-5.3.5/src/                                                                                                 #编译安装源码

root@ubuntu-test1:~/haproxy-2.8.0# make install prefix=/home/apps/haproxy
root@ubuntu-test1:~/haproxy-2.8.0# ln -s /home/apps/haproxy/sbin/haproxy /usr/local/sbin/
root@ubuntu-test1:~/haproxy-2.8.0# cd ~
root@ubuntu-test1:~# haproxy -v
HAProxy version 2.8.0-fdd8154 2023/05/31 - https://haproxy.org/

#配置HAProxy

root@ubuntu-test1:~# useradd -m -r -s /sbin/nologin -d /var/lib/haproxy haproxy
root@ubuntu-test1:~# mkdir /etc/haproxy
root@ubuntu-test1:~# vim /etc/haproxy/haproxy.cfg                                     #编辑配置文件
global
   maxconn 100000
   chroot /home/apps/haproxy
   stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
   user haproxy
   group haproxy
   daemon

   nbthread 4
   cpu-map auto:1-4 0-3
   #log 127.0.0.1 local2 info
defaults
   option http-keep-alive
   option forwardfor
   maxconn 100000
   mode http
   timeout connect 300000ms
   timeout client 300000ms
   timeout server 300000ms
listen stats
   bind 0.0.0.0:9999
   stats enable
   log global
   stats uri     /haproxy-status
   stats auth   admin:123456

root@ubuntu-test1:~# vim /lib/systemd/system/haproxy.service            #编辑service文件

[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg  -f /etc/haproxy/conf.d/ -c -q
ExecStart=/usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target
root@ubuntu-test1:~# chown haproxy.haproxy /home/apps/haproxy/ -R

root@ubuntu-test1:~# chown haproxy.haproxy /etc/haproxy/ -R

root@ubuntu-test1:~# systemctl daemon-reload
root@ubuntu-test1:~# systemctl enable --now haproxy.service

二、HAProxy基本使用

2.1,HAProxy调度算法

#Socat是Linux下的一个多功能的网络工具,可以对服务器动态权重和其它状态进行调整

root@ubuntu-test1:~# apt update && apt -y install socat
root@ubuntu-test1:~# echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock

静态算法

不支持socat

static-rr
基于权重的轮询调度,,其后端主机数量没有限制,相当于 LVS 中的 wrr
first
根据服务器列表位置,自上而下调度,只有第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置

动态算法支持socat

roundrobin
基于权重的轮询动态调度算法
leastconn
加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后端服务器而非权重进行优先调度,适合MySQL场景
random
基于随机数作为一致性 hash key ,支持weight 的动态调整,权重越大越容易 获取新请求,适用于大型服务器场或经常添加或删除服务器

source

算法

map-based
取模法,对 源地址进行hash计算,再基于服务器总权重的取模,不支持在线调整权重,此算法为hash-type 指定的默认值
consistent
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,支持在线调整权重
uri算法
基于对用户请求的 URI 的左半部分或整个 uri hash ,再将 hash 结果对总权重进行取模,此算法基于应用层至支持mode http
url_param算法
对用户请求的 url 中的规定的 params 部分进行 hash计算,再将hash结果对总权重进行取模,若未指定param按 roundrobin 算法
hdr算法
对用户每个 http 头部 请求中的指定信息做hash,再将hash结果对总权重进行取模
rdp-cookie算法
Windows 远程桌面的负载,使用 cookie 保持会话,默认是静态,也可通过指定 hash-type 来定义使用取模法还是一致性 hash

#HAProxy配置案例-源地址一致性哈希配置

#10.0.0.151--Rocky-test1

#10.0.0.152--Rocky-test2

[root@Rocky-test1 ~]# yum -y install nginx

[root@Rocky-test1 ~]# systemctl enable --now nginx.service
[root@Rocky-test1 ~]# echo www.wlm.com > /usr/share/nginx/html/index.html
[root@Rocky-test2 ~]# echo www.wlm.io > /usr/share/nginx/html/index.html
root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg                           #创建子配置文件

frontend web_http
   bind 10.0.0.161:80
   use_backend web_hosts

backend web_hosts
   balance source
   hash-type consistent
   server web1 10.0.0.151:80 check weight 2 inter 3000 fall 3 rise 2
   server web2 10.0.0.152:80 check weight 1 inter 3000 fall 3 rise 2
root@ubuntu-test1:~# haproxy -c -f /etc/haproxy/conf.d/web.cfg                #检测配置文件
root@ubuntu-test1:~# systemctl reload haproxy.service

root@ubuntu-test1:~# curl 10.0.0.161                                                             #测试
www.wlm.com

2.2,HAProxy高级用法

#ACL实例

#ACL实例--域名匹配

root@ubuntu-test1:~# vim /etc/hosts

10.0.0.161 www.wlm.com www.wlm.io www.wlm.org
root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg

frontend web_http
   bind 10.0.0.161:80
   balance roundrobin
   acl com_domain hdr_dom(host) -i www.wlm.com
   acl io_domain hdr_dom(host) -i www.wlm.io
   use_backend com_hosts if com_domain
   use_backend io_hosts if io_domain
   default_backend com_hosts

backend com_hosts
   server web1 10.0.0.151:80 check weight 2 inter 3000 fall 3 rise 2

backend io_hosts
   server web2 10.0.0.152:80 check weight 1 inter 3000 fall 3 rise 2

root@ubuntu-test1:~# systemctl reload haproxy.service
root@ubuntu-test1:~# curl www.wlm.org
www.wlm.com
root@ubuntu-test1:~# curl www.wlm.com
www.wlm.com
root@ubuntu-test1:~# curl www.wlm.io
www.wlm.io

#ACL实例--基于源地址访问控制

root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg

frontend web_http

......

   acl inter_src src 10.0.0.151 10.0.0.152
   http-request deny if inter_src

......

root@ubuntu-test1:~# systemctl reload haproxy.service

root@ubuntu-test1:~# curl 10.0.0.161
www.wlm.com

[root@Rocky-test1 ~]# curl 10.0.0.161

curl: (7) Failed to connect to 10.0.0.161 port 80: Connection refused

#ACL实例--动静分离

root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg

frontend web_http
   bind 10.0.0.161:80
   balance roundrobin
   acl static path_end -i .jpg .jpeg .html .css .js .png .gif
   acl php path_end -i .php
   use_backend com_hosts if static
   use_backend io_hosts if php
   default_backend com_hosts

backend com_hosts
   server web1 10.0.0.151:80 check weight 2 inter 3000 fall 3 rise 2

backend io_hosts
   server web2 10.0.0.152:80 check weight 1 inter 3000 fall 3 rise 2

root@ubuntu-test1:~# systemctl reload haproxy.service

三、高可用Keepalived介绍

3.1,Keepalived介绍

        VRRP(Virtual Router Redundancy Protocol),虚拟路由冗余协议,解决静态网关单点风险。物理层面通过路由器、三层交换机实现,软件层面通过Keepalived实现。

        Keepalived是高可用集群的通用无状态应用解决方案,其主要功能:

1,基于vrrp协议完成地址流动;

2,为vip地址所在的节点生成ipvs规则(在配置文件中预先定义);

3,为ipvs集群的各RS做健康状态检测;

4,基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginxhaproxy等服务

#Keepalived安装

root@ubuntu-test1:~# apt list keepalived -a
Listing... Done
keepalived/focal-updates 1:2.0.19-2ubuntu0.2 amd64

#编译安装

root@ubuntu-test1:~# apt update && apt -y install make gcc ipvsadm build-essential pkg-config automake autoconf libipset-dev libnl-3-dev libnl-genl-3-dev libssl-dev libxtables-dev libip4tc-dev libip6tc-dev libmagic-dev libsnmp-dev libglib2.0-dev libpcre2-dev libnftnl-dev libmnl-dev libsystemd-dev                                #安装依赖包

root@ubuntu-test1:~# wget https://keepalived.org/software/keepalived-2.3.0.tar.gz
root@ubuntu-test1:~# tar xf keepalived-2.3.0.tar.gz -C /usr/local/src/

root@ubuntu-test1:~# mkdir /home/apps/
root@ubuntu-test1:~# cd /usr/local/src/keepalived-2.3.0/
root@ubuntu-test1:/usr/local/src/keepalived-2.3.0# ./configure  --prefix=/home/apps/keepalived --disable-iptables                                        #指定目录编译

root@ubuntu-test1:/usr/local/src/keepalived-2.3.0# make -j2 && make install

root@ubuntu-test1:/usr/local/src/keepalived-2.3.0# cp ./keepalived/keepalived.service /lib/systemd/system/                                                                                   #复制service文件
root@ubuntu-test1:/usr/local/src/keepalived-2.3.0# cd ~

root@ubuntu-test1:~# systemctl daemon-reload

root@ubuntu-test1:~# cp /home/apps/keepalived/etc/keepalived/keepalived.conf.sample /home/apps/keepalived/etc/keepalived/             #拷贝模板配置文件至本地,注意网卡名称
root@ubuntu-test1:/home/apps/keepalived# systemctl enable --now keepalived.service

root@ubuntu-test1:~# hostname -I
10.0.0.161 192.168.200.16 192.168.200.17 192.168.200.18

root@ubuntu-test1:~# vim /home/apps/keepalived/etc/keepalived/keepalived.conf    #添加子配置文件路径
include /etc/keepalived/*.conf

root@ubuntu-test1:~# vim /home/apps/keepalived/etc/sysconfig/keepalived   #开启日志
KEEPALIVED_OPTIONS="-D -S 6"

root@ubuntu-test1:~# vim /etc/rsyslog.conf

local6.* /var/log/keepalived.log
root@ubuntu-test1:~# systemctl restart rsyslog.service keepalived.service
root@ubuntu-test1:~# ll /var/log/keepalived.log
-rw-r----- 1 syslog adm 6261 Oct 23 10:44 /var/log/keepalived.log

3.2,Keepalived单主架构实现

#root@ubuntu-test1--10.0.0.161--主节点

#root@ubuntu-test2--10.0.0.162--备节点

#对两台主机进行编译安装Keepalived,同时添加网卡(仅主机模式)做心跳网络

root@ubuntu-test1:~# ip link set ens36 up

root@ubuntu-test1:~# vim /etc/netplan/00-installer-config.yaml
network:
  ethernets:
    ens33:
      dhcp4: no
      addresses:
        - 10.0.0.161/24
      gateway4: 10.0.0.2
      nameservers:
        addresses: [8.8.8.8,223.5.5.5]
    ens36:
      dhcp4: no
      addresses:
        - 192.168.10.10/24

  version: 2
root@ubuntu-test1:~# netplan apply
#同样操作为ubuntu-test2添加192.168.10.20的网卡

#为两个节点配置keepalived配置文件

root@ubuntu-test1:~# vim /home/apps/keepalived/etc/keepalived/keepalived.conf
global_defs {
   router_id LVS_DEVEL_161
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_mcast_group4 230.0.0.100
}
include /etc/keepalived/*.conf
root@ubuntu-test1:~# vim /etc/keepalived/domain1.conf
vrrp_instance VI_1 {
    state MASTER
    interface ens36
    virtual_router_id 88
    priority 100

    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        10.0.0.160/24 dev ens33 label ens33:1
    }
}
root@ubuntu-test1:~# hostname -I
10.0.0.161 10.0.0.160 192.168.10.10
root@ubuntu-test2:~# vim /etc/keepalived/domain1.conf
vrrp_instance VI_1 {
    state BACKUP
    interface ens36
    virtual_router_id 88
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        10.0.0.160/24 dev ens33 label ens33:1
    }
}
root@ubuntu-test2:~# hostname -I
10.0.0.162 192.168.10.20


#在心跳网络抓包

root@ubuntu-test2:~# tcpdump -i ens36 -nn host 230.0.0.100
15:24:52.577437 IP 192.168.10.10 > 230.0.0.100: VRRPv2, Advertisement, vrid 88, prio 100, authtype simple, intvl 1s, length 20

#默认使用多播通信会造成网络堵塞,可设置单播模式减少流量,单播优先级高于多播

root@ubuntu-test1:~# vim /etc/keepalived/domain1.conf

vrrp_instance VI_1 {

.......

    unicast_src_ip 192.168.10.10
    unicast_peer {
        192.168.10.20
    }
}

root@ubuntu-test2:~# vim /etc/keepalived/domain1.conf

vrrp_instance VI_1 {

.......

    unicast_src_ip 192.168.10.20
    unicast_peer {
        192.168.10.10
    }
}

3.3,脑裂

脑裂现象:主备节点同时拥有同一个VIP

产生原因

1,心跳线故障在虚拟机环境中测试可以通过修改网卡的工作模式实现,断开网卡不行)

2,防火墙错误配置(在从节点执行iptables -A INPUT -s 主服务心跳网卡IP -j DROP进行模拟)

3,Keepalived配置错误(多播地址不同,interface错误,virtual_router_id不一致,密码不一致)

脑裂检测方法

在网络相连的其他主机使用arping -I 网卡 -c1 VIP命令

[root@Rocky-test1 ~]# arping -I ens160 -c1 10.0.0.160
ARPING 10.0.0.160 from 10.0.0.151 ens160
Unicast reply from 10.0.0.160 [00:0C:29:40:FA:70]  1.172ms
Unicast reply from 10.0.0.160 [00:0C:29:F7:F6:CF]  1.264ms

四、Keepalived实例--实现单主架构的LVS-DR模型

#在3.2单主架构的基础上配置两台后端真实服务器

#root@Rocky-test1--10.0.0.151

#root@Rocky-test2--10.0.0.152

#在真实服务器配置

[root@Rocky-test1 ~]# echo `hostname` > /usr/share/nginx/html/index.html

[root@Rocky-test1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@Rocky-test1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@Rocky-test1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@Rocky-test1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@Rocky-test1 ~]# ifconfig lo:1 10.0.0.160/32

#在Rocky-test2上进行同样操作

#在Keepalived节点上为子文件追加相同配置

root@ubuntu-test2:~# vim /etc/keepalived/domain1.conf

......

virtual_server 10.0.0.160 80 {
        delay_loop 3
        lb_algo wrr
        lb_kind DR
        protocol TCP
        real_server 10.0.0.151 80 {
          weight 1
          HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 3
            delay_before_retry 1
          }
        }
        real_server 10.0.0.152 80 {
          weight 2
          HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 3
            delay_before_retry 1
          }
        }
}
root@ubuntu-test2:~# systemctl restart keepalived.service
root@ubuntu-test1:~# ipvsadm -Ln                                #查看LVS调度规则
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.160:80 wrr
  -> 10.0.0.151:80                Route   1      0          0
  -> 10.0.0.152:80                Route   2      0          0

root@ubuntu-test3:~# while true;do curl 10.0.0.160;sleep 1;done #在其他客户端访问测试
Rocky-test1
Rocky-test2
Rocky-test2
Rocky-test1
Rocky-test2
Rocky-test2
Rocky-test1
Rocky-test2

Rocky-test2

#添加vrrp_script自定义资源监控脚本,实现节点自动切换

root@ubuntu-test1:~# vim /home/apps/keepalived/etc/keepalived/keepalived.conf

.......

vrrp_script check_keepalived {
   script /etc/keepalived/check_keepalived.sh
   interval 1
   timeout 2
   weight -30
   fall 2
   rise 3
}
root@ubuntu-test1:~# vim /etc/keepalived/domain1.conf
vrrp_instance VI_1 {
.......

    track_script {
        check_keepalived
    }

}
root@ubuntu-test1:~# vim /etc/keepalived/check_keepalived.sh

#!/bin/bash
/usr/bin/killall -0 keepalived
root@ubuntu-test1:~# chmod +x /etc/keepalived/check_keepalived.sh

root@ubuntu-test1:~# systemctl restart keepalived.service
root@ubuntu-test1:~# systemctl stop keepalived.service                            #模拟服务故障
root@ubuntu-test1:~# hostname -I
10.0.0.161 192.168.10.10

五、实例--通过Keepalived实现HAProxy高可用

#ubuntu-test1--10.0.0.161--部署Keepalived+HAProxy

#ubuntu-test2--10.0.0.162--部署Keepalived+HAProxy

#Rocky-test1--10.0.0.151--部署Nginx

#Rocky-test2--10.0.0.152--部署Nginx

#先在ubuntu-test1,2创建HAProxy和keepalived子配置文件

root@ubuntu-test1:~# vim /etc/keepalived/domain1.conf

vrrp_instance VI_1 {
    state MASTER
    interface ens36
    virtual_router_id 88
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        10.0.0.160/24 dev ens33 label ens33:1
    }
    unicast_src_ip 192.168.10.10
    unicast_peer {
        192.168.10.20
    }
    track_script {
        check_keepalived
    }
}

root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg

frontend web_http
   bind 10.0.0.160:80
   use_backend web_hosts
backend web_hosts
   balance roundrobin
   server web1 10.0.0.151:80 check weight 2 inter 3000 fall 3 rise 2
   server web2 10.0.0.152:80 check weight 1 inter 3000 fall 3 rise 2
root@ubuntu-test1:~# systemctl reload haproxy.service keepalived.service

#编辑内核参数,允许进程绑定到不属于本机接口的 IP 地址

root@ubuntu-test1:~# vim /etc/sysctl.conf

net.ipv4.ip_nonlocal_bind = 1
root@ubuntu-test1:~# sysctl -p

#在其他客户端访问测试

[root@Rocky-test3 ~]# curl 10.0.0.160
10.0.0.151 Rocky-test1
[root@Rocky-test3 ~]# curl 10.0.0.160
10.0.0.151 Rocky-test1
[root@Rocky-test3 ~]# curl 10.0.0.160
10.0.0.152 Rocky-test2


#在ubuntu-test1添加VRRP脚本实现高可用

root@ubuntu-test1:~# vim /etc/keepalived/check_haproxy.sh
#!/bin/bash
if /usr/bin/killall -0 haproxy ;then
        exit 0
else
        systemctl restart haproxy
fi
root@ubuntu-test1:~# chmod +x /etc/keepalived/check_haproxy.sh

root@ubuntu-test1:~# vim /home/apps/keepalived/etc/keepalived/keepalived.conf

.......

vrrp_script check_haproxy {
   script /etc/keepalived/check_haproxy.sh
   interval 1
   timeout 2
   weight -30
   fall 2
   rise 3
}

root@ubuntu-test1:~# vim /etc/keepalived/domain1.conf

.......
    track_script {
        check_keepalived
        check_haproxy
    }
}
root@ubuntu-test1:~# systemctl restart keepalived.service

#对后端服务器进行证书加密,HAProxy配置四层代理

[root@Rocky-test1 ~]# mkdir /home/nginx.cert
[root@Rocky-test1 ~]# cd /home/nginx.cert
[root@Rocky-test1 nginx.cert]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
[root@Rocky-test1 nginx.cert]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.wlm.com.key -out www.wlm.com.csr
[root@Rocky-test1 nginx.cert]# openssl x509 -req -days 365 -in www.wlm.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.wlm.com.crt
[root@Rocky-test1 nginx.cert]# cat www.wlm.com.crt ca.crt > www.wlm.com.pem

[root@Rocky-test1 ~]# vim /etc/nginx/nginx.conf

    server {
        listen 80;
        listen 443 ssl http2;
        server_name  www.wlm.com;
        root         /usr/share/nginx/html;
        ssl_certificate /home/nginx.cert/www.wlm.com.pem;
        ssl_certificate_key /home/nginx.cert/www.wlm.com.key;
        if ( $scheme = http ) {
            rewrite ^(.*) https://$server_name/$1 redirect;
        }
[root@Rocky-test1 ~]# systemctl reload nginx.service

root@ubuntu-test1:~# vim /etc/haproxy/conf.d/web.cfg
frontend web_http
   mode tcp
   bind 10.0.0.160:80
   use_backend web_hosts
backend web_hosts
   balance roundrobin
   mode tcp
   server web1 10.0.0.151:80 check weight 2 inter 3000 fall 3 rise 2
   server web2 10.0.0.152:80 check weight 1 inter 3000 fall 3 rise 2

[root@Rocky-test3 ~]# curl -k https://www.wlm.com                                          #测试成功

10.0.0.151 Rocky-test1

六、NoSQL数据库Redis

6.1,Redis简介

        NoSQL 数据库,全称为 Not Only SQL,既可以适用关系型数据库也可以使用其他类型的数据存储。

        Redis是一个开源的Key-Value存储系统,使用C语言开发,支持多种编程语言的API。它是一个高速缓存数据库,采用内存存储,并支持持久化,能够提供高性能的数据读写操作。

Redis特性:

属于非关系数据库,键值对数据库

高性能

纯内存操作,数据操作采用单线程(还有其他线程做备份等操作)

支持持久化

支持多种数据结构,编程语言

Redis高性能原因:

纯内存,数据操作较硬盘快

单线程操作数据,避免线程竞争,非阻塞IO,取消锁机制,epoll机制IO

Redis常见应用场景

缓存

缓存RDBMS中数据,比如网站的查询结果、商品信息、微博、新闻、消息

Session 共享

实现Web集群中的多服务器间的session共享

计数器

商品访问排行榜、浏览数、粉丝数、关注、点赞、评论等和次数相关的数值统计场景

社交

朋友圈、共同好友、可能认识他们等

地理位置

基于地理信息系统实现摇一摇、附近的人、外卖等功能

消息队列

ELK等日志系统缓存、业务的订阅/发布系统

名称

概念

解决方法

缓存穿透

缓存和Redis数据库中没有,

MySQL关系数据库也没有的数据,被请求访问

在接口层增加校验,如用户鉴权校验

对无法查询的数据短期定义key-null

缓存击穿

缓存和Redis数据库中没有,

MySQL数据库中有的数据,被请求访问

设置热点数据永远不过期

缓存雪崩

缓存中数据大批量到过期时间,

而查询数据量巨大,引起数据库压力过大甚至

设置热点数据永远不过期

缓存数据的过期时间设置随机

若数据库为分布式,热点数据均匀

分布不同缓存数据库

#编译安装Redis

root@ubuntu-test1:~# apt update && apt -y install gcc make libjemalloc-dev libsystemd-dev                                                                                                  #安装依赖包

root@ubuntu-test1:~# wget http://download.redis.io/releases/redis-7.2.0.tar.gz

root@ubuntu-test1:~# tar xf redis-7.2.0.tar.gz
root@ubuntu-test1:~# mkdir /home/apps
root@ubuntu-test1:~# cd redis-7.2.0/
root@ubuntu-test1:~/redis-7.2.0# make -j 2 USE_SYSTEMD=yes PREFIX=/home/apps/redis install
root@ubuntu-test1:~# echo 'PATH=/home/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh
root@ubuntu-test1:~# . /etc/profile.d/redis.sh

#优化参数,消除报警

root@ubuntu-test1:~# cat /proc/sys/net/core/somaxconn                        #需要大于128
4096

root@ubuntu-test1:~# echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
root@ubuntu-test1:~# chmod +x /etc/rc.local

root@ubuntu-test1:~# vim /etc/sysctl.conf

vm.overcommit_memory = 1
root@ubuntu-test1:~# sysctl -p

#创建Redis用户和Service文件

root@ubuntu-test1:~# useradd -r -s /sbin/nologin redis

root@ubuntu-test1:~# mkdir /home/apps/redis/{etc,data,log,run}

root@ubuntu-test1:~# cp /root/redis-7.2.0/redis.conf /home/apps/redis/etc/

root@ubuntu-test1:~# chown redis.redis -R /home/apps/redis/

root@ubuntu-test1:~# vim /lib/systemd/system/redis.service

[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=/home/apps/redis/bin/redis-server /home/apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=1000000

[Install]
WantedBy=multi-user.target

root@ubuntu-test1:~# systemctl daemon-reload
root@ubuntu-test1:~# systemctl enable --now redis.service

root@ubuntu-test1:~# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info
# Server
redis_version:7.2.0
......

# Keyspace
127.0.0.1:6379> exit


#修改配置文件,开启远程端口

root@ubuntu-test1:~# vim /home/apps/redis/etc/redis.conf

bind 0.0.0.0

logfile "/home/apps/redis/log/redis.log"
save 3600 1 300 100 60 10000

dir /home/apps/redis/data
repl-diskless-sync no                                                            #取消无盘同步,使用硬盘同步

rename-command FLUSHALL ""                                          #禁用该命令
rename-command SHUTDOWN ""

requirepass 123456
root@ubuntu-test1:~# systemctl restart redis.service

root@ubuntu-test1:~# grep -vE '^#|^$' /home/apps/redis/etc/redis.conf | grep slow
slowlog-log-slower-than 10000                                #慢查询定义的时间
slowlog-max-len 128                                                #保留的最近慢查询记录上限
root@ubuntu-test1:~# redis-cli -a 123456
127.0.0.1:6379> slowlog len                                #查询慢查询条数
(integer) 0

127.0.0.1:6379> slowlog get                               #查看慢查询记录

6.2,Redis持久化

方法

RDB(Redis DataBase)

AOF(AppendOnlyFile)

概念
基于某个时间点的快照,
只保留一个最新版本,
相当于MySQL 的完全备份

初次启动时进行完全备份,

后续将持续执行增量性备份

实现

方式

save 同步, 不推荐,
使用主进程完成,会阻赛其它命令
bgsave:异步后台执行
会开启子进程,不会阻赛其它命令

bgrewriteaof:会自动开启,也可手动执行,对数据进行重新整理

优点
1,只保存某个时间点的数据,恢复无需额外操作,适合灾备处理
2,在大集群时恢复速度较AOF快

1,数据安全性相对较高,每秒自动执行

2,写入操作采用append模式,宕机也不会损坏数据

3,会自动重写,重写操作绝对安全

4,AOF有记录所有操作的日志文件,可用于数据重建

缺点

1,不能实时保存,存在少量数据丢失风险

2,在数据集较大时,子进程可能会非常耗时,导致客户端长时间等待

1,AOF会记录重复操作,数据量大

2,AOF在恢复大数据集的速度比 RDB

3,fsync策略是appendfsync no时, AOF保存到磁盘的速度可能会慢于RDB

4,更易出现BUG

redis.conf内的RDB相关参数
save 3600 1 300 100 60 10000                        #bgsave触发条件

dir /home/apps/redis/data                                 #bgsave存放位置

dbfilename dump.rdb                                        #RDB文件名  

#正确开启AOF功能(RDB已开启且已有数据),先动态修改内存参数,再修改配置文件

#AOF默认为关闭,初次开启并重启服务后,AOF会因为较高优先级先启动,AOF默认无数据文件会导致旧数据丢失

root@ubuntu-test1:~# ll /home/apps/redis/data/
-rw-r--r-- 1 redis redis  108 Oct 30 16:17 dump.rdb
root@ubuntu-test1:~# redis-cli -a 123456
127.0.0.1:6379> KEYS *
1) "b"
2) "a"
3) "c"
127.0.0.1:6379> CONFIG GET appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> CONFIG SET appendonly yes
OK
127.0.0.1:6379> exit
root@ubuntu-test1:~# ll /home/apps/redis/data/
drwxr-xr-x 2 redis redis 4096 Oct 30 16:40 appendonlydir/
-rw-r--r-- 1 redis redis  108 Oct 30 16:17 dump.rdb
root@ubuntu-test1:~# vim /home/apps/redis/etc/redis.conf

appendonly yes

#模拟服务重启,测试数据是否会丢失

root@ubuntu-test1:~# systemctl restart redis.service

root@ubuntu-test1:~# redis-cli -a 123456
127.0.0.1:6379> KEYS *
1) "a"
2) "c"
3) "b"

#Redis服务BGWRITEAOF配置介绍

root@ubuntu-test1:~# grep -vE '^#|^$' /home/apps/redis/etc/redis.conf|grep aof
appendfilename "appendonly.aof"
auto-aof-rewrite-percentage 100              #当增长超过100比例会触发执行
auto-aof-rewrite-min-size 64mb               #触发的最小文件大小
aof-load-truncated yes                             #是否加载末尾异常的AOF文件(如断电,主进程kill)
aof-use-rdb-preamble yes
aof-timestamp-enabled no
aof-rewrite-incremental-fsync yes

root@ubuntu-test1:~# grep -vE '^#|^$' /home/apps/redis/etc/redis.conf|grep appendfsync
appendfsync everysec                        
no-appendfsync-on-rewrite no                #是否暂缓AOF记录立即同步至磁盘,默认否最安全但是会造成阻塞;开启暂时会避免阻塞,但是Redis故障会导致数据丢失

6.3,Redis使用介绍

Redis常用命令:

INFO--显示Redis运行状态信息

SELECT--切换数据库

KEYS--查看当前数据库下的所有key,慎用

BGSAVE--手动执行RDB

DBSIZE--返回当前库下的所有key 数量

FLUSHDB--强制清空当前库中的所有key,慎用

FLUSHALL--删除所有数据,慎用

SHUTDOWN--关闭服务

TYPE--查询key的数据类型

数据类型特点
字符串string基本数据类型,能包含任意类型的数据,单个值最大512M字节
列表list有序,可重复,可实现队列和栈
集合set无序,不可重复,实现集合操作(与sinter,或sunion,非sdiff)
有序集合zset有序,无重复元素,由score(不可重复)和value组成,用于实现排行榜
字典hash无序,每个元素都是键值对,可存储复杂数据

七、实例--构建Redis主从哨兵模式

7.1,主从复制优化

        Redis的主从同步是非阻塞的,即同步过程不会影响主服务器的正常访问;其主从复制分为全量同步和增量同步两种,主节点重启会导致全量同步,从节点重启只会导致增量同步。

全量复制触发情况:

        1,从节点首次连接主节点;

        2,从节点的复制偏移量不在复制积压缓冲区内;

        3,从节点无法连接主节点超过一定的时间;

避免全量复制:

        1,初次全量复制不可避免,后续全量复制可利用级联结构在低业务量时进行;

        2,增大repl-backlog-size数值,避免复制积压缓冲区不足;

        3,节点RUN_ID不匹配:主节点重启导致RUN_ID变化,会触发全量复制,可用config命令动态修改配置。故障转移例如哨兵或集群选举新的主节点也不会全量复制(从主节点重启只会触发增量复制);

避免复制风暴:

1,单主节点复制风暴(当主节点重启,多从节点复制)
解决方法:使用级联复制
2,单机器多实例复制风暴(机器宕机后,大量全量复制)
解决方法:主节点分散多机器

7.2,常见主从复制故障

1,主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据

2,rename-command命令不一致,错执行被禁用的命令会导致主从节点不同步

3,从节点配置的master密码错误,验证不通过,无法建立主从同步

4,Redis版本不同导致兼容问题

5,开启了安全模式且未开启远程设置,无法进行远程连接

7.3,实例--构筑主从哨兵模式

#ubuntu-test1--10.0.0.161

#ubuntu-test2--10.0.0.162

#ubuntu-test3--10.0.0.163

#为三台服务器编译安装Redis并保持redis.conf配置一致(注意,Redis密码需要相同)

#以162为主节点,163为从节点创建主从同步测试

root@ubuntu-test3:~# vim /home/apps/redis/etc/redis.conf        #修改配置文件重启生效

replicaof 10.0.0.162 6379

masterauth 123456

root@ubuntu-test3:~# redis-cli -a 123456                                         #配置修改在从节点进行
127.0.0.1:6379> replicaof 10.0.0.162 6379                                       #在线修改配置
OK

127.0.0.1:6379> config set masterauth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.162
master_port:6379

master_link_status:up

root@ubuntu-test2:~# redis-cli -a 123456                                        #登录主节点查看信息
127.0.0.1:6379> info replication
role:master
connected_slaves:1
slave0:ip=10.0.0.163,port=6379,state=online,offset=3290,lag=0
127.0.0.1:6379> set key1 1
root@ubuntu-test3:~# redis-cli -a 123456 get key1                         #确认主节点数据同步
"1"

#取消163从节点

root@ubuntu-test3:~# redis-cli -a 123456 replicaof no one     #在从节点执行取消主从命令
root@ubuntu-test3:~# redis-cli -a 123456 info replication       #验证信息
# Replication
role:master
connected_slaves:0

#正式搭建主从哨兵架构

#在所有节点配置下列信息

root@ubuntu-test1:~# vim /home/apps/redis/etc/redis.conf       

replicaof 10.0.0.161 6379                                                        #7.2版本主节点不能配置该项

masterauth 123456

requirepass 123456

root@ubuntu-test1:~# cp ./redis-7.2.0/sentinel.conf /home/apps/redis/etc/
root@ubuntu-test1:~# chown redis.redis /home/apps/redis/etc/sentinel.conf

root@ubuntu-test1:~# vim /home/apps/redis/etc/sentinel.conf  

dir /home/apps/redis/data

logfile "/home/apps/redis/log/sentinel.log"

sentinel monitor mymaster 10.0.0.161 6379 2

sentinel auth-pass mymaster 123456

sentinel down-after-milliseconds mymaster 5000                #判断主节点下线时间5s

root@ubuntu-test1:~# systemctl restart redis.service

root@ubuntu-test1:~# vim /lib/systemd/system/redis-sentinel.service

[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/home/apps/redis/bin/redis-sentinel /home/apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
RuntimeDirectory=redis RuntimeDirectory
Mode=0755
[Install]
WantedBy=multi-user.target

root@ubuntu-test1:~# systemctl enable --now redis-sentinel.service
root@ubuntu-test1:~# redis-cli -p 26379 info sentinel                              #查看哨兵状态
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.161:6379,slaves=2,sentinels=3

#停止主节点服务,验证哨兵机制

root@ubuntu-test1:~# systemctl stop redis.service
root@ubuntu-test2:~# redis-cli -a 123456 info replication
# Replication
role:slave
master_host:10.0.0.163
master_port:6379
master_link_status:up
root@ubuntu-test3:~# redis-cli -a 123456 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.162,port=6379,state=online,offset=88277,lag=0
master_failover_state:no-failover

#重启启动ubuntu-test1上的Redis

root@ubuntu-test1:~# systemctl start redis.service
root@ubuntu-test1:~# redis-cli -a 123456 info replication
# Replication
role:slave
master_host:10.0.0.163

master_port:6379
master_link_status:up
root@ubuntu-test1:~# cat /home/apps/redis/etc/redis.conf | grep replicaof          #哨兵自动修改配置文件
replicaof 10.0.0.163 6379

八、实例--三节点Redis集群搭建

        哨兵只能解决Redis高可用,实现自动故障转移,无法解决单主节点的写入性能瓶颈,使用分布式集群可解决该问题(建立Cluster时,节点需要清空数据,且网络中不能有哨兵主从)

#ubuntu-test1--10.0.0.161--Redis主节点

#ubuntu-test2--10.0.0.162--Redis主节点

#ubuntu-test3--10.0.0.163--Redis主节点

#ubuntu-test--10.0.0.160--安装多实例Redis做从节点

#在10.0.0.161/162/163主节点上修改配置文件

root@ubuntu-test1:~# vim /home/apps/redis/etc/redis.conf

masterauth "123456"

requirepass "123456"

cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-require-full-coverage no


#在10.0.0.160上配置多实例

root@ubuntu:~# vim /home/apps/redis/etc/redis6379.conf

bind 0.0.0.0

port 6379
pidfile "/var/run/redis_6379.pid"

logfile "/home/apps/redis/log/redis6379.log"

dbfilename "dump6379.rdb"

masterauth "123456"

requirepass "123456"

cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-require-full-coverage no

root@ubuntu:~# sed 's/6379/6380/' /home/apps/redis/etc/redis6379.conf > /home/apps/redis/etc/redis6380.conf
root@ubuntu:~# sed 's/6379/6381/' /home/apps/redis/etc/redis6379.conf > /home/apps/redis/etc/redis6381.conf
root@ubuntu:~# vim /lib/systemd/system/redis6379.service

......

ExecStart=/home/apps/redis/bin/redis-server /home/apps/redis/etc/redis6379.conf --supervised systemd
......
root@ubuntu:~# sed 's/6379/6380/' /lib/systemd/system/redis6379.service > /lib/systemd/system/redis6380.service
root@ubuntu:~# sed 's/6379/6381/' /lib/systemd/system/redis6379.service > /lib/systemd/system/redis6381.service

root@ubuntu:~# systemctl daemon-reload
root@ubuntu:~# systemctl enable --now redis6379.service redis6380.service redis6381.service

root@ubuntu:~# tree /home/apps/redis/
/home/apps/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof -> redis-server
│   ├── redis-check-rdb -> redis-server
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── data
│   ├── nodes-6379.conf
│   ├── nodes-6380.conf
│   └── nodes-6381.conf
├── etc
│   ├── redis6379.conf
│   ├── redis6380.conf
│   └── redis6381.conf
├── log
│   ├── redis6379.log
│   ├── redis6380.log
│   ├── redis6381.log
│   └── redis.log
└── run
root@ubuntu-test1:~# redis-cli -a 123456 --cluster create 10.0.0.161:6379 10.0.0.162:6379 10.0.0.163:6379 10.0.0.160:6379 10.0.0.160:6380 10.0.0.160:6381 --cluster-replicas 1                                                                                        #组建集群
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.160:6380 to 10.0.0.161:6379
Adding replica 10.0.0.160:6381 to 10.0.0.162:6379
Adding replica 10.0.0.160:6379 to 10.0.0.163:6379
M: d48544aa7962934c443741a43f88cbb38cb5244d 10.0.0.161:6379
   slots:[0-5460],[7365],[15495] (5461 slots) master
M: c954b82ff2f86fc5feecca51b6e481010e98dc3c 10.0.0.162:6379
   slots:[3300],[5461-10922],[15495] (5462 slots) master
M: fba93a9b96fff704a86b66fbf83ffb33824bc466 10.0.0.163:6379
   slots:[3300],[7365],[10923-16383] (5461 slots) master
S: ddc047ac5f0ef2bdc1e77076aace31ecc219d7fa 10.0.0.160:6379
   replicates fba93a9b96fff704a86b66fbf83ffb33824bc466
S: bfd046c0b9f4ac6318cfb218edb2327d8b2d5daa 10.0.0.160:6380
   replicates d48544aa7962934c443741a43f88cbb38cb5244d
S: 7f2e05c72c2c54eece48a908d0a3c59662d0f8c7 10.0.0.160:6381
   replicates c954b82ff2f86fc5feecca51b6e481010e98dc3c
Can I set the above configuration? (type 'yes' to accept): yes

root@ubuntu-test1:~# cat /home/apps/redis/data/nodes-6379.conf     #节点信息存放文件
root@ubuntu-test1:~# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
15af0ab4decfe08de958223266efb401dd29b377 10.0.0.161:6379@16379 myself,master - 0 1730704529000 1 connected 0-5460
60d3a2d1b5c24e03683e7453e7c05f6b6ebdeb56 10.0.0.162:6379@16379 master - 0 1730704533365 2 connected 5461-10922
148d09fcaa36daeb8ab367338eede0f6a01dd941 10.0.0.160:6381@16381 slave 60d3a2d1b5c24e03683e7453e7c05f6b6ebdeb56 0 1730704531000 2 connected
d8ee0bd1c084a34e3a77ebfc860156ea44a54644 10.0.0.160:6380@16380 slave 15af0ab4decfe08de958223266efb401dd29b377 0 1730704531000 1 connected
be21431937366822cb55ef481d9562c0e9253583 10.0.0.160:6379@16379 slave 40d8dfe76324fab1925bf1c457eb4aaf2f9b9ac4 0 1730704532328 3 connected
40d8dfe76324fab1925bf1c457eb4aaf2f9b9ac4 10.0.0.163:6379@16379 master - 0 1730704531291 3 connected 10923-16383

root@ubuntu-test1:~# redis-cli -a 123456 -c                                        #-c自动跳转槽位
127.0.0.1:6379> set a 1
-> Redirected to slot [15495] located at 10.0.0.163:6379
OK
10.0.0.163:6379> set z 2
-> Redirected to slot [8157] located at 10.0.0.162:6379
OK
10.0.0.162:6379> get a
-> Redirected to slot [15495] located at 10.0.0.163:6379
"1"

        Redis cluster的从节点是只读连接的,也就是说集群模式中的从节点是拒绝任何读写请求的。并且当多个节点运行一段时间后,可能会出现倾斜现象,某个节点数据偏多,内存消耗更大,或者用户请求访问更多,主要原因如下:

节点和槽分配不均

不同槽对应键值数量差异较大

包含bigkey,建议少用

内存相关配置不一致

热点数据不均衡 : 一致性不高时,可以使用本缓存和MQ


原文地址:https://blog.csdn.net/weixin_69286966/article/details/142920561

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!