文章目录

  • 实现流程图
  • 缓存架构范围
  • 集群环境搭建
    • 1、在虚拟机中安装CentOS
    • 2.配置网络
    • 3. 配置hosts
    • 4. 关闭防火墙
    • 5.配置yum
    • 6. 在每个CentOS中都安装Java和Perl
      • (1)安装JDK
      • (2)安装Perl
    • 7、在4个虚拟机中安装CentOS集群
    • 8、配置4台CentOS为ssh免密码互相通信
      • 多个节点复制
    • 9.node1 上安装redis
      • 1、安装单机版redis
      • 2、redis的生产环境启动方案
      • 3、redis cli的使用
    • redis数据备份
      • 1、RDB和AOF两种持久化机制的介绍
      • 2、RDB持久化机制的优点
      • 3、RDB持久化机制的缺点
      • 4、AOF持久化机制的优点
      • 5、AOF持久化机制的缺点
      • 6、RDB和AOF到底该如何选择
    • Redis生产环境目录
    • Redis中配置RDB
    • Redis 配置AOP
      • 1、AOF持久化的配置
      • 2、AOF持久化的数据恢复实验
      • 3、AOF rewrite
      • 4、AOF破损文件的修复
      • 5、AOF和RDB同时工作
    • Reids企业持久化和备份方案
      • 1.企业级的持久化的配置策略
      • 2.企业级的数据备份方案
    • Redis 瓶颈
    • 10万QPS如何支持?
    • redis replication的核心机制
    • master持久化对于主从架构的安全保障的意义
    • 主从架构
      • 1.主从架构原理
      • 数据同步的核心机制
        • (1)master和slave都会维护一个offset
        • (2)backlog
        • (3)master run id
        • (4)psync
      • 3、主从之间无磁盘化复制
        • 1.全量复制
        • 2.增量复制
        • 3.数据恢复时的数据同步
      • 4、过期key处理

实现流程图


大型电商网站商品详情页实现流程

1.前端请求,达到nginx,nginx中保存了很多html模板,和本地缓存数据,如果本地缓存中有数据,则将本地的缓存渲染html模板,将响应结果返回给前端

2.如果nginx中没有本地缓存,则查看redis缓存,从redis中读取缓存,并渲染html模板,返回响应

3.如果redis中也没有缓存,则请求到缓存数据生产服务中,查看缓存中的ehacha中是否有缓存,如果有,则将ehcache中的数据拉取到redis中,渲染html模板,直接返回页面

4.如果ehcache中也没有数据,则调用商品服务,从源头再获取一份数据保存到缓存中

当商品服务中的数据发生变更以后,将变更消息推送到mq,这样缓存数据生产服务就会接受到消息,并将最新的缓存数据推送到redis中;

而nginx中的缓存是有过期期限的,比如10分钟,如果一旦过期了,就会自动从redis中获取最新的数据

如果html模板变了,不用全量重新渲染,直接将最新的html模板推送到nginx服务器上就可以

大量的情况下,数据是直接从nginx本地取的缓存,没有网络请求的开销,没有业务逻辑,渲染到模板中。

缓存架构范围

1.redis架构
要支持高并发、高可用、海量数据、数据备份,随时可恢复,缓存架构如果要支持这些要点,首先,redis就得支撑

redis架构,每秒钟几十万的访问量QPS,99.99%的高可用性,TB级的海量的数据,备份和恢复,缓存架构就成功了一半了

最最简单的模式,无非就是存取redis,存数据,取数据

支撑你的缓存架构,最基础的就是redis架构

解决各种各样高并发场景下的缓存面临的难题,缓存架构中不断的引入各种解决方案和技术,解决高并发的问题

解决各种各样缓存架构本身面临的高可用的问题,缓存架构中引入各种解决方案和技术,解决高可用的问题

集群环境搭建

我们后面,会进行一些实时计算技术的应用,包括storm,讲解一下storm的基础知识,对于java工程师来说,会用就可以了,用一些storm最基本的分布式实时计算的feature就ok了,搭建一个storm的集群

部署我们整套的系统,nginx,tomcat+java web应用,mysql

redis集群,独立的一套机器
storm集群,独立的一套机器
nginx,独立部署
tomcat + java web应用,独立部署
mysql,独立部署


1、在虚拟机中安装CentOS

启动一个virtual box虚拟机管理软件(vmware,我早些年,发现不太稳定,主要是当时搭建一个hadoop大数据的集群,发现每次休眠以后再重启,集群就挂掉了)

virtual box,发现很稳定,集群从来不会随便乱挂,所以就一直用virtual box了

(1)使用课程提供的CentOS 6.5镜像即可,CentOS-6.5-i386-minimal.iso。
(2)创建虚拟机:打开Virtual Box,点击“新建”按钮,点击“下一步”,输入虚拟机名称为node1,选择操作系统为Linux,选择版本为Red Hat,分配1024MB内存,后面的选项全部用默认,在Virtual Disk File location and size中,一定要自己选择一个目录来存放虚拟机文件,最后点击“create”按钮,开始创建虚拟机。
(3)设置虚拟机网卡:选择创建好的虚拟机,点击“设置”按钮,在网络一栏中,连接方式中,选择“Bridged Adapter”。
(4)安装虚拟机中的CentOS 6.5操作系统:选择创建好的虚拟机,点击“开始”按钮,选择安装介质(即本地的CentOS 6.5镜像文件),选择第一项开始安装-Skip-欢迎界面Next-选择默认语言-Baisc Storage Devices-Yes, discard any data-主机名:spark2upgrade01-选择时区-设置初始密码为hadoop-Replace Existing Linux System-Write changes to disk-CentOS 6.5自己开始安装。
(5)安装完以后,CentOS会提醒你要重启一下,就是reboot,你就reboot就可以了。

2.配置网络

vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=dhcp
service network restart
ifconfig

BOOTPROTO=static
IPADDR=192.168.0.X
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
service network restart

3. 配置hosts

vi /etc/hosts
配置本机的hostname到ip地址的映射

4. 关闭防火墙

service iptables stop
service ip6tables stop
chkconfig iptables off
chkconfig ip6tables off

vi /etc/selinux/config
SELINUX=disabled

关闭windows的防火墙

centos 7关闭防火墙

查看防火墙的状态的命令为:sudo systemctl status firewalld。打开防火墙的方式有两种,一种是打开后重启会恢复回原来的状态,命令为:sudo systemctl start firewalld;另一种是打开后重启不会恢复到原来的状态,命令为:sudo systemctl enable firewalld,这种方式输入命令后要重启系统才会生效。关闭防火墙的方式也有两种,和打开相对应,命令分别为sudo systemctl stop firewalld  --关闭防火墙sudo systemctl disable firewalld  --确保重启系统,防火墙也不会生效

后面要搭建集群,有的大数据技术的集群之间,在本地你给了防火墙的话,可能会没有办法互相连接,会导致搭建失败

5.配置yum

yum clean all
yum makecache
yum install wget


6. 在每个CentOS中都安装Java和Perl

WinSCP,就是在windows宿主机和linux虚拟机之间互相传递文件的一个工具

(1)安装JDK

1、将jdk-7u60-linux-i586.rpm通过WinSCP上传到虚拟机中
2、安装JDK:rpm -ivh jdk-7u65-linux-i586.rpm
3、配置jdk相关的环境变量
vi ~/.bashrc
export JAVA_HOME=/usr/java/latest
export PATH=PATH:PATH:PATH:JAVA_HOME/bin
source .bashrc
4、测试jdk安装是否成功:java -version

(2)安装Perl

很多讲师,拿着自己之前花了很多时间调试好的虚拟机环境,去讲课,这个很不负责任

yum install -y gcc

wget http://www.cpan.org/src/5.0/perl-5.16.1.tar.gz
tar -xzf perl-5.16.1.tar.gz
cd perl-5.16.1
./Configure -des -Dprefix=/usr/local/perl
make && make test && make install
perl -v

为什么要装perl?我们整个大型电商网站的详情页系统,复杂。java+nginx+lua,需要perl。

perl,是一个基础的编程语言的安装,tomcat,跑java web应用


7、在4个虚拟机中安装CentOS集群

(1)按照上述步骤,再安装三台一模一样环境的linux机器
(2)另外三台机器的hostname分别设置为node2,node3,node4
(3)安装好之后,在每台机器的hosts文件里面,配置好所有的机器的ip地址到hostname的映射关系

比如说,在eshop-cache01的hosts里面

192.168.31.187 node1
192.168.31.xxx node2
192.168.31.xxx node3
192.168.31.xxx node4


8、配置4台CentOS为ssh免密码互相通信

(1)首先在三台机器上配置对本机的ssh免密码登录
ssh-keygen -t rsa
生成本机的公钥,过程中不断敲回车即可,ssh-keygen命令默认会将公钥放在/root/.ssh目录下
cd /root/.ssh
cp id_rsa.pub authorized_keys
将公钥复制为authorized_keys文件,此时使用ssh连接本机就不需要输入密码了

以node1为例,这样我们就可以执行

ssh node1 进行登录了

(2)接着配置三台机器互相之间的ssh免密码登录
使用ssh-copy-id -i hostname命令将本机的公钥拷贝到指定机器的authorized_keys文件中

例如:

这样也就可以采用ssh的方式连接其他机器了


基于虚拟机的linux集群环境,都准备好了,手上有4台机器,后面玩儿各种redis、kafka、storm、tomcat、nginx,都有机器了

多个节点复制

节点复制以后,会存在ip相同的情况

复制产生的新的node一定要重新刷新,生成新的mac地址

然后修改新node的网络配置


重启以后,就会分配新的ip地址,之后,再将ip配置到ifcfg-enp0s3中,

再重启service network restart

然后修改本机node的/etc/hosts

9.node1 上安装redis

1、安装单机版redis

redis 3.2.8 用来如下组件,我们提前装好

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
tar -xzvf tcl8.6.1-src.tar.gz
cd /root/tcl8.6.1/unix/
./configure
make && make install

使用redis-3.2.8.tar.gz(截止2017年4月的最新稳定版)

wget http://download.redis.io/releases/redis-3.2.8.tar.gz
tar -zxvf redis-3.2.8.tar.gz
cd redis-3.2.8
make && make test && make install


2、redis的生产环境启动方案

如果一般的学习课程,你就随便用redis-server启动一下redis,做一些实验,这样的话,没什么意义

要把redis作为一个系统的daemon进程去运行的,每次系统启动,redis进程一起启动

(1)redis utils目录下,有个redis_init_script脚本
(2)将redis_init_script脚本拷贝到linux的/etc/init.d目录中,将redis_init_script重命名为redis_6379,6379是我们希望这个redis实例监听的端口号
(3)修改redis_6379脚本的第6行的REDISPORT,设置为相同的端口号(默认就是6379)

cp /root/redis-3.2.8/utils/redis_init_script /etc/init.d/
cd /etc/initd.d
mv redis_init_script redis_6379

(4)创建两个目录:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件)

mkdir -p /var/redis/6379
mkdir /etc/redis

(5)修改redis配置文件(默认在根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为6379.conf

[root@node1 redis-3.2.8]# cp /root/redis-3.2.8/redis.conf /etc/redis/
[root@node1 redis-3.2.8]# mv /etc/redis/redis.conf 6379.conf

(6)修改redis.conf中的部分配置为生产环境

daemonize yes 让redis以daemon进程运行
pidfile /var/run/redis_6379.pid 设置redis的pid文件位置
port 6379 设置redis的监听端口号
dir /var/redis/6379 设置持久化文件的存储位置

(7)启动redis,执行cd /etc/init.d,

chmod 777 redis_6379,./redis_6379 start

(8)确认redis进程是否启动,ps -ef | grep redis

(9)让redis跟随系统启动自动启动

在redis_6379脚本中,最上面,加入两行注释

# chkconfig:   2345 90 10# description:  Redis is a persistent key-value database

然后执行

chkconfig redis_6379 on


3、redis cli的使用

redis-cli SHUTDOWN,连接本机的6379端口停止redis进程

[root@node1 init.d]# ps -ef |grep redis
root 10152 1 0 14:30 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379
root 10456 1395 0 14:30 pts/0 00:00:00 grep --color=auto redis
[root@node1 init.d]# redis-cli shutdown
[root@node1 init.d]# ps -ef |grep redis
root 10707 1395 0 14:30 pts/0 00:00:00 grep --color=auto redis
[root@node1 init.d]#

redis-cli -h 127.0.0.1 -p 6379 SHUTDOWN,制定要连接的ip和端口号

redis-cli PING,ping redis的端口,看是否正常

[root@node1 init.d]# redis-cli PING
Could not connect to Redis at 127.0.0.1:6379: Connection refused

redis-cli,进入交互式命令行

[root@node1 init.d]# redis-cli
127.0.0.1:6379> get *
(nil)

生产环境不要轻易使用get *

redis数据备份

1、RDB和AOF两种持久化机制的介绍
2、RDB持久化机制的优点
3、RDB持久化机制的缺点
4、AOF持久化机制的优点
5、AOF持久化机制的缺点
6、RDB和AOF到底该如何选择

我们已经知道对于一个企业级的redis架构来说,持久化是不可减少的

企业级redis集群架构:海量数据、高并发、高可用

持久化主要是做灾难恢复,数据恢复,也可以归类到高可用的一个环节里面去

比如你redis整个挂了,然后redis就不可用了,你要做的事情是让redis变得可用,尽快变得可用

重启redis,尽快让它对外提供服务,但是就像上一讲说,如果你没做数据备份,这个时候redis启动了,也不可用啊,数据都没了

很可能说,大量的请求过来,缓存全部无法命中,在redis里根本找不到数据,这个时候就死定了,缓存雪崩问题,所有请求,没有在redis命中,就会去mysql数据库这种数据源头中去找,一下子mysql承接高并发,然后就挂了

mysql挂掉,你都没法去找数据恢复到redis里面去,redis的数据从哪儿来?从mysql来。。。

具体的完整的缓存雪崩的场景,还有企业级的解决方案,到后面讲

如果你把redis的持久化做好,备份和恢复方案做到企业级的程度,那么即使你的redis故障了,也可以通过备份数据,快速恢复,一旦恢复立即对外提供服务

redis的持久化,跟高可用,是有关系的,企业级redis架构中去讲解

redis持久化:RDB,AOF


1、RDB和AOF两种持久化机制的介绍

RDB持久化机制,对redis中的数据执行周期性的持久化

AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的时候,可以通过回放AOF日志中的写入指令来重新构建整个数据集

如果我们想要redis仅仅作为纯内存的缓存来用,那么可以禁止RDB和AOF所有的持久化机制

通过RDB或AOF,都可以将redis内存中的数据给持久化到磁盘上面来,然后可以将这些数据备份到别的地方去,比如说阿里云,云服务

如果redis挂了,服务器上的内存和磁盘上的数据都丢了,可以从云服务上拷贝回来之前的数据,放到指定的目录中,然后重新启动redis,redis就会自动根据持久化数据文件中的数据,去恢复内存中的数据,继续对外提供服务

如果同时使用RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整


2、RDB持久化机制的优点

(1)RDB会生成多个数据文件,但是每次生成的,都是新的dump.rdb,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这种完整的数据文件发送到一些远程的安全存储上去,比如说Amazon的S3云服务上去,在国内可以是阿里云的ODPS分布式存储上,以预定好的备份策略来定期备份redis中的数据

(2)RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可

(3)相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速


3、RDB持久化机制的缺点

(1)如果想要在redis故障时,尽可能少的丢失数据,那么RDB没有AOF好。一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦redis进程宕机,那么会丢失最近5分钟的数据

(2)RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒


4、AOF持久化机制的优点

(1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据

(2)AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。因为在rewrite log的时候,会对其中的指导进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。当新的merge后的日志文件ready的时候,再交换新老日志文件即可。

(4)AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据


5、AOF持久化机制的缺点

(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大

(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的

(3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。所以说,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过AOF就是为了避免rewrite过程导致的bug,因此每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。


6、RDB和AOF到底该如何选择

(1)不要仅仅使用RDB,因为那样会导致你丢失很多数据

(2)也不要仅仅使用AOF,因为那样有两个问题,第一,你通过AOF做冷备,没有RDB做冷备,来的恢复速度更快; 第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug

(3)综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复

Redis生产环境目录

/etc/redis/6379.conf —拷贝来自redis安装包中的redis.conf
/etc/init.d/redis_6379 —拷贝自redis安装包中redis utils/redis_init_script脚本,用来启动redis
/var/run/redis_7379.pid ----启动后,进程process
/var/redis/6379 --存储数据,其中dump.rdb保存在此
/usr/local/bin —保存了redis的服务和客户端命令,在安装redis执行make install的时候,将命令安装到这个地方

Redis中配置RDB

1、如何配置RDB持久化机制

redis.conf文件,也就是/etc/redis/6379.conf,去配置持久化

save 60 1000

每隔60s,如果有超过1000个key发生了变更,那么就生成一个新的dump.rdb文件,就是当前redis内存中完整的数据快照,这个操作也被称之为snapshotting,快照

也可以手动调用save或者bgsave命令,同步或异步执行rdb快照生成

save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去check一下,是否有指定的key数量发生了变更,如果有,就生成一个新的dump.rdb文件


2、RDB持久化机制的工作流程

(1)redis根据配置自己尝试去生成rdb快照文件
(2)fork一个子进程出来
(3)子进程尝试将数据dump到临时的rdb快照文件中
(4)完成rdb快照文件的生成之后,就替换之前的旧的快照文件

dump.rdb,每次生成一个新的快照,都会覆盖之前的老快照


3、基于RDB持久化机制的数据恢复实验

(1)在redis中保存几条数据,立即停掉redis进程,然后重启redis,看看刚才插入的数据还在不在

数据还在,为什么?

因为通过redis-cli SHUTDOWN这种方式去停掉redis,其实是一种安全退出的模式,redis在退出的时候会将内存中的数据立即生成一份完整的rdb快照

/var/redis/6379/dump.rdb

(2)在redis中再保存几条新的数据,用kill -9粗暴杀死redis进程,模拟redis故障异常退出,导致内存数据丢失的场景

这次就发现,redis进程异常被杀掉,数据没有进dump文件,几条最新的数据就丢失了

(2)手动设置一个save检查点,save 5 1
(3)写入几条数据,等待5秒钟,会发现自动进行了一次dump rdb快照,在dump.rdb中发现了数据
(4)异常停掉redis进程,再重新启动redis,看刚才插入的数据还在

rdb的手动配置检查点,以及rdb快照的生成,包括数据的丢失和恢复,全都演示过了

例如:

[root@node1 redis]# vi /etc/redis/6379.conf 


之后启动redis,然后设置key4 key5以后,接下来就是强制停止且重启以后的过程

[root@node1 init.d]# ps -ef |grep redis
root     18663     1  0 17:31 ?        00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379
root     19054  1395  0 17:32 pts/0    00:00:00 grep --color=auto redis
[root@node1 init.d]# kill -9 18663
[root@node1 init.d]# rm -rf /var/run/redis_6379.pid
[root@node1 init.d]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@node1 init.d]# redis-cli
127.0.0.1:6379> get key4
"name4"
127.0.0.1:6379> get key5
"name5"
127.0.0.1:6379>

发现数据依然保存在redis中

Redis 配置AOP

1、AOF持久化的配置

AOF持久化,默认是关闭的,默认是打开RDB持久化

appendonly yes

通过上面设置,可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓

打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下

而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整

可以配置AOF的fsync策略,有三种策略可以选择,一种是每次写入一条数据就执行一次fsync; 一种是每隔一秒执行一次fsync; 一种是不主动执行fsync

always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了

mysql -> 内存策略,大量磁盘,QPS到多少,一两k。QPS,每秒钟的请求数量
redis -> 内存,磁盘持久化,QPS到多少,单机,一般来说,上万QPS没问题

everysec: 每秒将os cache中的数据fsync到磁盘,这个最常用的,生产环境一般都这么配置,性能很高,QPS还是可以上万的

no: 仅仅redis负责将数据写入os cache就撒手不管了,然后后面os自己会时不时有自己的策略将数据刷入磁盘,不可控了


2、AOF持久化的数据恢复实验

(1)先仅仅打开RDB,写入一些数据,然后kill -9杀掉redis进程,接着重启redis,发现数据没了,因为RDB快照还没生成
(2)打开AOF的开关,启用AOF持久化
(3)写入一些数据,观察AOF文件中的日志内容

其实你在appendonly.aof文件中,可以看到刚写的日志,它们其实就是先写入os cache的,然后1秒后才fsync到磁盘中,只有fsync到磁盘中了,才是安全的,要不然光是在os cache中,机器只要重启,就什么都没了

(4)kill -9杀掉redis进程,重新启动redis进程,发现数据被恢复回来了,就是从AOF文件中恢复回来的

redis进程启动的时候,直接就会从appendonly.aof中加载所有的日志,把内存中的数据恢复回来


3、AOF rewrite

redis中的数据其实有限的,很多数据可能会自动过期,可能会被用户删除,可能会被redis用缓存清除的算法清理掉

redis中的数据会不断淘汰掉旧的,就一部分常用的数据会被自动保留在redis内存中

所以可能很多之前的已经被清理掉的数据,对应的写日志还停留在AOF中,AOF日志文件就一个,会不断的膨胀,到很大很大

所以AOF会自动在后台每隔一定时间做rewrite操作,比如日志里已经存放了针对100w数据的写日志了; redis内存只剩下10万; 基于内存中当前的10万数据构建一套最新的日志,到AOF中; 覆盖之前的老日志; 确保AOF日志文件不会过大,保持跟redis内存数据量一致

redis 2.4之前,还需要手动,开发一些脚本,crontab,通过BGREWRITEAOF命令去执行AOF rewrite,但是redis 2.4之后,会自动进行rewrite操作

在redis.conf中,可以配置rewrite策略

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

比如说上一次AOF rewrite之后,是128mb

然后就会接着128mb继续写AOF的日志,如果发现增长的比例,超过了之前的100%,256mb,就可能会去触发一次rewrite

但是此时还要去跟min-size,64mb去比较,256mb > 64mb,才会去触发rewrite

(1)redis fork一个子进程
(2)子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志
(3)redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件
(4)子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
(5)用新的日志文件替换掉旧的日志文件


4、AOF破损文件的修复

如果redis在append数据到AOF文件时,机器宕机了,可能会导致AOF文件破损

用redis-check-aof --fix命令来修复破损的AOF文件


5、AOF和RDB同时工作

(1)如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting
(2)如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite
(3)同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整


6、最后一个小实验,让大家对redis的数据恢复有更加深刻的体会

(1)在有rdb的dump和aof的appendonly的同时,rdb里也有部分数据,aof里也有部分数据,这个时候其实会发现,rdb的数据不会恢复到内存中
(2)我们模拟让aof破损,然后fix,有一条数据会被fix删除
(3)再次用fix得aof文件去重启redis,发现数据只剩下一条了

数据恢复完全是依赖于底层的磁盘的持久化的,主要rdb和aof上都没有数据,那就没了

vi /etc/redis/6379.conf
将
[root@node1 6379]# pwd
/var/redis/6379
[root@node1 6379]# ll
总用量 4
-rw-r--r--. 1 root root   0 6月  22 18:07 appendonly.aof
-rw-r--r--. 1 root root 141 6月  22 18:06 dump.rdb

appendonly.aof 为0是因为,虽然一开始部分数据已经set到redis中,但是redis是后来才打开的appendonly,所以历史数进不到appendonly.aof中

之后我们set一些数据进去,再看appendonly.aof

[root@node1 6379]# cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
key6
$5
name6

我们模拟一下aof文件破损

[root@node1 6379]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@node1 6379]# redis-cli
127.0.0.1:6379> set key1 name1
OK
127.0.0.1:6379> set key2 name2
OK
127.0.0.1:6379> set key3 name3
OK
127.0.0.1:6379> set key4 name4
OK
127.0.0.1:6379> set key5 name5
OK
127.0.0.1:6379> exit
[root@node1 6379]# redis-cli shutdown
[root@node1 6379]# cd /var/redis/6379/
[root@node1 6379]# ll
总用量 8
-rw-r--r--. 1 root root 250 6月  22 18:32 appendonly.aof
-rw-r--r--. 1 root root 153 6月  22 18:32 dump.rdb
[root@node1 6379]# vi appendonly.aof
删除末尾的部分数据,模拟破损将项目拷贝到另一个目录
[root@node1 6379]# cp appendonly.aof /usr/local/bin/[root@node1 bin]# /root/redis-3.2.8/src/redis-check-aof --fix /usr/local/bin/appendonly.aof
0x              e0: Expected to read 5 bytes, got 2 bytes
AOF analyzed: size=226, ok_up_to=216, diff=10
This will shrink the AOF from 226 bytes, with 10 bytes, to 216 bytes
Continue? [y/N]: y
Successfully truncated AOF再拷贝回去
[root@node1 bin]# cp /usr/local/bin/appendonly.aof /var/redis/6379/
cp:是否覆盖"/var/redis/6379/appendonly.aof"? y

重启项目以后,发现只有部分数据了

[root@node1 6379]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@node1 6379]# redis-cli
127.0.0.1:6379> keys *
1) "key6"
2) "key1"
3) "key2"
4) "key3"
5) "key4"
127.0.0.1:6379> 

其他丢失的数据,为什么不从rdb中获取恢复 呢?
在有rdb的dump和aof的appendonly的同时,rdb里也有部分数据,aof里也有部分数据,这个时候其实会发现,rdb的数据不会恢复到内存中

Reids企业持久化和备份方案

1.企业级的持久化的配置策略

在企业中,RDB的生成策略,用默认的也差不多

save 60 10000:如果你希望尽可能确保说,RDB最多丢1分钟的数据,那么尽量就是每隔1分钟都生成一个快照,低峰期,数据量很少,也没必要

10000->生成RDB,1000->RDB,这个根据你自己的应用和业务的数据量,你自己去决定

AOF一定要打开,fsync,everysec

auto-aof-rewrite-percentage 100: 就是当前AOF大小膨胀到超过上次100%,上次的两倍
auto-aof-rewrite-min-size 64mb: 根据你的数据量来定,16mb,32mb

2.企业级的数据备份方案

RDB非常适合做冷备,每次生成之后,就不会再有修改了

数据备份方案

(1)写crontab定时调度脚本去做数据备份
(2)每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份
(3)每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份
(4)每次copy备份的时候,都把太旧的备份给删了
(5)每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去

如下是通过shell方式定时将dump.rdb拷贝到固定磁盘的例子:

[root@node1 redis]# pwd
/usr/local/redis
[root@node1 redis]# vi redis_rdb_copy_hourly.sh
cur_date=`date +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir -p /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date
del_date=`date -d -48hour +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$del_date
[root@node1 redis]# sh redis_rdb_copy_hourly.sh
[root@node1 redis]# ll
总用量 4
-rw-r--r--. 1 root root 275 6月  23 11:03 redis_rdb_copy_hourly.sh
drwxr-xr-x. 3 root root  24 6月  23 11:03 snapshotting
[root@node1 redis]# cd snapshotting/
[root@node1 snapshotting]# ll
总用量 0
drwxr-xr-x. 2 root root 22 6月  23 11:03 2022062311
[root@node1 snapshotting]# cd 2022062311/
[root@node1 2022062311]# ll
总用量 4
-rw-r--r--. 1 root root 141 6月  23 11:03 dump.rdb
[root@node1 2022062311]# cd ..
[root@node1 snapshotting]# date -d -48hour +%Y%m%d%k
2022062111
[root@node1 snapshotting]# mkdir 2022062111
再次执行 sh redis_rdb_copy_hourly.sh 会发现2022062111目录被删除了

可以将sh执行由crontab定时执行

crontab -e
内容为:
0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

也可以实现一天备份一次

crontab -e

内容为:
0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

vi redis_rdb_copy_daily.sh

#!/bin/sh cur_date=`date +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_datedel_date=`date -d -1month +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date

热修改redis中的配置信息,但是这种方式的修改无法无法持久化到redis配置文件中,redis重启就会失效

Redis 瓶颈

单机Redis QPS也就上万或者几万

如果要实现高并发,高可用,就必须用集群

10万QPS如何支持?

如果redis要支撑超过10万+的并发,那应该怎么做?

单机的redis几乎不太可能说QPS超过10万+,除非一些特殊情况,比如你的机器性能特别好,配置特别高,物理机,维护做的特别好,而且你的整体的操作不是太复杂

单机在几万

读写分离,一般来说,对缓存,一般都是用来支撑读高并发的,写的请求是比较少的,可能写请求也就一秒钟几千,一两千

大量的请求都是读,一秒钟二十万次读

读写分离

主从架构 -> 读写分离 -> 支撑10万+读QPS的架构
一主多从,主负责写,将数据同步到slave,slave负责读,如果后期QPS增加,水平扩容很方便(直接增加slave机器就可以)

redis replication的核心机制

(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量
(2)一个master node是可以配置多个slave node的
(3)slave node也可以连接其他的slave node
(4)slave node做复制的时候,是不会block master node的正常工作的
(5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
(6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量

slave,高可用性,有很大的关系

master持久化对于主从架构的安全保障的意义

如果采用了主从架构,那么建议必须开启master node的持久化

不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了

master -> RDB和AOF都关闭了 -> 全部在内存中

master宕机,重启,是没有本地数据可以恢复的,然后就会直接认为自己IDE数据是空的

master就会将空的数据集同步到slave上去,所有slave的数据全部清空

100%的数据丢失

master节点,必须要使用持久化机制

第二个,master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的

即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障

主从架构

1.主从架构原理

1)slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没开始(master host和ip是从哪儿来的,redis.conf里面的slaveof配置的
)
(2)slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接
(3)slave node发送ping命令给master node
(4)口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证
5) slave node 它会发送一个PSYNC命令给master node

如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据;,也就是断点续传。否则如果是slave node第一次连接master node,那么会触发一次full resynchronization

开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

为了保证同步数据的一致性

数据同步的核心机制

(1)master和slave都会维护一个offset

master会在自身不断累加offset,slave也会在自身不断累加offset
slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset

这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况

(2)backlog

master node有一个backlog,默认是1MB大小
master node给slave node复制数据时,也会将数据在backlog中同步写一份
backlog主要是用来做全量复制中断候的增量复制的

(3)master run id

在slave node上,如何查看master run id ?????

info server

可以看到master run id
如果根据host+ip定位master node,是不靠谱的,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,run id不同就做全量复制
如果需要不更改run id重启redis,可以使用redis-cli debug reload命令

(4)psync

从节点使用psync从master node进行复制,psync runid offset
master node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制

从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份

master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制

但是如果没有找到对应的offset,那么就会执行一次resynchronization

3、主从之间无磁盘化复制

master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

repl-diskless-sync
repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来

1.全量复制

(1)master执行bgsave,在本地生成一份rdb快照文件
(2)master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数
(3)对于千兆网卡的机器,一般每秒传输100MB(1000/8计算得到),6G文件,很可能超过60s
(4)master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,用户大量的写入,由于此时写入的命令写入到了缓存中,导致内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败

(6)slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务
(7)如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF

rdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间 如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟

2.增量复制

(1)如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制
(2)master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB
(3)msater就是根据slave发送的psync中的offset来从backlog中获取数据的

3.数据恢复时的数据同步

1)起初master node和slave node数据一致,都有100w条数据
2)由于某些故障原因,需要恢复20小时以前的rdb数据,此时master node中数据已经发生了变更,而且run id也变了
3)此时slave还依旧拿着之前的run id去同步,肯定是不行的,这种情况,只能全量同步了
master每次重启runid都发生变化

4、过期key处理

slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。


如果全量复制在5 ,6G的话,可能要耗费2分钟的样子

1.亿级流量电商详情页系统实战--主节点部署redis相关推荐

  1. 亿级流量电商详情页系统实战:缓存架构+高可用服务架构+微服务架构

    <缓存架构+高可用服务架构+微服务架构>深入讲解了亿级流量电商详情页系统的完整大型架构.同时最重要的是,在完全真实的大型电商详情页系统架构下,全流程实战了整套微服务架构,包含了基于领域驱动 ...

  2. 大型电商架构亿级流量电商详情页系统实战--redis基础票

    亿级流量电商详情页系统实战-缓存架构+高可用服务架构+微服务架构 01_高并发高可用复杂系统中的缓存架构有哪些东西 (1)如何让redis集群支撑几十万QPS高并发+99.99%高可用+TB级海量数据 ...

  3. 19.亿级流量电商详情页系统实战---总结

    文章目录 1.亿级流量电商网站的商品详情页系统架构 2.redis企业级集群架构 3.多级缓存架构设计 4.数据库+缓存双写一致性解决方案 5.缓存维度化拆分解决方案 6.缓存命中率提升解决方案 7. ...

  4. 大型电商架构亿级流量电商详情页系统--实战 服务降级

    86_电商网站的商品详情页缓存服务业务背景以及框架结构说明 我们这个课程,基于hystrix,如何来构建高可用的分布式系统的架构,项目实战 模拟真实业务的这么一个小型的项目,来全程贯穿,用这个项目中的 ...

  5. 大型电商架构亿级流量电商详情页系统实战-缓存架构+高可用服务架构+微服务架构(七)

    文章目录 八十九.高并发场景下恐怖的缓存雪崩现象以及导致系统全盘崩溃的后果 九十.缓存雪崩的基于事前+事中+事后三个层次的完美解决方案 九十一.基于hystrix完成对redis访问的资源隔离以避免缓 ...

  6. 大型电商架构亿级流量电商详情页系统--实战 缓存同步,热点key统计 降级

       35 我们之前的三十讲,主要是在讲解redis如何支撑海量数据.高并发读写.高可用服务的架构,redis架构 redis架构,在我们的真正类似商品详情页读高并发的系统中,redis就是底层的缓存 ...

  7. 6.亿级流量电商详情页系统实战

    1.上亿流量的商品详情页系统的多级缓存架构 很多人以为,做个缓存,其实就是用一下redis,访问一下,就可以了,简单的缓存 做复杂的缓存,支撑电商复杂的场景下的高并发的缓存,遇到的问题,非常非常之多, ...

  8. 亿级流量电商详情页系统实战-1.小型电商网站的商品详情页的页面静态化架构以及其缺陷

    1.电商网站按规模分类 电商网站里,大概可以说分成两种: 小型电商 简单的一种架构方案,页面静态化的方案 大型电商 复杂的一套架构,大电商,国内排名前几的电商,大型的详情页架构页面静态化,全量的页面静 ...

  9. 亿级流量电商详情页系统实战-28.商品详情页结构分析、缓存全量更新问题以及缓存维度化解决方案

    1.前言 实时性比较高的那块数据,比如说库存,销量之类的这种数据,我们采取的实时的缓存+数据库双写的技术方案,双写一致性保障的方案 实时性要求不高的数据,比如说商品的基本信息,等等,我们采取的是三级缓 ...

最新文章

  1. Java_Shell多线程
  2. 双网卡oracle rac,Linux+Oracle 10g RAC双网卡绑定和解除绑定的实现(2)
  3. linux grub 下载,GRUB 2.04发布下载,附新功能介绍
  4. 打开非遗文化新呈现方式 三七互娱“非遗广州红”游园会即将开幕
  5. 竟然有一半的人不知道 for 与 foreach 的区别???
  6. mendeley 笔记_免费文献管理器 Mendeley,其实比你想象的好用!
  7. vc 文件总行数_Spark中的文件源(上)—— Spark的文件组织方式
  8. Mac中显示和隐藏隐藏文件命令行
  9. FZCCHJW--GB1-0-GBpc-EUC-H:在系统中未找到字体;已替换缺少的字体。
  10. C语言解决约瑟夫环问题
  11. 了解计算机技术的课件,了解计算机课件.ppt
  12. 计算机的高级应用office,MS Office高级应用
  13. vasp计算-INCAR文件
  14. linux开发板增加adb功能
  15. k8s高可用二进制部署
  16. python合并两列数据_python将两列合并
  17. 深入支付宝支付扫描支付-跳转支付宝二维码页面支付与自定义生成二维码支付-2跳转固定的支付宝页面进行扫码支付
  18. 无限循环小数四则运算_无尽小数的公理及其四则运算.doc
  19. 【夜读】一个人最积极的生活状态
  20. 在线文章生成-自动文章生成

热门文章

  1. 模拟股票涨跌功能(jquery应用4)
  2. 在人一生的成长过程中,什么才是最重要的因素?
  3. barrier()函数
  4. 期末复习操作系统---设备管理
  5. 【语音识别】作业1:语音特征提取
  6. 企业数字化转型迫切,团队协同工具何以成为“杀手锏”?
  7. HDU-4745-Two Rabbits
  8. Linux ALSA 之九:ALSA ASOC Codec Driver
  9. QQ和微信止步不前,意味着即时通讯社交应用创业的第2春已来?
  10. Wargames学习笔记--Bandit