您的位置:首页 > 运维架构 > 网站架构

亿级流量场景下,大型缓存架构的虚拟机环境搭建

2018-08-18 23:16 525 查看
---内容持续更新---

首先说一下三个重要的标准:

海量数据:支持海量数据缓存,支持大规模数据;

高并发:在亿级QPS的场景下,可以做到满足业务需求;

高可用:表示redis可以做到并且尽可能的做到 可以持续使用。比如全年保持99.99%的时间处在可用状态,除非遇到各种断电等特殊灾害;



小型电商:

静态模板是固定的 数据库中的数据全量喧嚷到模板中,下次请求来了直接返回,速度也很快;



当数据上亿的时候,如果模板改定,把这些所有的数据在mysql中渲染进模板,非常耗时,不现实;



大型电商 --- 使用大型的高级缓存架构:

缓存数据生产服务;

不需要再进行全量重新渲染,直接将最新的html模板推送到nginx服务器,请求过来后直接在nginx本地进行渲染进模板中返回请求;



redis的重要性:



虚拟机环境设置 ---- 安装ISO + 配置网络 + 安装JDK和Perl + SSH免密通信:

虚拟机中安装CentOS

启动一个virtual box虚拟机管理软件 使用CentOS 6.5镜像即可,CentOS-6.5-i386-minimal.iso。

配置网络

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

配置hosts

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

配置SecureCRT【本人使用的Xshell 感觉也很好用】

此时就可以使用SecureCRT从本机连接到虚拟机进行操作了

关闭防火墙

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

vi /etc/selinux/config
SELINUX=disabled

关闭windows的防火墙

配置yum

yum clean all
yum makecache
yum install wget

------------------------------------------------------------------------------------------

在每个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:$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应用

------------------------------------------------------------------------------------------

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

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

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

192.168.31.187 eshop-cache01
192.168.31.xxx eshop-cache02
192.168.31.xxx eshop-cache03
192.168.31.xxx eshop-cache04

------------------------------------------------------------------------------------------

4、配置4台CentOS为ssh免密码互相通信【此时四台linux虚拟机可以通过ssh实现无密码输入通信】

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

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

虚拟机环境设置 ---- 单机版Redis安装以及生产环境设置(开机自启动)

1、安装单机版tcl + redis

1. wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz 2. tar -xzvf tcl8.6.1-src.tar.gz
3. cd /usr/local/tcl8.6.1/unix/
4. ./configure
5. make && make install

6. 使用redis-3.2.8.tar.gz(截止2017年4月的最新稳定版)
7. tar -zxvf redis-3.2.8.tar.gz
8. cd redis-3.2.8
9. make && make test && make install

------------------------------------------------------------------------

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

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

1. 要把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)
(4)创建两个目录:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件,也就是后面要使用的redis备份)
(5)修改redis配置文件(默认在根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为6379.conf

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

  daemonize    yes    让redis以daemon进程运行(守护线程,可以理解为java运行时的jvm线程,在后台进行service服务)
  pidfile    /var/run/redis_6379.pid 设置redis的pid文件位置 【/var/run 目录下放的是各程序的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

在Xshell中执行 chkconfig redis_6379 on

------------------------------------------------------------------------

3、redis cli的使用

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

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

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

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

存取删测试:

set k1 v1
get k1
del k1


redis的技术,包括4块:

redis各种数据结构和命令的使用,包括java api的使用
redis一些特殊的解决方案的使用,pub/sub消息系统,分布式锁,输入的自动完成,等等
redis日常的管理相关的命令
redis企业级的集群部署和架构

redis的使用以及原理分析:

1、redis持久化的意义:



Redis在不使用备份的情况下会产生缓存雪崩问题;



下边堆 redis 写如数据的两种方式进行分析:

原理图:



redis 的 AOF 下的 rewrite 机制原理:



AOF和RDB两种模式:

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

如果我们想要redis仅仅作为纯内存的缓存来用,那么可以禁止RDB和AOF所有的持久化机制【但是采用这种方式的项目是个高危项目】

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

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

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

RDB持久化机制,对redis中的数据执行周期性的持久化,也就是每个固定的时间去做一次内存快照的保存工作,适合做冷备份。

-------------------------------------------------------------------------------------

RDB持久化机制的优点

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

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

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

-------------------------------------------------------------------------------------

RDB持久化机制的缺点

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

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

-------------------------------------------------------------------------------------

AOF持久化机制的优点

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

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

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

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

-------------------------------------------------------------------------------------

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的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

-------------------------------------------------------------------------------------

linux环境下 redis 的默认配置中 AOF 模式是关闭的 可以从配置文件 appendonly=no 看到,而 默认打开的是 RDB 模式;在两种模式都开启的情况下,做数据恢复的时候优先使用AOF的数据;

下面重点对AOF模式的配置进行分析:

设置appendonly=yes;

设置appendfsync,对于设置linux缓存oscache支持的选项 always, everysec,no;

设置auto-aof-rewrite-percentage 1-100 用来设置现在aof文件大小相比于上次rewrite时空间增加的比例 比如设置为100 则表示 在比上一次增大了一倍时再次rewrite

设置auto-aof-rewrite-min-size XXmb 最小rewrite空间大小,以mb为单位,必须超过该空间才有可能触发rewrite,每次都会进行比较;

rewrite过程描述:



rewrite的实现图,在创建新aof文件时如果有新的client加入数据时的场景,新的数据会都保存在新旧aof文件中后

再删除旧的aof文件;



redis的数据受损修复功功能:



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

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

1、数据备份方案

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

2、数据恢复方案

(1)如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据

(2)如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复,AOF没有破损,也是可以直接基于AOF恢复的,AOF append-only,顺序写入,如果AOF文件破损,那么用redis-check-aof fix【损坏部分容忍丢失,其实只丢失了一秒的数据量】

(3)如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复

当前最新的AOF和RDB文件都出现了丢失/损坏到无法恢复,一般不是机器的故障,人为

/var/redis/6379下的文件给删除了,找到RDB最新的一份备份,小时级的备份可以了,小时级的肯定是最新的,copy到redis里面去,就可以恢复到某一个小时的数据

容灾演练

停止redis,关闭aof,拷贝rdb备份,重启redis,确认数据恢复,直接在命令行热修改redis配置,打开aof,这个redis就会将内存中的数据对应的日志,写入aof文件中

此时aof和rdb两份数据文件的数据就同步了,redis config set热修改配置参数,可能配置文件中的实际的参数没有被持久化的修改,再次停止redis,手动修改配置文件,打开aof的命令,再次重启redis

(4)如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据

(5)如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复

非单机redis介绍:

单机的redis的一般场景下的极限值差不多读的QPS在5万左右,当然也收服务器的性能配置影响,所以高于这个极限值很大的境况下,redis随时有崩掉的危险,那么

怎么做到更高的QPS呢,总的思路就是读写分离,同时增加读的redis个数,因为在通常的场景下,读远远大于写;

这就引出了redis的主从结构话设计;



主从结构框架配置 必须实现 master 的持久化!!!



主从reids间的同步原理:



redis的主从通信基本流程:



runid的作用:



redis replication原理总结:

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)master node第一次执行全量复制,将所有数据发给slave node
(6)master node后续持续将写命令,异步复制给slave node

2、数据同步相关的核心机制

指的就是第一次slave连接msater的时候,执行的全量复制,那个过程里面你的一些细节的机制

(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

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触发增量复制

3、全量复制

(1)master执行bgsave,在本地生成一份rdb快照文件
(2)master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数
(3)对于千兆网卡的机器,一般每秒传输100MB,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分钟

4、增量复制

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

5、heartbeat

主从节点互相都会发送heartbeat信息

master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat

6、异步复制

master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node

虚拟机配置主从结构的redis连接:

1、在slave node上配置:slaveof 192.168.X.X 6379,即可

2、强制读写分离

基于主从复制架构,实现读写分离 redis slave node必须设置为只读模式,默认开启,slave-read-only yes

开启了只读的redis slave node,会拒绝所有的写操作,这样可以强制搭建成读写分离的架构

3、集群安全认证

master上启用安全认证,requirepass passwd
slave上设置连接口令,masterauth passwd

两个passwd需要保持一致

4、bind 对应的 IP

在master 和 slave 上都设置bind IP,默认为127.0.0.1 这里需要设置自己的虚拟机的ip

5、

先开启master,使用 redis-cli -h IP -a passwd 命令操作,本人操作过,如果不加 -a passwd参数会出现 (error) NOAUTH Authentication required.错误

输入后进入redis命令号 输入info replication 进行验证



验证结果



【从中也可以看到 master和slave的offset此时是不一致的】

然后开启slave从redis; 输入redis-cli -h IP; 然后输入info replication进行信息验证;



验证结果



主从数据验证:

master:



slave:



可以看到master的RDB数据已经传到了slave中; 同时我们也可以知道,如果在slave上试图添加数据,会被无情的拒绝;

----------------------------------------------------- 更新至2018.8.19 22.46 -----------------------------------------------------

对搭建的主从架构进行QPS压力测试;

进入 redis 安装目录的 src目录下;

执行 redis-benchmark -h IP -c n1 -n n2 -d n3 进行测试

-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 100000)
-d <size> Data size of SET/GET value in bytes (default 2)


本人机器测试如下:我们可以看到 在Get操作中 QPS 为 76863 相当于每秒1.7W的访问量,虚拟机的配置为1G内存单CPU,如果进行水平扩容2台,架构由一台master加三台slave,则支持7.6W*2 = 22W的QPS,当然在生产场景下,与访问的数据大小存在关系;



在主从架构中slave发生问题时,如果是一台slave出现问题,不会影响整个架构的运行,因为其他的slave会顶替该宕机的slave,但是如果master出现了宕机,就没有机器继续给

slave机器复制数据,所以这时候需要采用一种机制来实现高可用性;



如何实现缓存架构的高可用性【增加哨兵Node】;



经典的三点哨兵集群:【为什么最少是3个哨兵,因为只要quorum 和 majority 都满足的情况下才可以进行故障转移】

哨兵是redis集群架构中非常重要的一个组件,主要功能如下

(1)集群监控,负责监控redis master和slave进程是否正常工作
(2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
(3)故障转移,如果master node挂掉了,会自动转移到slave node上
(4)配置中心,如果故障转移发生了,通知client客户端新的master地址

哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作

(1)故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题
(2)即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了

哨兵的核心知识

(1)哨兵至少需要3个实例,来保证自己的健壮性
(2)哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性
(3)对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练



在master宕机以及脑裂的异常情况下的处理:

第一种情况:在client不断往master写入数据,在准备将数据异步拷贝给各个slave的时候,此时master宕机的情况下,哨兵会选举新的master,然后clinet就会向

新的master写入数据,此时原来的master里边原来写入的那块数据就丢失了;



第二种情况脑裂:

也就是master由于异常原因,独立出slave所在的网络,但是master可以继续工作,但此时哨兵检测到master的异常后,重新选出一个slave作为新的master,

此时的场景下存在了两个master,在新的master选举出来之前,然后client继续向原来的master写入数据,当选举新master完成后,原来的master恢复被被设置

为slave,此时旧的master缓存的数据就会被覆盖,导致数据丢失;



解决方案:

在redis的配置文件配置参数:

min-slaves-to-write 1
min-slaves-max-lag 10

要求至少有1个slave,数据复制和同步的延迟不能超过10秒

如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了

哨兵模式的虚拟机模拟配置 :

首先说一下这里有个坑爹的地方就是 坑了我三天才得以解决,就是哨兵在监视master 和 slave的时候,都需要配置密码,sentinel auth-pass mymaster redis-pass 这一步我配置的过程中漏掉了,导致哨兵

一直监视不了主从架构,所以在配置的过程中一定要加上;

基本配置:

哨兵默认用26379端口,默认不能跟其他机器在指定端口连通,只能在本地访问

mkdir /etc/sentinal
mkdir -p /var/sentinal/5000

/etc/sentinal/5000.conf

在5000.conf文件中进行配置:
port 5000
bind 192.168.1.108
dir /var/sentinal/5000
sentinel monitor mymaster 192.168.1.108 6379 2
sentinel down-after-milliseconds mymaster 30000 //超过多少毫秒跟一个redis实例断了连接,哨兵就可能认为这个redis实例挂了
sentinel failover-timeout mymaster 60000   //执行故障转移的timeout超时时长
sentinel parallel-syncs mymaster 1 //选举出新的master后 一次性把几个slave挂载上去
sentinel auth-pass mymaster redis-pass

port 5000
bind 192.168.1.109
dir /var/sentinal/5000
sentinel monitor mymaster 192.168.1.108 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster redis-pass

port 5000
bind 192.168.1.105
dir /var/sentinal/5000
sentinel monitor mymaster 192.168.1.108 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster redis-pass

3、启动哨兵进程 在eshop-cache01、eshop-cache02、eshop-cache03三台机器上,分别启动三个哨兵进程,组成一个集群,观察一下日志的输出
redis-sentinel /etc/sentinal/5000.conf
redis-server /etc/sentinal/5000.conf --sentinel
日志里会显示出来,每个哨兵都能去监控到对应的redis master,并能够自动发现对应的slave 哨兵之间,互相会自动进行发现,用的就是之前说的pub/sub,消息发布和订阅channel消息系统和机制

4、检查哨兵状态 redis-cli -h 192.168.1.108 -p 5000
sentinel master mymaster
SENTINEL slaves mymaster
SENTINEL sentinels mymaster

SENTINEL get-master-addr-by-name mymaster


配置成功后的运行截图:

master的哨兵信息:



Slave上的哨兵信息:



master的哨兵监视信息:



slave的监视信息:





模式master 宕机后的情景:

将master的端口关闭掉,或者直接关闭master虚拟机,



************************redis clustor 介绍 ***************************

简单的取模 hash函数实现:【严重的弊端,对机器的个数进行取模】



一致性hash算法:



对于一致性hash算法热点问题的改进:



redis slot的实现原理:

以前写的内容是master机器和slave机器分离,分别负责读写,但是到了 redis cluster之后,就不再读写分离,所有的读和写都是通过master进行的;

针对key进行hash slot运算找slot;





关于redis cluster的读写分离;



补充 redis cluster部分的内容

亿级流量商品详情页的缓存架构:



架构理解:

采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构

时效性要求非常高的数据:库存

一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存会不断的变化

当然,我们就希望当库存变化的时候,尽可能更快将库存显示到页面上去,而不是说等了很长时间,库存才反应到页面上去。

时效性要求不高的数据:时效性要求不高的数据:商品的基本信息(名称、颜色、版本、规格参数,等等)

商品价格/库存等时效性要求高的数据,而且种类较少,采取相关的服务系统每次发生了变更的时候,直接采取数据库和redis缓存双写的方案,这样缓存的时效性最高

商品基本信息等时效性不高的数据,而且种类繁多,来自多种不同的系统,采取MQ异步通知的方式,写一个数据生产服务,监听MQ消息,然后异步拉取服务的数据,更新tomcat jvm缓存+redis缓存

nginx+lua脚本做页面动态生成的工作,每次请求过来,优先从nginx本地缓存中提取各种数据,结合页面模板,生成需要的页面如果nginx本地缓存过期了,那么就从nginx到redis中去拉取数据,更新到nginx本地

如果redis中也被LRU算法清理掉了,那么就从nginx走http接口到后端的服务中拉取数据,数据生产服务中,现在本地tomcat里的jvm堆缓存中找,ehcache,如果也被LRU清理掉了,那么就重新发送请求到源头的服务中去拉取数据,然后再次更新tomcat堆内存缓存+redis缓存,并返回数据给nginx,nginx缓存到本地

2、多级缓存架构中每一层的意义

nginx本地缓存,抗的是热数据的高并发访问,一般来说,商品的购买总是有热点的,比如每天购买iphone、nike、海尔等知名品牌的东西的人,总是比较多的

这些热数据,利用nginx本地缓存,由于经常被访问,所以可以被锁定在nginx的本地缓存内

大量的热数据的访问,就是经常会访问的那些数据,就会被保留在nginx本地缓存内,那么对这些热数据的大量访问,就直接走nginx就可以了

那么大量的访问,直接就可以走到nginx就行了,不需要走后续的各种网络开销了

redis分布式大规模缓存,抗的是很高的离散访问,支撑海量的数据,高并发的访问,高可用的服务

redis缓存最大量的数据,最完整的数据和缓存,1T+数据; 支撑高并发的访问,QPS最高到几十万; 可用性,非常好,提供非常稳定的服务

nginx本地内存有限,也就能cache住部分热数据,除了各种iphone、nike等热数据,其他相对不那么热的数据,可能流量会经常走到redis那里

利用redis cluster的多master写入,横向扩容,1T+以上海量数据支持,几十万的读写QPS,99.99%高可用性,那么就可以抗住大量的离散访问请求

tomcat jvm堆内存缓存,主要是抗redis大规模灾难的,如果redis出现了大规模的宕机,导致nginx大量流量直接涌入数据生产服务,那么最后的tomcat堆内存缓存至少可以再抗一下,不至于让数据库直接裸奔

同时tomcat jvm堆内存缓存,也可以抗住redis没有cache住的最后那少量的部分缓存

传统的缓存读写模式:【不涉及到高并发的访问】





Redis和数据库双写不一致问题:

一:不优先删除缓存的情况下,写入数据后,如果再清空缓存如果出现问题,则此时会出现不一致问题;

先产缓存 在删除数据库



读写并发读写的时候可能出现下面这种双写不一致的问题:

在读并发很低的情况,很少的情况会出现这种双写不一致问题,如果每天商议的流量,则会可能出现不一致情况;



解决方案【建立串行写读队列】:



对读写串行队列需要考虑读的情况下,读的操作可能会hang的过久,需要根据业务场景进行测试;



---恢复内容结束---
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐