速度快
说到Redis的速度快,大家的第一反应一定是内存读取,那是肯定的,但如果面试的时候仅仅说到这点,那还是远远不够的,至少还有以下三点要补充:
Redis是用C语言实现的,而众所周知,C语言是“距离”操作系统最近的的编程语言,执行速度快
Redis采用了单线程的架构(这点很容易遗忘,但是是Redis的最重要特性),避免了多线程的资源竞争问题
Redis的源码非常精简,可以说是集性能和优雅于一身的代码
基于键值对的服务器
Redis的全程是Remote Dictionary Server,是集合了五种数据结构:字符串、列表、哈希、集合、有序集合,可以说五种数据结构都是围绕于key-value的形式,而value不仅仅可以是值,还能是具体的数据结构,这给予了Redis强大的变化性和灵活能力。
丰富的功能
除了数据结构的强大,另外就是Redis所提供的丰富的功能了:
提供了key过期的功能,这能运用于实现缓存
提供了发布订阅的功能,可运用于消息队列,如celery
支持lua脚本功能,当觉得Redis的命令实现功能不够时,就能利用lua来创建新的功能
提供了简单的事务功能,不过不能支持回滚,但也能一定程度上保持事务的特性
提供了pipeling功能,这样客户端可以将多条命令一次io,减少了网络的开销
简单稳定
Redis的简单表现在两方面,一方面是在3.0版本之前源代码仅3万行,后面3.0加入了集群后代码加到了5万行,而5万行的源代码对于开发人员来说,要理解掌握它也显得并不是那么难;另一方面就是Redis是单线程的结构,这使得Redis的服务端处理模型变得简单,客户端开发也显得简单。Redis虽然代码少,并且是单线程的,但是它又非常的稳定,很少会出现因为自身bug而down掉的情况。
客户端语言多
Redis目前基本可以说和MySQL的知名度一样高了,太多的运用场景,太多的支持语言,常见的比如:java的jedis,Python的redis、PHP、C、C++等等。
持久化
Redis还支持两种方式的持久化,即将数据写入磁盘的方法,RDB和AOF,两种方法各有利弊,这里就不详细介绍了。
主从复制
那数据库的主从复制、集群功能是非常重要的,可以在Redis异常挂了后不影响客户端的使用,而Redis也是支持主从复制功能。
高可用和分布式
Redis从2.8版本后提供了高可用实现的Redis Sentinel,即Redis的“哨兵机制”,可以保证Redis节点的故障发现和自动转移,这实现了Redis强大的分布式功能。
缓存
缓存可以说是Redis最常用的功能之一了,合理的缓存不仅可以加快速度的访问速度,以及可以减少后端的压力(通常就是MySQL的压力)。可以说,一个合理的缓存可以极大地提高网站的性能。
排行榜系统
利用Redis的列表和有序集合的特点,可以制作排行榜系统,而排行榜系统目前在商城类、新闻类、博客类等等,都是比不可缺的。
计数器应用
计数器的应用基本和排行榜系统一样,都是多数网站的普遍需求,如视频网站的播放计数,电商网站的浏览数等等,但这些数量一般比较庞大,如果存到关系型数据库,对MySQL或者其他关系型数据库的挑战还是很大的,而Redis基本可以说是天然支持计数器应用。
消息队列系统
Redis支持发布订阅系统和阻塞队列的功能,可以充当一般的消息队列功能,虽然和专业的消息队列MQ比如RebbitMQ比起来还优点差距,但也基本够用了,比如celery的异步模型,Redis也是celery官方指定的2种队列的一种。
社交网络
对于社交网络来说,一般用户量是及其庞大的,此时的关系型数据库就捉襟见肘了,比如好有点赞、关注、推送等等功能,用Redis就能比较轻松地实现这些功能
redis虽然是一个内存级别的缓存程序,但是它可以将内存的数据按照一定的策略保存到硬盘中,从而实现数据的持久化保持。目前,redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF,这两种模式分别类似于MySQL备份中dump和二进制日志方式。
RDB模式RDB模式工作原理
RDB(Redis DataBase,redis数据库):基于时间的快照,默认只保留当前最新的一次快照,优点是执行速度比较快,缺点是可能会丢失上一次快照到当前快照时间点之间的数据。其工作原理如下图所示,首先redis将内存中的数据备份到二进制RDB文件中,之后如果redis处于关闭状态,则内存中的数据将不复存在,但是redis重启后,会自动加载之前备份的RDB文件,重新读取数据。
要想将redis内存中的数据备份到RDB文件中,我们可以使用到save指令(同步,会阻赛其它命令,不推荐使用)、bgsave指令(异步后台执行,不影响其它命令的执行)或者自动(制定规则,自动执行)的方式。例如RDB bgsave的方式,其实现快照的具体过程如下图所示:
RDB bgsave实现快照时,redis会从master主进程先fork一个子进程,使用写时复制机制,子进程将内存中的数据保存为一个临时RDB文件,当所有数据保存完毕之后再将上一次的RDB文件替换掉,然后关闭子进程,从而保证每一次做RDB快照所保存的数据都是完整的。
RDB模式的优缺点
RDB模式优点
RDB模式的优点主要表现为以下几点:
①RDB快照保存了某个时间点的数据,可以通过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操作,不推荐)命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本,很适合备份,并且此文件格式也支持有不少第三方工具可以进行后续的数据分析。
②RDB可以最大化Redis的性能,父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/O操作。
③RDB在大量数据,比如几个G的数据,恢复的速度比AOF的快。
RDB模式缺点
RDB模式的缺点表现在两方面:
①不能实时保存数据,可能会丢失自上一次执行RDB备份到当前的内存数据。如果需要尽量避免在服务器故障时丢失数据,那么RDB并不适合。虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但RDB文件需要保存整个数据集的状态,所以它并不是一个轻松快速的操作,因此一般会超过5分钟以上才保存一次RDB文件,在这种情况下,一旦发生故障停机就可能会丢失好几分钟的数据。
②当数据量非常大的时候,从父进程fork子进程进行保存至RDB文件时需要一点时间,可能是毫秒或者秒,取决于磁盘IO性能。在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端,如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或更久。虽然AOF重写也需要进行fork(),但无论AOF重写的执行间隔有多长,数据的持久性都不会有任何损失。
AOF模式AOF模式工作原理
AOF(Append Only File):按照操作顺序依次将操作追加到指定的日志文件末尾。AOF模式和RDB模式一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障最多只丢失1秒钟之内的数据,也可以设置不同的fsync策略always,即设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的I/O影响。同时启用RDB和AOF进行恢复时,默认AOF文件优先级高于RDB文件,即会使用AOF文件进行恢复。
注意:AOF模式默认是关闭并且没有数据文件存在的,第一次开启AOF并重启服务生效后,会因为AOF的优先级高于RDB而导致所有数据丢失。
AOF模式的优缺点
AOF模式优点
AOF模式的优点表现为:
①数据安全性相对较高,根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次fsync,在这种配置下,redis仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
②由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek,即使出现宕机现象也不会破坏日志文件中已经存在的内容。如果本次操作只是写入了一半数据就出现了系统崩溃问题,在redis下次启动之前,可以通过redis-check-aof工具来解决数据一致性的问题。
③redis可以在AOF文件体积变得过大时自动地在后台对AOF进行重写,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为redis在创建新AOF文件的过程中,append模式不断的将修改数据追加到现有的AOF文件里面,即使重写过程中发生停机,现有的 AOF文件也不会丢失。而一旦新AOF文件创建完毕,redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。
④AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作,事实上也可以通过该文件完成数据的重建。AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。
AOF模式缺点
AOF模式的缺点表现为:
①即使有些操作是重复的也会全部记录,因此AOF的文件大小要大于RDB格式的文件。
②AOF在恢复大数据集时的速度比RDB的恢复速度要慢。
③根据fsync策略不同,AOF速度可能会慢于RDB。
④在AOF模式中,bug出现的可能性会更多。
RDB和AOF的选择 选择何种模式要依据实际情况来定:
①如果主要充当缓存功能,或者可以承受数分钟数据的丢失,通常生产环境中只开启RDB即可,这也是默认设置。
②如果数据需要持久保存,一点都不能丢失,可以同时开启RDB和AOF。
③一般不建议只开启AOF。
redis 哨兵(Sentinel)
redis 集群介绍
主从架构无法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题导致master无法使用,而redis主从复制无法实现自动的故障转移(将slave 自动提升为新master),需要手动修改环境配置,才能切换到slave redis服务器,另外当单台Redis服务器性能无法满足业务写入需求的时候,也无法横向扩展Redis服务的并行写入性能
需要解决以上的两个核心问题:
master和slave角色的无缝切换,让业务无感知从而不影响业务使用可横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。Redis 集群实现方式:
客户端分片:由应用决定将不同的KEY发送到不同的Redis服务器代理分片:由代理决定将不同的KEY发送到不同的Redis服务器,代理程序如:codis,twemproxy等Redis Cluster:着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
哨兵 (Sentinel) 工作原理Redis Sentinal:着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Sentinel 故障转移 :
(1)多个sentinel发现并确认master有问题(2)选举出一个sentinel作为领导(3)选出一个slave作为master(4)通知其余slave成为新master的slave(5)通知客户端主从变化(6)等待老的master复活成为新master的slave
Sentinel 进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,此功能在redis2.6+的版本已引用,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本
哨兵(Sentinel) 是一个分布式系统,可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossip protocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master
每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(此项可配置)内未得到回应,则暂时认为对方已离线,也就是所谓的”主观认为宕机” (主观:是每个成员都具有的独自的而且可能相同也可能不同的意识),英文名称:Subjective Down,简称SDOWN
有主观宕机,对应的有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出SDOWN的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”(客观:是不依赖于某种意识而已经实际存在的一切事物),英文名称是:Objectively Down, 简称 ODOWN
通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)
Sentinel 机制可以解决master和slave角色的自动切换问题,但单个 Master 的性能瓶颈问题无法解决,类似于MySQL中的MHA功能
Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,但Sentinel只是配置中心不是代理。
Redis Sentinel 节点与普通redis 没有区别,要实现读写分离依赖于客户端程序
redis 3.0 之前版本中,生产环境一般使用哨兵模式,3.0后推出redis cluster功能,可以支持更大规模的生产环境
sentinel中的三个定时任务:
每10秒每个sentinel对master和slave执行info
发现slave节点
确认主从关系
每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
通过sentinel__:hello频道交互
交互对节点的“看法”和自身信息
每1秒每个sentinel对其他sentinel和redis执行ping
实现redis哨兵
由于主从架构无法实现master和slave角色的自动切换,所以在发送master节点宕机时,redis主从复制无法实现自动的故障转移,即将slave 自动提升为新的master。因此,需要配置哨兵来"盯"着它们干活,一旦发现master节点宕机,会快速的将slave节点提升为新master节点。
关闭防火墙 systemctl disable --now firewalld
系统版本 CentOS 7.9
master服务器 10.0.0.131(主机名:centos7-01)
salve服务器1 10.0.0.132(主机名:centos7-02)
salve服务器2 10.0.0.133(主机名:centos7-03)
哨兵的准备实现主从复制架构
#需要安装wget包 [root@centos7-01 ~]# yum -y install wget #在所有节点都脚本编译安装redis 6.2.4 [root@centos7-01 ~]# ls install_redis.sh [root@centos7-01 ~]# cat install_redis.sh #!/bin/bash VERSION=redis-6.2.4 PASSWORD=123456 INSTALL_DIR=/apps/redis color () { RES_COL=60 MOVE_TO_COL="echo -en \\033[${RES_COL}G" SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_WARNING="echo -en \\033[1;33m" SETCOLOR_NORMAL="echo -en \E[0m" echo -n "$1" && $MOVE_TO_COL echo -n "[" if [ $2 = "success" -o $2 = "0" ] ;then ${SETCOLOR_SUCCESS} echo -n $" OK " elif [ $2 = "failure" -o $2 = "1" ] ;then ${SETCOLOR_FAILURE} echo -n $"FAILED" else ${SETCOLOR_WARNING} echo -n $"WARNING" fi ${SETCOLOR_NORMAL} echo -n "]" echo } install() { yum -y install gcc jemalloc-devel || { color "安装软件包失败,请检查网络配置" 1 ; exit; } wget http://download.redis.io/releases/${VERSION}.tar.gz || { color "Redis 源码下载失败" 1 ; exit; } tar xf ${VERSION}.tar.gz cd ${VERSION} make -j 4 PREFIX=${INSTALL_DIR} install && color "Redis 编译安装完成" 0 || { color "Redis 编译安装失败" 1 ;exit ; } ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/ mkdir -p ${INSTALL_DIR}/{etc,log,data,run} cp redis.conf ${INSTALL_DIR}/etc/ sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e "/# requirepass/a requirepass $PASSWORD" -e "/^dir .*/c dir ${INSTALL_DIR}/data/" -e "/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6379.log" -e "/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis_6379.pid" ${INSTALL_DIR}/etc/redis.conf if id redis &> /dev/null ;then color "Redis 用户已存在" 1 else useradd -r -s /sbin/nologin redis color "Redis 用户创建成功" 0 fi chown -R redis.redis ${INSTALL_DIR} cat >> /etc/sysctl.conf <<EOF net.core.somaxconn = 1024 vm.overcommit_memory = 1 EOF sysctl -p echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local /etc/rc.d/rc.local cat > /usr/lib/systemd/system/redis.service <<EOF [Unit] Description=Redis persistent key-value database After=network.target [Service] ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf --supervised systemd ExecStop=/bin/kill -s QUIT \$MAINPID #Type=notify User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now redis &> /dev/null && color "Redis 服务启动成功,Redis信息如下:" 0 || { color "Redis 启动失败" 1 ;exit; } sleep 2 redis-cli -a $PASSWORD INFO Server 2> /dev/null } install #运行脚本开始安装redis [root@centos7-01 ~]# bash install_redis.sh #安装完成查看端口是否启动 [root@centos7-01 ~]# ss -ntl State Recv-Q Send-Q Peer Address:Port Local Address:Port LISTEN 0 511 *:6379 *:* ...省略... #修改主节点配置文件如下: [root@centos7-01 ~]# vim /apps/redis/etc/redis.conf masterauth 123456 requirepass 123456 #修改两个从节点配置文件如下: [root@centos7-01 ~]# vim /apps/redis/etc/redis.conf replicaof 10.0.0.131 6379 masterauth 123456 #重启redis [root@centos7-01 ~]# systemctl restart redis #在master节点查看查看主从复制状态如下内容: [root@centos7-01 ~]# redis-cli -a 123456 info replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:2 slave0:ip=10.0.0.133,port=6379,state=online,offset=0,lag=1 slave1:ip=10.0.0.132,port=6379,state=online,offset=0,lag=1 master_failover_state:no-failover master_replid:5ecf0dd2e3af50946750a2f892bc84b1a4d57d0f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:0 #查看salve服务器1从节点状态 [root@centos7-02 ~]# redis-cli -a 123456 info replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.131 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:504 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:5ecf0dd2e3af50946750a2f892bc84b1a4d57d0f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:504 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:504 #查看salve服务器2从节点状态 [root@centos7-03 ~]# redis-cli -a 123456 info replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.131 master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:560 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:5ecf0dd2e3af50946750a2f892bc84b1a4d57d0f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:560 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:560
编辑哨兵的配置文件
Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持。默认监听在26379/tcp端口
哨兵可以不和Redis服务器部署在一起,但一般部署在一起以节约成本
所有redis节点使用相同的以下示例的配置文件
#在master服务器源码目录有sentinel.conf,复制到安装目录即可,如:/apps/redis/etc/sentinel.conf [root@centos7-01 ~]# cd redis-6.2.4 [root@centos7-01 redis-6.2.4]# ls 00-RELEASENOTES CONDUCT COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src TLS.md BUGS CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests utils #拷贝sentinel到目录 [root@centos7-01 redis-6.2.4]# cp sentinel.conf /apps/redis/etc/ #编辑sentinel文件 [root@centos7-01 redis-6.2.4]# vim /apps/redis/etc/sentinel.conf bind 0.0.0.0 port 26379 daemonize yes pidfile /apps/redis/run/redis-sentinel.pid logfile /apps/redis/log/sentinel_26379.log dir /tmp sentinel monitor mymaster 10.0.0.131 6379 2 #mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口 #2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有sentinel节点(一般总数是>=3的奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,取整为2,是master的ODOWN客观下线的依据 sentinel auth-pass mymaster 123456 #mymaster集群中master的密码,注意此行要在上面行的下面 sentinel down-after-milliseconds mymaster 3000 #(SDOWN)判断mymaster集群中所有节点的主观下线的时间,单位:毫秒,建议3000 sentinel parallel-syncs mymaster 1 #发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力 sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超时时间,单位:毫秒 sentinel deny-scripts-reconfig yes #禁止修改脚本 #将配置文件拷贝到两台从节点上 [root@centos7-01 redis-6.2.4]# scp /apps/redis/etc/sentinel.conf 10.0.0.132:/apps/redis/etc/ [root@centos7-01 redis-6.2.4]# scp /apps/redis/etc/sentinel.conf 10.0.0.133:/apps/redis/etc/ #三个哨兵服务器的配置都如下 [root@centos7-01 redis-6.2.4]# grep -vE "^#|^$" /apps/redis/etc/sentinel.conf bind 0.0.0.0 port 26379 daemonize yes pidfile /apps/redis/run/redis-sentinel.pid logfile "/apps/redis/log/sentinel_26379.log" dir /tmp sentinel monitor mymaster 10.0.0.131 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 3000 acllog-max-len 128 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes SENTINEL resolve-hostnames no SENTINEL announce-hostnames no #三台哨兵服务器都要启动 [root@centos7-01 redis-6.2.4]# vim /lib/systemd/system/redis-sentinel.service [Unit] Description=Redis Sentinel After=network.target [Service] ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd ExecStop=/bin/kill -s QUIT $MAINPID User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target #拷贝redis-sentinel.service到从服务器 [root@centos7-01 redis-6.2.4]# scp /lib/systemd/system/redis-sentinel.service 10.0.0.132:/lib/systemd/system/redis-sentinel.service [root@centos7-01 redis-6.2.4]# scp /lib/systemd/system/redis-sentinel.service 10.0.0.133:/lib/systemd/system/redis-sentinel.service #注意所有节点的目录权限,否则无法启动服务 [root@centos7-01 redis-6.2.4]# chown -R redis.redis /apps/redis/ [root@centos7-01 redis-6.2.4]# ll /apps/redis/etc/sentinel.conf -rw-r--r-- 1 redis redis 13858 Jul 3 10:35 /apps/redis/etc/sentinel.conf [root@centos7-02 redis-6.2.4]# chown -R redis.redis /apps/redis/ [root@centos7-02 redis-6.2.4]# ll /apps/redis/etc/sentinel.conf -rw-r--r-- 1 redis redis 13858 Jul 3 10:35 /apps/redis/etc/sentinel.conf [root@centos7-03 redis-6.2.4]# chown -R redis.redis /apps/redis/ [root@centos7-03 redis-6.2.4]# ll /apps/redis/etc/sentinel.conf -rw-r--r-- 1 redis redis 13858 Jul 3 10:35 /apps/redis/etc/sentinel.conf #所有节点重新加载配置文件 [root@centos7-01 ~]# systemctl daemon-reload [root@centos7-02 ~]# systemctl daemon-reload [root@centos7-03 ~]# systemctl daemon-reload #如果是编译安装,在所有哨兵服务器执行下面操作启动哨兵 [root@centos7-01 redis-6.2.4]# /apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf #所有节点都可以看到26379端口 [root@centos7-01 redis-6.2.4]# ss -ntl State Recv-Q Send-Q Peer Address:Port Local Address:Port LISTEN 0 511 *:* *:26379 #查看哨兵日志 [root@centos7-01 redis-6.2.4]# tail -f /apps/redis/log/sentinel_26379.log 7043:X 03 Jul 2022 10:46:05.337 # Configuration loaded 7043:X 03 Jul 2022 10:46:05.338 * Increased maximum number of open files to 10032 (it was originally set to 1024). 7043:X 03 Jul 2022 10:46:05.338 * monotonic clock: POSIX clock_gettime 7043:X 03 Jul 2022 10:46:05.339 * Running mode=sentinel, port=26379. 7043:X 03 Jul 2022 10:46:05.341 # Sentinel ID is 083f0611260042946e0766c35d1f7dbe7f991748 7043:X 03 Jul 2022 10:46:05.341 # +monitor master mymaster 10.0.0.131 6379 quorum 2 7043:X 03 Jul 2022 10:46:05.342 * +slave slave 10.0.0.133:6379 10.0.0.133 6379 @ mymaster 10.0.0.131 6379 7043:X 03 Jul 2022 10:46:05.344 * +slave slave 10.0.0.132:6379 10.0.0.132 6379 @ mymaster 10.0.0.131 6379 7043:X 03 Jul 2022 10:46:05.748 * +sentinel sentinel a99bf07a5f70522f095c742349f0bbed84516e51 10.0.0.132 26379 @ mymaster 10.0.0.131 6379 7043:X 03 Jul 2022 10:46:06.689 * +sentinel sentinel fa168d6a97026eb2216771164a3e8d5362298d7d 10.0.0.133 26379 @ mymaster 10.0.0.131 6379 slave的哨兵日志 [root@centos7-02 ~]# tail -f /apps/redis/log/sentinel_26379.log 5916:X 03 Jul 2022 10:46:01.632 # Configuration loaded 5916:X 03 Jul 2022 10:46:01.633 * Increased maximum number of open files to 10032 (it was originally set to 1024). 5916:X 03 Jul 2022 10:46:01.633 * monotonic clock: POSIX clock_gettime 5916:X 03 Jul 2022 10:46:01.634 * Running mode=sentinel, port=26379. 5916:X 03 Jul 2022 10:46:01.638 # Sentinel ID is a99bf07a5f70522f095c742349f0bbed84516e51 5916:X 03 Jul 2022 10:46:01.638 # +monitor master mymaster 10.0.0.131 6379 quorum 2 5916:X 03 Jul 2022 10:46:01.640 * +slave slave 10.0.0.133:6379 10.0.0.133 6379 @ mymaster 10.0.0.131 6379 5916:X 03 Jul 2022 10:46:01.641 * +slave slave 10.0.0.132:6379 10.0.0.132 6379 @ mymaster 10.0.0.131 6379 5916:X 03 Jul 2022 10:46:02.515 * +sentinel sentinel fa168d6a97026eb2216771164a3e8d5362298d7d 10.0.0.133 26379 @ mymaster 10.0.0.131 6379 5916:X 03 Jul 2022 10:46:07.261 * +sentinel sentinel 083f0611260042946e0766c35d1f7dbe7f991748 10.0.0.131 26379 @ mymaster 10.0.0.131 6379 #查看sentinel状态,在sentinel状态中尤其是最后一行,涉及到master IP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量 [root@centos7-01 redis-6.2.4]# redis-cli -p 26379 INFO sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=10.0.0.131:6379,slaves=2,sentinels=3 #测试数据同步,主节点写入数据 [root@centos7-01 redis-6.2.4]# redis-cli 127.0.0.1:6379> AUTH 123456 OK 127.0.0.1:6379> set date 20220703 OK #从节点查看数据 [root@centos7-02 ~]# redis-cli 127.0.0.1:6379> AUTH 123456 OK 127.0.0.1:6379> get date "20220703" [root@centos7-03 ~]# redis-cli 127.0.0.1:6379> AUTH 123456 OK 127.0.0.1:6379> get date "20220703" #停止主节点测试故障转移 [root@centos7-01 redis-6.2.4]# systemctl stop redis.service #查看从节点上哨兵信息,发现已经转移到了10.0.0.132: [root@centos7-02 ~]# redis-cli -p 26379 INFO sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=10.0.0.132:6379,slaves=2,sentinels=3 #故障转移时sentinel的信息: [root@centos7-02 ~]# tail -f /apps/redis/log/sentinel_26379.log 5916:X 03 Jul 2022 10:54:54.423 # +sdown master mymaster 10.0.0.131 6379 5916:X 03 Jul 2022 10:54:54.524 # +new-epoch 1 5916:X 03 Jul 2022 10:54:54.525 # +vote-for-leader 083f0611260042946e0766c35d1f7dbe7f991748 1 5916:X 03 Jul 2022 10:54:55.552 # +odown master mymaster 10.0.0.131 6379 #quorum 3/2 5916:X 03 Jul 2022 10:54:55.553 # Next failover delay: I will not start a failover before Sun Jul 3 11:00:55 2022 5916:X 03 Jul 2022 10:54:55.685 # +config-update-from sentinel 083f0611260042946e0766c35d1f7dbe7f991748 10.0.0.131 26379 @ mymaster 10.0.0.131 6379 5916:X 03 Jul 2022 10:54:55.685 # +switch-master mymaster 10.0.0.131 6379 10.0.0.132 6379 5916:X 03 Jul 2022 10:54:55.686 * +slave slave 10.0.0.133:6379 10.0.0.133 6379 @ mymaster 10.0.0.132 6379 5916:X 03 Jul 2022 10:54:55.686 * +slave slave 10.0.0.131:6379 10.0.0.131 6379 @ mymaster 10.0.0.132 6379 5916:X 03 Jul 2022 10:54:58.730 # +sdown slave 10.0.0.131:6379 10.0.0.131 6379 @ mymaster 10.0.0.132 6379 #故障转移后哨兵配置文件的sentinel monitor IP 会被修改 [root@centos7-02]# grep "monitor mymaster" /apps/redis/etc/sentinel.conf sentinel monitor mymaster 10.0.0.132 6379 2 #自动修改此行 [root@centos7-03]# grep "monitor mymaster" /apps/redis/etc/sentinel.conf sentinel monitor mymaster 10.0.0.132 6379 2 [root@centos7-01]# grep "monitor mymaster" /apps/redis/etc/sentinel.conf sentinel monitor mymaster 10.0.0.132 6379 2 #查看当前 redis状态 #新的master 状态 [root@centos7-02 ~]# redis-cli -a 123456 info replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:2 slave0:ip=10.0.0.133,port=6379,state=online,offset=286899,lag=0 slave1:ip=10.0.0.131,port=6379,state=online,offset=286764,lag=1 master_failover_state:no-failover master_replid:43391e35ece748aa653500c971b8dca36d388161 master_replid2:5ecf0dd2e3af50946750a2f892bc84b1a4d57d0f master_repl_offset:286899 second_repl_offset:108246 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:286899 #恢复故障的原master重新加入redis集群 #启动redis [root@centos7-01 redis-6.2.4]# systemctl start redis.service #查看状态,目前role:slave,主节点指向了10.0.0.132 [root@centos7-01 redis-6.2.4]# redis-cli -a 123456 info replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.132 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:274800 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:43391e35ece748aa653500c971b8dca36d388161 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:274800 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:231554 repl_backlog_histlen:43247 [root@centos7-01 redis-6.2.4]# redis-cli -p 26379 INFO sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=10.0.0.132:6379,slaves=2,sentinels=3
在哨兵sentinel机制中,可以解决redis高可用问题,即当master故障后可以自动将slave提升为master,从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素。
早期Redis 分布式集群部署方案:
客户端分区:由客户端程序决定key写分配和写入的redis node,但是需要客户端自己处理写入分配、高可用管理和故障转移等
代理方案:基于三方软件实现redis proxy,客户端先连接之代理层,由代理层实现key的写入分配,对客户端来说是有比较简单,但是对于集群管节点增减相对比较麻烦,而且代理本身也是单点和性能瓶颈。
redis 3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群当中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接
Redis Cluster特点如下:
所有Redis节点使用(PING机制)互联
集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效
客户端不需要proxy即可直接连接redis,应用程序中需要配置有全部的redis服务器IP
redis cluster把所有的redis node 平均映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作,因此有多少个redis node相当于redis 并发扩展了多少倍,每个redis node 承担16384/N个槽位
Redis cluster预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。
关闭防火墙 systemctl disable --now firewalld
系统版本 CentOS 7.9
redis服务器1 10.0.0.131(主机名:node1)
redis服务器2 10.0.0.132(主机名:node2)
redis服务器3 10.0.0.133(主机名:node3)
redis服务器4 10.0.0.134(主机名:node4)
redis服务器5 10.0.0.135(主机名:node5)
redis服务器6 10.0.0.136(主机名:node6)
部署redis
#安装需要wget包 [root@node1 ~]# yum -y install wget #在所有节点都脚本编译安装redis-5.0.3 [root@node1 ~]# ls install_redis.sh [root@node1 ~]# cat install_redis.sh #!/bin/bash VERSION=redis-5.0.3 PASSWORD=123456 INSTALL_DIR=/apps/redis color () { RES_COL=60 MOVE_TO_COL="echo -en \\033[${RES_COL}G" SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_WARNING="echo -en \\033[1;33m" SETCOLOR_NORMAL="echo -en \E[0m" echo -n "$1" && $MOVE_TO_COL echo -n "[" if [ $2 = "success" -o $2 = "0" ] ;then ${SETCOLOR_SUCCESS} echo -n $" OK " elif [ $2 = "failure" -o $2 = "1" ] ;then ${SETCOLOR_FAILURE} echo -n $"FAILED" else ${SETCOLOR_WARNING} echo -n $"WARNING" fi ${SETCOLOR_NORMAL} echo -n "]" echo } install() { yum -y install gcc jemalloc-devel || { color "安装软件包失败,请检查网络配置" 1 ; exit; } wget http://download.redis.io/releases/${VERSION}.tar.gz || { color "Redis 源码下载失败" 1 ; exit; } tar xf ${VERSION}.tar.gz cd ${VERSION} make -j 4 PREFIX=${INSTALL_DIR} install && color "Redis 编译安装完成" 0 || { color "Redis 编译安装失败" 1 ;exit ; } ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/ mkdir -p ${INSTALL_DIR}/{etc,log,data,run} cp redis.conf ${INSTALL_DIR}/etc/ sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e "/# requirepass/a requirepass $PASSWORD" -e "/^dir .*/c dir ${INSTALL_DIR}/data/" -e "/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6379.log" -e "/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis_6379.pid" ${INSTALL_DIR}/etc/redis.conf if id redis &> /dev/null ;then color "Redis 用户已存在" 1 else useradd -r -s /sbin/nologin redis color "Redis 用户创建成功" 0 fi chown -R redis.redis ${INSTALL_DIR} cat >> /etc/sysctl.conf <<EOF net.core.somaxconn = 1024 vm.overcommit_memory = 1 EOF sysctl -p echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local /etc/rc.d/rc.local cat > /usr/lib/systemd/system/redis.service <<EOF [Unit] Description=Redis persistent key-value database After=network.target [Service] ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf --supervised systemd ExecStop=/bin/kill -s QUIT \$MAINPID #Type=notify User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now redis &> /dev/null && color "Redis 服务启动成功,Redis信息如下:" 0 || { color "Redis 启动失败" 1 ;exit; } sleep 2 redis-cli -a $PASSWORD INFO Server 2> /dev/null } install #运行脚本开始安装redis [root@node1 ~]# bash install_redis.sh #安装完成查看端口是否启动 [root@node1 ~]# ss -ntl State Recv-Q Send-Q Peer Address:Port Local Address:Port LISTEN 0 511 *:6379 *:* ...省略...
配置redis cluster
[root@node1 ~]# redis-server --version Redis server v=5.0.3 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=5fc1b390c8531b09 #每个节点修改redis配置,必须开启cluster功能的参数 #执行下面命令,批量修改 [root@node1 ~]# sed -i.bak -e '/masterauth/a masterauth 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/ccluster-require-full-coverage no' /apps/redis/etc/redis.conf #重新加载配置文件 [root@node1 ~]# systemctl daemon-reload #重启redis服务 [root@node1 ~]# systemctl restart redis.service [root@node1 ~]# ss -ntl State Recv-Q Send-Q Peer Address:Port Local Address:Port LISTEN 0 511 *:* *:16379 #注意进程有[cluster]状态 [root@node1 ~]# ps aux|grep redis redis 5850 0.2 0.1 153980 3 Ssl 20:17 0:00 /apps/redis/bin/redis-server 0.0.0.0:6379 [cluster] root 5858 0.0 0.0 112808 968 pts/0 S+ 20:19 0:00 grep --color=auto redis
创建集群
#命令redis-cli的选项 --cluster-replicas 1 表示每个master对应一个slave节点 [root@node1 ~]# redis-cli -a 123456 --cluster create 10.0.0.131:6379 10.0.0.132:6379 10.0.0.133:6379 10.0.0.134:6379 10.0.0.135:6379 10.0.0.136:6379 --cluster-replicas 1 Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. >>> 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.134:6379 to 10.0.0.131:6379 Adding replica 10.0.0.135:6379 to 10.0.0.132:6379 Adding replica 10.0.0.136:6379 to 10.0.0.133:6379 M: 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379 #带M的为master slots:[0-5460] (5461 slots) master #当前master的槽位起始和结束位 M: 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379 slots:[5461-10922] (5462 slots) master M: 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379 slots:[10923-16383] (5461 slots) master S: 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379 #带S的slave replicates 13466080cae98b5e86eb6a1a3444c96d4e3110ec S: 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379 replicates 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 S: b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379 replicates 001cee9baf30a2d16f210789e0032fd2d0c595b7 Can I set the above configuration? (type 'yes' to accept): yes #输入yes自动创建集群 >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ........ >>> Performing Cluster Check (using node 10.0.0.131:6379) M: 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379 slots:[10923-16383] (5461 slots) master #已经分配的槽位 1 additional replica(s) #分配了一个slave S: 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379 slots: (0 slots) slave #slave没有分配槽位 replicates 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 #对应的master的10.0.0.132的ID S: b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379 slots: (0 slots) slave replicates 001cee9baf30a2d16f210789e0032fd2d0c595b7 #对应的master的10.0.0.133的ID M: 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379 slots: (0 slots) slave replicates 13466080cae98b5e86eb6a1a3444c96d4e3110ec #对应的master的10.0.0.131的ID [OK] All nodes agree about slots configuration. #所有节点槽位分配完成 >>> Check for open slots... #检查打开的槽位 >>> Check slots coverage... #检查插槽覆盖范围 [OK] All 16384 slots covered. #所有槽位(16384个)分配完成 #观察以上结果,可以看到3组master/slave #master:10.0.0.131---slave:10.0.0.134 #master:10.0.0.132---slave:10.0.0.135 #master:10.0.0.133---slave:10.0.0.136
查看六台服务器的主从状态
[root@node1 ~]# redis-cli -a 123456 -c INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:1 slave0:ip=10.0.0.134,port=6379,state=online,offset=588,lag=1 master_replid:466d2c27ec444c6029568fc5c2061b0c42624b63 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:588 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:588 [root@node2 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:1 slave0:ip=10.0.0.135,port=6379,state=online,offset=672,lag=0 master_replid:cd2d0407eb96492af69adcfee231ee1b4c3d6136 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:672 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:672 [root@node3 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:1 slave0:ip=10.0.0.136,port=6379,state=online,offset=700,lag=1 master_replid:bae53e2d5fa70c1c6f3e9c209cb1a1470f180996 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:700 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:700 [root@node4 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.131 master_port:6379 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:756 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:466d2c27ec444c6029568fc5c2061b0c42624b63 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:756 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:756 [root@node5 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.132 master_port:6379 master_link_status:up master_last_io_seconds_ago:9 master_sync_in_progress:0 slave_repl_offset:784 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:cd2d0407eb96492af69adcfee231ee1b4c3d6136 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:784 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:784 [root@node6 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.133 master_port:6379 master_link_status:up master_last_io_seconds_ago:5 master_sync_in_progress:0 slave_repl_offset:812 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:bae53e2d5fa70c1c6f3e9c209cb1a1470f180996 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:812 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:812
#查看集群node对应关系
[root@node6 ~]# redis-cli -a 123456 cluster nodes Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656880556608 5 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 slave 13466080cae98b5e86eb6a1a3444c96d4e3110ec 0 1656880557622 4 connected b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 myself,slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656880555000 6 connected 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656880556000 3 connected 10923-16383 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656880557000 2 connected 5461-10922 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 master - 0 1656880556000 1 connected 0-5460
验证集群状态
[root@node6 ~]# redis-cli -a 123456 CLUSTER INFO Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 #6个节点 cluster_size:3 #3个集群 cluster_current_epoch:6 cluster_my_epoch:3 cluster_stats_messages_ping_sent:672 cluster_stats_messages_pong_sent:646 cluster_stats_messages_meet_sent:5 cluster_stats_messages_sent:1323 cluster_stats_messages_ping_received:646 cluster_stats_messages_pong_received:677 cluster_stats_messages_received:1323 #查看任意节点的集群状态 [root@node5 ~]# redis-cli -a 123456 --cluster info 10.0.0.135:6379 Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 10.0.0.133:6379 (001cee9b...) -> 0 keys | 5461 slots | 1 slaves. 10.0.0.132:6379 (0bed8d39...) -> 0 keys | 5462 slots | 1 slaves. 10.0.0.131:6379 (13466080...) -> 0 keys | 5461 slots | 1 slaves. [OK] 0 keys in 3 masters. 0.00 keys per slot on average. #查看集群状态文件 [root@node5 ~]# cat /apps/redis/data/nodes-6379.conf 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 myself,slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656879927000 5 connected 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656879924000 3 connected 10923-16383 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656879927000 2 connected 5461-10922 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 master - 0 1656879928000 1 connected 0-5460 b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656879928768 6 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 slave 13466080cae98b5e86eb6a1a3444c96d4e3110ec 0 1656879925000 4 connected vars currentEpoch 6 lastVoteEpoch 0
模拟master故障,对应的slave节点自动提升为新master
[root@node1 ~]# redis-cli -a 123456 -c INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:1 slave0:ip=10.0.0.134,port=6379,state=online,offset=1120,lag=0 master_replid:466d2c27ec444c6029568fc5c2061b0c42624b63 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1120 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1120 #模拟node1节点出故障,需要相应的数秒故障转移时间 [root@node1 ~]# redis-cli -a 123456 shutdown [root@node1 ~]# tail -f /apps/redis/log/redis-6379.log 5850:M 03 Jul 2022 20:25:27.576 * Background saving started by pid 5863 5863:C 03 Jul 2022 20:25:27.579 * DB saved on disk 5863:C 03 Jul 2022 20:25:27.580 * RDB: 0 MB of memory used by copy-on-write 5850:M 03 Jul 2022 20:25:27.612 * Background saving terminated with success 5850:M 03 Jul 2022 20:25:27.613 * Synchronization with replica 10.0.0.134:6379 succeeded 5850:M 03 Jul 2022 20:39:45.801 # User requested shutdown... 5850:M 03 Jul 2022 20:39:45.801 * Saving the final RDB snapshot before exiting. 5850:M 03 Jul 2022 20:39:45.801 * DB saved on disk 5850:M 03 Jul 2022 20:39:45.801 * Removing the pid file. 5850:M 03 Jul 2022 20:39:45.802 # Redis is now ready to exit, bye bye... #查看集群node对应关系 [root@node4 ~]# redis-cli -a 123456 cluster nodes Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656880839163 3 connected 10923-16383 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656880838135 5 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 myself,master - 0 1656880839000 7 connected 0-5460 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 master,fail - 1656880785519 1656880783000 1 disconnected 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656880838000 2 connected 5461-10922 b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656880840185 6 connected #10.0.0.134自动提升为新的master [root@node4 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:master connected_slaves:0 master_replid:40dc16bb51ac8230e511b1edfaa7e572ef54823e master_replid2:466d2c27ec444c6029568fc5c2061b0c42624b63 master_repl_offset:1176 second_repl_offset:1177 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1176 [root@node4 ~]# tail -f /apps/redis/log/redis-6379.log 6575:S 03 Jul 2022 20:40:00.965 * FAIL message received from 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 about 13466080cae98b5e86eb6a1a3444c96d4e3110ec 6575:S 03 Jul 2022 20:40:00.987 # Start of election delayed for 538 milliseconds (rank #0, offset 1176). 6575:S 03 Jul 2022 20:40:01.292 * Connecting to MASTER 10.0.0.131:6379 6575:S 03 Jul 2022 20:40:01.293 * MASTER <-> REPLICA sync started 6575:S 03 Jul 2022 20:40:01.293 # Error condition on socket for SYNC: Connection refused 6575:S 03 Jul 2022 20:40:01.600 # Starting a failover election for epoch 7. 6575:S 03 Jul 2022 20:40:01.607 # Failover election won: I'm the new master. 6575:S 03 Jul 2022 20:40:01.607 # configEpoch set to 7 after successful failover 6575:M 03 Jul 2022 20:40:01.607 # Setting secondary replication ID to 466d2c27ec444c6029568fc5c2061b0c42624b63, valid up to offset: 1177. New replication ID is 40dc16bb51ac8230e511b1edfaa7e572ef54823e 6575:M 03 Jul 2022 20:40:01.608 * Discarding previously cached master state. #查看集群状态文件10.0.0.131:6379@16379 master,fail [root@node4 ~]# cat /apps/redis/data/nodes-6379.conf 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656880801193 3 connected 10923-16383 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656880800000 5 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 myself,master - 0 1656880799000 7 connected 0-5460 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 master,fail - 1656880785519 1656880783000 1 disconnected 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656880800178 2 connected 5461-10922 b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656880799000 6 connected vars currentEpoch 7 lastVoteEpoch 0
恢复故障节点node1可以自动成为slave节点
[root@node1 ~]# systemctl start redis #查看集群状态文件,可以查看node1自动成为slave节点,10.0.0.131:6379@16379 myself,slave [root@node1 ~]# cat /apps/redis/data/nodes-6379.conf 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656881054170 3 connected 10923-16383 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656881054170 2 connected 5461-10922 b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656881054170 6 connected 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 myself,slave 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 0 1656881054166 1 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 master - 0 1656881054171 7 connected 0-5460 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656881054171 5 connected vars currentEpoch 7 lastVoteEpoch 0 #自动变为10.0.0.134的slave [root@node1 ~]# redis-cli -a 123456 INFO replication Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Replication role:slave master_host:10.0.0.134 master_port:6379 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:1260 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:40dc16bb51ac8230e511b1edfaa7e572ef54823e master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1260 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1177 repl_backlog_histlen:84 #查看集群node对应关系 [root@node1 ~]# redis-cli -a 123456 cluster nodes Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 001cee9baf30a2d16f210789e0032fd2d0c595b7 10.0.0.133:6379@16379 master - 0 1656881195000 3 connected 10923-16383 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 10.0.0.132:6379@16379 master - 0 1656881196832 2 connected 5461-10922 b6e1bbd3c09a73bdb756e4b066d8215af2a0763a 10.0.0.136:6379@16379 slave 001cee9baf30a2d16f210789e0032fd2d0c595b7 0 1656881197848 6 connected 13466080cae98b5e86eb6a1a3444c96d4e3110ec 10.0.0.131:6379@16379 myself,slave 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 0 1656881195000 1 connected 1e934bf301f2ffc08e6fbbdbcc7caab3b1040e8f 10.0.0.134:6379@16379 master - 0 1656881195816 7 connected 0-5460 4fa633be7f5dce581040067b31af15a735144940 10.0.0.135:6379@16379 slave 0bed8d397b9288b0f78dfbbd1abd93e99dddc709 0 1656881197000 5 connected
关闭防火墙 systemctl disable --now firewalld
系统版本 CentOS 7.9
Zabbix服务器 10.0.0.131(主机名:node1)
数据库服务器 10.0.0.132(主机名:node2)
数据库服务器安装MariaDB 10.5.16
#yum源配置 [root@node2 ~]# vim /etc/yum.repos.d/mariadb.repo [mariadb] name = MariaDB baseurl = https://mirrors.nju.edu.cn/mariadb/yum/10.5/centos7-amd64 gpgkey=https://mirrors.nju.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB gpgcheck=1 #安装mysql数据库 yum -y install mariadb-server #启动数据库 [root@node2 ~]# systemctl start mysqld #创建初始数据库 [root@node2 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 5 Server version: 10.5.16-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database zabbix character set utf8 collate utf8_bin; Query OK, 1 row affected (0.000 sec) MariaDB [(none)]> create user zabbix@'10.0.0.%' identified by 'zabbix'; Query OK, 0 rows affected (0.001 sec) MariaDB [(none)]> grant all privileges on zabbix.* to zabbix@'10.0.0.%'; Query OK, 0 rows affected (0.001 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.000 sec) MariaDB [(none)]> quit Bye #重启数据库 [root@node2 ~]# systemctl restart mysqld.service
安装zabbix
[root@node1 ~]# rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm [root@node1 ~]# rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm Retrieving https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm warning: /var/tmp/rpm-tmp.lBeUuA: Header V4 RSA/SHA512 Signature, key ID a14fe591: NOKEY Preparing... ################################# [100%] Updating / installing... 1:zabbix-release-5.0-1.el7 ################################# [100%] [root@node1 ~]# sed -i 's#http://repo.zabbix.com#https://mirrors.aliyun.com/zabbix#' /etc/yum.repos.d/zabbix.repo [root@node1 ~]# yum clean all Loaded plugins: fastestmirror Repository epel is listed more than once in the configuration Cleaning repos: BaseOS epel zabbix zabbix-non-supported Cleaning up list of fastest mirrors Other repos take up 135 M of disk space (use --verbose for details) #安装zabbix server和agent [root@node1 ~]# yum install -y zabbix-server-mysql zabbix-agent #安装Zabbix前端 [root@node1 ~]# yum install -y centos-release-scl #如果报错No package centos-release-scl available,执行以下可解决,再重新安装centos-release-scl [root@node1 ~]# rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl-rh/2/3.el7.centos/noarch/centos-release-scl-rh-2-3.el7.centos.noarch.rpm [root@node1 ~]# rpm -ivh https://cbs.centos.org/kojifiles/packages/centos-release-scl/2/3.el7.centos/noarch/centos-release-scl-2-3.el7.centos.noarch.rpm #编辑配置文件 /etc/yum.repos.d/zabbix.repo [root@node1 ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix-frontend] enabled=1 #安装Zabbix前端软件包 [root@node1 ~]# yum install -y zabbix-web-mysql-scl zabbix-apache-conf-scl #导入初始架构和数据 [root@node1 ~]# ll /usr/share/doc/zabbix-server-mysql*/create.sql.gz -rw-r--r-- 1 root root 2034736 Jun 27 08:14 /usr/share/doc/zabbix-server-mysql-5.0.25/create.sql.gz [root@node1 ~]# zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -pzabbix -h 10.0.0.132 zabbix #如果报错ERROR 1045 (28000): Access denied for user 'zabbix'@'node1' (using password: YES),需要在数据库服务器执行命令后,再重新执行导入数据 [root@node2 ~]# mysql -uroot -e"delete from user where user=' ';" #删掉空用户 [root@node2 ~]# mysql -uroot -e"flush privileges;" #刷新权限 #在数据库服务器查看是否导入成功 [root@node2 ~]# mysql MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | zabbix | +--------------------+ MariaDB [(none)]> use zabbix; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [zabbix]> show tables; +----------------------------+ | Tables_in_zabbix | +----------------------------+ | acknowledges | | actions | | alerts | | application_discovery | | application_prototype | | application_template | | applications | | auditlog | | auditlog_details | | autoreg_host | | conditions | ....................................... #为Zabbix server配置数据库,需要改动以下内容 [root@node1 ~]# vim /etc/zabbix/zabbix_server.conf ListenPort=10051 DBHost=10.0.0.132 DBName=zabbix DBUser=zabbix DBPassword=zabbix DBPort=3306 #为Zabbix前端配置PHP,更改时区 [root@node1 ~]# vim /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf php_value[date.timezone] = Asia/Shanghai #启动Zabbix server和agent进程,并设置开机自启: [root@node1 ~]# systemctl restart zabbix-server zabbix-agent httpd rh-php72-php-fpm [root@node1 ~]# systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm
配置Zabbix前端
连接到新安装的Zabbix前端:10.0.0.131/zabbix
点击【next step】
确认状态没问题,点击【next step】
配置数据库连接,点击【next step】
输入Zabbix server 详细信息,点击【next step】
确认安装信息,点击【next step】
完成安装【finish】
登录zabbix,用户名为Admin,密码为zabbix
登录成功
配置中文语言
点击左下角【User settings】,选择【Chinese(zh_CH)】,点击【Update】更新
监控图形出现乱码的解决办法
在windows拷贝字体在windows上找到【C:\Windows\Fonts\楷体 常规(simkai.ttf)】(或者其他个人喜欢的中文字体),然后将字体拷贝到windows系统当前用户的桌面。
上传字体上传字体到zabbix_server服务器的/usr/share/zabbix/assets/fonts/目录下。
[root@node1 ~]# cd /usr/share/zabbix/assets/fonts/ [root@node1 fonts]# ll total 11512 lrwxrwxrwx 1 root root 33 Jul 3 22:44 graphfont.ttf -> /etc/alternatives/zabbix-web-font -rw-r--r-- 1 root root 11787328 Jul 3 23:12 simkai.ttf #修改权限 [root@node1 fonts]# chown zabbix.zabbix ./* [root@node1 fonts]# ll total 11512 lrwxrwxrwx 1 root root 33 Jul 3 22:44 graphfont.ttf -> /etc/alternatives/zabbix-web-font -rw-r--r-- 1 zabbix zabbix 11787328 Jul 3 23:12 simkai.ttf #修改配置文件 [root@node1 fonts]# vim /usr/share/zabbix/include/defines.inc.php #第81行,注释掉graphfont,加入simkai #define('ZBX_GRAPH_FONT_NAME', 'graphfont'); // font file name define('ZBX_GRAPH_FONT_NAME', 'simkai'); // font file name #第122行,注释掉graphfont,加入simkai #define('ZBX_FONT_NAME', 'graphfont'); define('ZBX_FONT_NAME', 'simkai');
验证字体是否生效
关闭防火墙 systemctl disable --now firewalld
系统版本 CentOS 7.9
Zabbix服务器 10.0.0.131(主机名:node1)
Nginx服务器 10.0.0.132(主机名:node2)
数据库服务器 10.0.0.133(主机名:node3)
安装nginx-1.18.0
#安装依赖包 [root@node2 ~]# yum -y install gcc pcre-devel openssl-devel zlib-devel #创建账号 [root@node2 ~]# useradd -s /sbin/nologin nginx #下载nginx-1.18,注意需要提前安装wget依赖包 [root@node2 ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gz #解压缩 [root@node2 ~]# ls anaconda-ks.cfg nginx-1.18.0.tar.gz [root@node2 ~]# tar xf nginx-1.18.0.tar.gz [root@node2 ~]# cd nginx-1.18.0/ [root@node2 nginx-1.18.0]# ls auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src #创建文件夹 [root@node2 nginx-1.18.0]# mkdir -p /apps/nginx #编译http的监控模块 [root@node2 nginx-1.18.0]# ./configure --prefix=/apps/nginx --with-http_stub_status_module --without-http_rewrite_module [root@node2 nginx-1.18.0]# make -j 2 #安装 [root@node2 nginx-1.18.0]# make install #修改文件夹权限 [root@node2 nginx-1.18.0]# chown -R nginx.nginx /apps/nginx/ #生成的目录 [root@node2 nginx-1.18.0]# ll /apps/nginx/ total 0 drwxr-xr-x 2 nginx nginx 333 Jun 15 06:24 conf drwxr-xr-x 2 nginx nginx 40 Jun 15 06:24 html drwxr-xr-x 2 nginx nginx 6 Jun 15 06:24 logs drwxr-xr-x 2 nginx nginx 19 Jun 15 06:24 sbin #conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有个样板配置文件,是文件名.default结尾,使用的使用将其复制为并将default去掉即可。 #html:保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。 #logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。 #sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。 #验证版本及编译参数 [root@node2 nginx-1.18.0]# ls /apps/nginx/sbin/ nginx #创建软连接 [root@node2 nginx-1.18.0]# ln -s /apps/nginx/sbin/nginx /usr/sbin/ #查看版本 [root@node2 nginx-1.18.0]# nginx -v nginx version: nginx/1.18.0 #查看编译参数 nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) configure arguments: --prefix=/apps/nginx --with-http_stub_status_module --without-http_rewrite_module #创建service文件 [root@node2 nginx-1.18.0]# vim /usr/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/apps/nginx/run/nginx.pid ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID LimitNOFILE=100000 [Install] WantedBy=multi-user.target ##创建目录存放pid [root@node2 nginx-1.18.0]# mkdir /apps/nginx/run/ [root@node2 nginx-1.18.0]# chown -R nginx.nginx /apps/nginx/run/ #修改配置文件 [root@node2 nginx-1.18.0]# vim /apps/nginx/conf/nginx.conf #配置文件加入pid路径 pid /apps/nginx/run/nginx.pid; #验证 Nginx 自启动文件 [root@node2 nginx-1.18.0]# systemctl daemon-reload [root@node2 nginx-1.18.0]# systemctl enable --now nginx #80端口已启动 [root@node2 nginx-1.18.0]# ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 [::]:80 [::]:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 100 [::1]:25 [::]:* #pid已自动生成 [root@node2 nginx-1.18.0]# ll /apps/nginx/run/ total 4 -rw-r--r-- 1 root root 5 Jun 15 06:38 nginx.pid #客户端测试验证 [root@node2 nginx]# curl -I 127.0.0.1 HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Mon, 04 Jul 2022 02:03:11 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Mon, 04 Jul 2022 01:58:54 GMT Connection: keep-alive ETag: "62c2495e-264" Accept-Ranges: bytes #修改配置文件 [root@node2 nginx]# vim /apps/nginx/conf/nginx.conf ##添加location location /nginx_status { stub_status on; allow 10.0.0.0/16; allow 127.0.0.1; deny all; } #重启服务 [root@node2 nginx]# nginx -s reload #测试状态页 [root@node2 nginx]# curl http://127.0.0.1/nginx_status Active connections: 1 server accepts handled requests 3 3 3 Reading: 0 Writing: 1 Waiting: 0
其中信息的含义:
active connections – 活跃的连接数量
server accepts handled requests — 总共处理了3个连接 , 成功创建3次握手,总共处理了3个请求
reading — 读取客户端的连接数.
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.
Nginx服务器安装zabbix-agent
[root@node2 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm Retrieving https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm warning: /var/tmp/rpm-tmp.YgdI7f: Header V4 RSA/SHA512 Signature, key ID a14fe591: NOKEY Preparing... ################################# [100%] Updating / installing... 1:zabbix-release-5.0-1.el7 ################################# [100%] #修改zabbix的repo文件中的源地址 [root@node2 ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix] name=Zabbix Official Repository - $basearch baseurl=http://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/$basearch/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591 [zabbix-non-supported] name=Zabbix Official Repository non-supported - $basearch baseurl=http://mirrors.aliyun.com/zabbix/non-supported/rhel/7/$basearch/ enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX gpgcheck=1 #安装 zabbix-agent [root@node2 ~]# yum -y install zabbix-agent #配置agent [root@node2 ~]# vim /etc/zabbix/zabbix_agentd.conf Server=10.10.0.131 #指向当前zabbix server ListenPort=10050 #监听端口 ListenIP=0.0.0.0 startAgents=5 #被动状态时默认启动的实例数(进程数),为0不监听任何端口 Hostname=10.0.0.132 #启动agent [root@node2 ~]# systemctl start zabbix-agent # 制作监控脚本 [root@node2 ~]# cd /etc/zabbix/zabbix_agentd.d/ [root@node2 zabbix_agentd.d]# vim nginx_status.sh nginx_status_fun(){ #函数内容 NGINX_PORT=$1 #端口,函数的第一个参数是脚本的第二个参数,即脚本的第二个参数是段端口号 NGINX_COMMAND=$2 #命令,函数的第二个参数是脚本的第三个参数,即脚本的第三个参数是命令 nginx_active(){ #获取nginx_active数量,以下相同,这是开启了nginx状态但是只能从本机看到 /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| grep 'Active' | awk '{print $NF}' } nginx_reading(){ #获取nginx_reading状态的数量 /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| grep 'Reading' | awk '{print $2}' } nginx_writing(){ /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| grep 'Writing' | awk '{print $4}' } nginx_waiting(){ /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| grep 'Waiting' | awk '{print $6}' } nginx_accepts(){ /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| awk NR==3 | awk '{print $1}' } nginx_handled(){ /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| awk NR==3 | awk '{print $2}' } nginx_requests(){ /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/nginx_status/" 2>/dev/null| awk NR==3 | awk '{print $3}' } case $NGINX_COMMAND in active) nginx_active; ;; reading) nginx_reading; ;; writing) nginx_writing; ;; waiting) nginx_waiting; ;; accepts) nginx_accepts; ;; handled) nginx_handled; ;; requests) nginx_requests; esac } main(){ #主函数内容 case $1 in #分支结构,用于判断用户的输入而进行响应的操作 nginx_status) #当输入nginx_status就调用nginx_status_fun,并传递第二和第三个参数 nginx_status_fun $2 $3; ;; *) #其他的输入打印帮助信息 echo $"Usage: $0 {nginx_status key}" esac #分支结束符 } main $1 $2 $3 #zabbix agent 添加自定义监控项 [root@node2 zabbix_agentd.d]# vim userparameter_nginx.conf UserParameter=nginx_status[*],/etc/zabbix/zabbix_agentd.d/nginx_status.sh "$1" "$2" "$3" #重启zabbix agent [root@node2 zabbix_agentd.d]# systemctl restart zabbix-agent
Zabbix服务器测试监控数据
#zabbix的repo文件中的源地址 [root@node1 ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix] name=Zabbix Official Repository - $basearch baseurl=https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/$basearch/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591 [zabbix-frontend] name=Zabbix Official Repository frontend - $basearch baseurl=https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/$basearch/frontend enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591 [zabbix-debuginfo] name=Zabbix Official Repository debuginfo - $basearch baseurl=https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/$basearch/debuginfo/ enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591 gpgcheck=1 [zabbix-non-supported] name=Zabbix Official Repository non-supported - $basearch baseurl=https://mirrors.aliyun.com/zabbix/non-supported/rhel/7/$basearch/ enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX gpgcheck=1 #安装zabbix-get [root@node1 ~]# yum install install zabbix-get -y #测试是否可以获取到数据;如果有报错,请仔细检查文件内容;这里的nginx.active是文件对应的UserParameter的内容 [root@node1 ~]# zabbix_get -s 10.0.0.132 -p 10050 -k "nginx_status["nginx_status",80,"active"]" 1
监控模板制作
创建主机
创建模板
创建监控项
创建触发器
设置表达式
添加完成
创建图形
查看图形
Mysql的监控
[root@node3 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm Retrieving https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm warning: /var/tmp/rpm-tmp.YgdI7f: Header V4 RSA/SHA512 Signature, key ID a14fe591: NOKEY Preparing... ################################# [100%] Updating / installing... 1:zabbix-release-5.0-1.el7 ################################# [100%] #修改zabbix的repo文件中的源地址 [root@node3 ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix] name=Zabbix Official Repository - $basearch baseurl=http://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/$basearch/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591 [zabbix-non-supported] name=Zabbix Official Repository non-supported - $basearch baseurl=http://mirrors.aliyun.com/zabbix/non-supported/rhel/7/$basearch/ enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX gpgcheck=1 #安装 zabbix-agent [root@node3 ~]# yum -y install zabbix-agent #配置agent [root@node3 ~]# vim /etc/zabbix/zabbix_agentd.conf Server=10.10.0.131 #指向当前zabbix server ListenPort=10050 #监听端口 ListenIP=0.0.0.0 startAgents=5 #被动状态时默认启动的实例数(进程数),为0不监听任何端口 Hostname=10.0.0.133 #启动agent [root@node2 ~]# systemctl start zabbix-agent #下载安装percona [root@node3 ~]# wget https://www.percona.com/downloads/percona-monitoring-plugins/percona-monitoring-plugins-1.1.7/binary/redhat/7/x86_64/percona-zabbix-templates-1.1.7-2.noarch.rpm #脚本需要安装php依赖包 [root@node3 scripts]# yum install php php-mysql #进入percona目录 [root@node3 ~]# cd /var/lib/zabbix/percona/templates #将文件拷贝到zabbix_agentd.d目录 [root@node3 templates]# cp userparameter_percona_mysql.conf /etc/zabbix/zabbix_agentd.d/ #就改连接密码 [root@node3 scripts]# vim ss_get_mysql_stats.php $mysql_user = 'zabbix'; $mysql_pass = 'zabbix'; [root@node3 scripts]# systemctl restart zabbix-agent
在zabbix网页中配置主机
添加模板
在图像中查看
产生zabbix邮件通知的条件为:
有可用的相关报警媒介;
正确设置了被调用邮箱的授权;
触发的相应动作调用了该报警媒介。
这里使用QQ邮箱作为zabbix调用的邮箱,即邮件通知的发件人是设置的QQ邮箱帐户。
使用zabbix调用QQ邮箱时,需要开启POP3/SMTP服务。
登录自己的QQ邮箱(即准备作为zabbix邮件通知发件人的邮箱),设置-帐户,找到“POP3/SMTP服务”,点击开启
点开启,并发送手机短信后点击我已发送
获取到授权码
(如果需要更改授权码,可以点击“生成授权码”,重新生成)
zabbix创建报警媒介
QQ邮箱所需的信息在帮助中心的常用邮件客户端软件设置中都能找到:https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=371
为zabbix的用户添加报警媒介
创建一个用户用来接收报警信息,当触发报警时自动发送给此用户的邮箱
可发送邮件测试
登录邮箱查看收到邮件
实现zabbix报警的邮件通知
实现:当被监控主机的Nginx服务80端口监听故障时,通过邮件通知到xiaoming用户。最多进行3次通知,每次通知间隔60s。
创建主机监控项,监听80端口故障
创建触发器
创建动作
基于触发器“Nginx监听80端口异常”,当触发器告警时,则激活动作。
#主题 #新Zabbix恢复通知: {TRIGGER.NAME}:{TRIGGER.STATUS} #消息 #告警商户: {TRIGGER.HOSTGROUP.NAME} #告警主机: {HOST.NAME} #主机 IP: {IPADDRESS} #告警时间: {EVENT.DATE} {EVENT.TIME} #恢复时间: {DATE} {TIME} #告警等级: {TRIGGER.SEVERITY} #告警信息: {TRIGGER.NAME} #问题详情: {ITEM.NAME}:{ITEM.VALUE} #当前状态: {TRIGGER.STATUS}:{ITEM.VALUE1} #事件 ID: {EVENT.ID}
关闭nginx测试邮件发送
[root@node2 zabbix_agentd.d]# systemctl stop nginx
邮件已经发送
打开邮件查看邮件
恢复nginx服务
root@node2 zabbix_agentd.d]# systemctl start nginx
打开邮件查看邮件