第三周作业
第三周
1、redis服务配置文件详解
daemonize yes
tcp-backlog 511
timeout 0
tcp-keepalive 60
loglevel notice
logfile "/data/redis/logs/redis.log"
databases 16
bind {{ ansible_ssh_host }} #修改为绑定主机IP
dir /data/redis/backup/ # 数据持久化保存路径,可自定义修改
port {{ redis_port }} # redis 监控端口,默认6379
maxmemory {{ redis_max_mem }} #定义redis可用最大物理内存,通常设置为2G
maxmemory-policy volatile-lru #过期策略,只对设置了过期时间的key进行LRU(默认方式)
stop-writes-on-bgsave-error no
repl-timeout 60 #slave和master之间的复制超时时间
repl-ping-slave-period 10 #定义心跳(PING)间隔
repl-disable-tcp-nodelay no #??启用 TCP_NODELAY 无网络延迟,主服务器的命令无论大小都会及时发送给从节点
repl-backlog-size 10M #环形缓冲区,主库会记录自己写到的位置,从库则会记录自己 已经读到的位置
repl-backlog-ttl 7200 #环形缓冲复制队列存活时长(所有slaves不可用时,保留repl_backlog多长时间,单位:秒)
slave-serve-stale-data yes #主从复制中,从服务器可以响应客户端请求
slave-read-only yes # 为只读状态
slave-priority 100 #slave的权重值,默认100,Sentinel将会从slave列表中找到权重值最低(>0)的slave,并提升为master。如果权重值为0,表示此slave为"观察者",不参与master选举
lua-time-limit 5000 #lua脚本运行的最大时间
slowlog-log-slower-than 10000 #"慢操作日志"记录,单位:微秒,"0"表示记录全部操作
slowlog-max-len 128 #"慢操作日志"保留的最大条数
hash-max-ziplist-entries 512 #hash类型ziplist中允许存储的最大条目个数,,默认为512
hash-max-ziplist-value 64 #hash类型ziplist中允许条目value值最大字节数,默认为64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes #是否开启顶层数据结构的rehash功能,rehash能够很大程度上提高K-V存取的效率
client-output-buffer-limit normal 0 0 0 #客户端buffer控制<class> <hard> <soft> <seconds>hard和soft都设置为0,则表示禁用buffer控制.通常hard值大于soft
client-output-buffer-limit slave 512mb 128mb 60 # normal -> 普通连接;slave ->与slave之间的连接;pubsub ->pub/sub类型连接
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10 #Redis server执行后台任务的频率,默认为10
save 3600 1 #保存数据快照的频率,即将数据持久化到dump.rdb文件中的频度
appendonly yes #开启append only 模式
appendfsync everysec
appendfilename {{ ansible_ssh_host }}.{{ redis_port }}.aof #aof 文件名称,使用IP+port.aof格式
dbfilename {{ ansible_ssh_host }}.{{ redis_port }}.rdb # 镜像文件名称IP+port,rdb 格式
aof-rewrite-incremental-fsync yes
no-appendfsync-on-rewrite yes #在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略
auto-aof-rewrite-min-size 512m # 触发aof rewrite的最小文件尺寸
auto-aof-rewrite-percentage 80 #当Aof log增长超过指定比例时,重写log file, 设置为0表示不自动重写Aof 日志
rdbcompression yes #数据镜像备份时,是否启用rdb文件压缩手段,默认为yes
rdbchecksum yes
repl-diskless-sync no
repl-diskless-sync-delay 5
maxclients 1000 #限制同时连接的客户数量。当连接数超过这个值时,redis 将不再接收其他连接请求
hll-sparse-max-bytes 3000
min-slaves-to-write 0
min-slaves-max-lag 10
aof-load-truncated yes
notify-keyspace-events ""
protected-mode yes
pidfile /var/run/redis.pid
requirepass {{ redis_auth_password }} #客户端连接密码
masterauth {{ redis_auth_password }} #主数据库连接密码
2、RDB、AOF详解及优缺点总结
2.1 Redis 持久化:
2.1.1 持久化流程
要有下面五个过程:
(1)客户端向服务端发送写操作(数据在客户端的内存中)。
(2)数据库服务端接收到写请求的数据(数据在服务端的内存中)。
(3)服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。
(4)操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。
(5)磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。
这5个过程是在理想条件下一个正常的保存流程,但是在大多数情况下,我们的机器等等都会有各种各样的故障,这里划分了两种情况:
(1)Redis数据库发生故障,只要在上面的第三步执行完毕,那么就可以持久化保存,剩下的两步由操作系统替我们完成。
(2)操作系统发生故障,必须上面5步都完成才可以。
2.1.2 RDB机制
RDB持久化是指在指定的时间间隔内将内存中的数据集快照(point-in-time snapshot)写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
特性:fork一个进程,遍历hash table,利用copy on write,把整个db dump保存下来。
save, shutdown, slave 命令会触发这个操作。
粒度比较大,如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复。
1、save触发方式
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。具体流程如下:

执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。
2、bgsave触发方式
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:

具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

3、自动触发
自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置,我们可以去设置:
①save:这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
默认如下配置:
#表示900 秒内如果至少有 1 个 key 的值变化,则保存save 900 1#表示300 秒内如果至少有 10 个 key 的值变化,则保存save 300 10#表示60 秒内如果至少有 10000 个 key 的值变化,则保存save 60 10000
不需要持久化,那么你可以注释掉所有的 save 行来停用保存功能。
②stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了
③rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。
④rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
⑤dbfilename :设置快照的文件名,默认是 dump.rdb
⑥dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。
4、 RDB优点:
(1)RDB会生成多个数据文件,每个数据文件都代表了某一个时刻的数据,这种多个数据文件的方式,非常适合做冷备。
(2)RDB在redis对外提供读写服务的时候,影响非常的小,因为redis主进程只需要fork一个子进程出来,让子进程对磁盘io来进行持久化。
(3)RDB在恢复大数据集的时速度比AOF的恢复速度快。
5、RDB缺点:
(1)如果redis要故障时尽可能的少丢失数据,RDB没有AOF好。例如1:00进行的快照,在1:10又要进行快照的时候宕机了,这个时候就会丢失10分钟的数据。
(2)RDB每次fork出子进程来执行RDB快照生成文件时,如果文件特别大,可能会导致客户端提供服务暂停数毫秒或者几秒。
2.1.3 AOF机制
redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。
1、持久化原理

每当有一个写命令过来时,就直接保存在我们的AOF文件中。
2、文件重写原理
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。

重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
3、AOF也有三种触发机制
(1)每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
(2)每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失
(3)不同no:从不同步
4、AOF优点:
(1)AOF可以更好的保护数据不丢失,一般AOF会以每隔1秒,通过后台的一个线程去执行一次fsync操作,如果redis挂掉了,最多丢失1秒的数据。
(2)AOF以append-only的模式写入,所以没有任何的磁盘寻址的开销,写入性能非常的高。
(3)AOF日志文件的命令通过非常可读的方式进行记录,这个非常适合做灾难性的误删除紧急恢复,如果某人不小心用flushall命令清空了所有数据,只要这个时候还没有执行rewrite,那么就可以将日志文件中的flushall删除,进行恢复。
5、AOF缺点:
(1)对于同一份数据备份文件,AOF比RDB大
(2)AOF开启后支持写的QPS会比RDB支持的写的QPS低,因为AOF一般会配置成每秒fsync操作,每秒的fsync操作还是很高的。
(3)数据恢复比较慢,不适合做冷备。
2.1.4二者的区别
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
2.1.5 RDB和AOF到底该如何选择
- 如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久。
- AOF 将 Redis 执行的每一条命令追加到磁盘中,处理巨大的写入会降低 Redis 的性能,不知道你是否可以接受。
2.1.6 数据库备份和灾难恢复**:
定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。
Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。
3、Redis Cluster扩、缩容
3、Redis Cluster扩、缩容
4、LVS调试算法总结
4.1 LVS介绍
LVS:Linux Virtual Server(Linux虚拟服务器),负载调度器,分发用户的请求,该功能集成在内核处。
4.2 LVS相关术语
VS:Virtual Server,也叫Director Server、Dispatcher(调度器)。指的是负载调度的主机
RS:Real Server。VS将请求分发到后端干活的主机。
VIP:Virtual Server IP。VS接收外部的用户请求的IP;作为用户请求的目标IP地址
DIP:Director Server IP。VS与内部干活的主机通讯的IP
RIP:Real Server IP。后端干活的主机的IP
CIP:Client IP。客户端的IP
访问流程:CIP<-->VPI == DIP<-->RIP
4.3 工作原理
LVS根据请求报文的目标和目标协议及端口将其调度转发至某RS,根据算法来挑选RS。LVS是内核级功能,工作在input链的位置,将发往input的流量进行处理。
4.4 工作模式
4.4.1 NAT模式
本质是多目标的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的的RS和RIP和port实现转发:
(DNAT:就是对数据包的源地址和目的地址进行修改,并且保存修改前后的映射关系,并且根据需要进行还原操作)
注:
(1)RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关指向DIP
(2)请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈
(3)支持端口映射,可修改请求报文的目标PORT
(4)VS必须是Linux系统,RS可以是任意OS系统
4.4.2 DR模式
Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变
DR模式的特点:
- Director和各RS都配置有VIP
- 确保前端路由器将目标IP为VIP的请求报文发往Director
- RS的RIP可以使用私网地址,也可以是公网地址; RIP与DIP在同一IP网络; RIP的网关不能指向DIP,以确保响应报文不会经由Director
- RS和Director要在同一个物理网络
- 请求报文要经由Director,但响应报文不经由Director, 而由RS直接发往Client
- 不支持端口映射(端口不能修改)
- 无需开启ip_forward
- RS可使用大多数OS系统
4.4.3TUN模式
转发方式:不修改请求报文的IP首部,(源IP为CIP,目标IP为VIP),而在源IP报文之外再封装一个IP首部(源IP是DIP,目标IP是DIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
TUN模式特点
-
RIP和DIP可以不处于同一物理网络中,RS的网关一般不能指向DIP,且RIP可以和公网通信。也就是说集群节点可以跨互联网实现。DIP, VIP, RIP可以是公网地址
-
RealServer的tun接口上需要配置VIP地址,以便接收director转发过来的数据包,以及作为响应的报文源IP
-
Director转发给RealServer时需要借助隧道,隧道外层的IP头部的源IP是DIP,目标IP是RIP, 而RealServer响应给客户端的IP头部是根据隧道内层的IP头分析得到的,源IP是VIP,目标IP是CIP
-
请求报文要经由Director,但响应不经由Director ,响应由RealServer自己完成
-
不支持端口映射
-
RS的OS须支持隧道功能
4.4.4 FULLNAT模式
通过同时修改请求报文的源IP地址和目标地址进行转发
FULLNAT特点
- VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
- RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
- 请求和响应报文都经由Director
- 相对NAT模式,可以更好的实现LVS-RealServer间跨VLAN通讯
- 支持端口映射
4.5 调度算法
ipvs scheduler:根据其调度时是否考虑各RS当前的负载状态
分为两种:静态方法和动态方法
4.5.1 静态方法
仅根据算法本身进行调度
1、RR:RoundRobin,轮询,较常用
2、WRR:Weighted RR ,加权轮询,较常用
3、SH:Source Hashing ,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定。
4、DH:Desination Hashing,目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用是正向代理缓存场景中的负载均衡,如:Web缓存
4.5.2 动态方法
主要根据每RS当前的负载状态及调度算法进行调度Overhead的值越小说明负载越小,处于最小的RS将被调度
1、LC:least connections,最小链接算法,适用于长链接应用
Overhead=activeconns*256+inactiveconns
此算法需计算后端的链接数,当前链接数越少的RS主机分配到的请求就越多。
但此算法有个缺陷:不能按照人为主观意愿进行分配。
比如加台性能更强的新机器到集群中,该新机器能承受更多的请求更高的并发,使用LC算法并不能主动分配链接请求到新机器中去。
2、WLC:Weighted LC,加权最少连接,默认调度方法,较常用
Overhead=(activeconns*256+inactiveconns)/weight
此算法可以根据加权重的方式来弥补LC算法不能人为主观意愿分配请求的问题。权重越大,分配到的请求就越多
但此法也有个缺陷:初始状态下,高权重RS主机不能优先接收的请求。比如:当刚搭建完LVS集群,后端RS主机都加了大大小小的权重,此时链接数都为0,那么根据WLC算法,此时不论哪台RS主机权重大小如何,分配到请求的几率是一样的,有可能将请求分配到性能较差的主机。
3、SED: Shortest Expection Delay,最短延时调度,初始连接高权重优先,只检查活动连接,而不考虑非活动连接
Overhead=(activeconns+1)*256/weight
此算法解决了WLC的缺陷,使得初始状态下,高权重RS主机可以优先接收的请求。
但此法也有个缺陷:当RS主机之间权重差别过大的情况,会导致权重小的RS主机接收不到请求。
比如:A主机权重为1,B主机权重为10,当一个新连接请求过来时,此时A主机的负载为:Overhead=(activeconns+1)256/weight=(0+1)256/1=256,B主机的负载为:Overhead=(activeconns+1)256/weight=(0+1)256/10=25.6,此时新连接请求就往B主机调度;当第二个新连接请求过来时,此时A主机的负载为:Overhead=(activeconns+1)256/weight=(0+1)256/1=256,B主机的负载为:Overhead=(activeconns+1)256/weight=(1+1)256/10=51.2,新连接还是往B主机调度,以此类推。这种情况下,A主机收不到请求,空闲下来,从而造成资源浪费。
4、NQ: Never Queue,第一轮均匀分配,后续SED
此算法是当RS主机至少分配了一次连接请求后,再根据SED算法进行调度。此算法弥补了SED的不足。
5、LBLC: Locality-Based LC,动态的DH算法。
此算法是把目标地址进行哈希运算,根据运算结果动态的调度到后端负载最小的RS主机
使用场景:根据负载状态实现正向代理,实现Web Cache等
6、LBLCR: LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS,实现Web Cache等
内核版本4.15版本后新增的调度算法
FO (Weighted Fail Over)调度算法,在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F_OVERLOAD标志)的且权重最高的真实服务器,进行调度
OVF (Overflow-connection) 调度算法,基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值,之后调度到下-个权重值最高的真实服务器,在此0VF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。
5、LVS的NAT、DR模型实现

浙公网安备 33010602011771号