狂神Redis笔记

Redis:

目录

Redis:

Redis 发布订阅

Redis主从复制:

哨兵模式

Redis缓存穿透和雪崩


 redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失.所以Redis提供了持久化功能 !

RDB (Redis DataBase)  什么是RDB? 

     在指定的时间间隔内将内存中的数据及快照写入磁盘,也就是Snapshot快照,它恢复时时将快照直接读到内存里,Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入一个临时文件中,待持久化结束了,再用这个临时文件替换上次持久化好的文件.整个过程中,主进程时不进行任何IO操作的.这就确保了极高的性能.如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常猛按,那RDB方式要比AOF方式更加高效.RDB的缺点时最后一次持久化后的数据可能丢失!

rdb保存的文件是dump.rdb

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin/yconfig" 
#如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据

优点 :

1,适合大规模的数据恢复 !

2,对数据的完整性要求不高 !

缺点:

1, 需要一定的时间间隔进程操作! 如果redis意外宕机了,那最后一次修改的数据就没有了!

2,fork进程的时候,会占用一定的内存空间

AOF(Append Only File)

     以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只可以追加文件不可以修改文件,redis启动之除会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

   默认市不开启的,我们需要手动进行配置!我们需要把appendonly no改为yes就开启了aof,重启,redis就可以生效了 ! 如果aof文件有错位,这时候redis是启动不起来的,就需要修复中国文件,redis给提供了一个工具 redis-check-aof --fix   如果文件正常,重启就可以恢复了

优点和缺点 !

appendonly no  #默认是不开启aof模式的,默认是使用rdb方式持久化,大部分所有情况下,rdb完全够用
appendfilename "appendonly.aof"  #持久化的文件的名字
# appendfsync always      #每秒修改都会sync消耗性能
appendfsync everysec      #每秒执行一次sync,可能会丢失之1秒的数据
# appendfsync no           # 不执行 sync ,这个时候操作系统自己同步数据,速度

重写规则说明

    aof默认就是文件无限追加,文件会越来越大 ! 如果aof文件大于64兆,太大了,fork一格新的进程来将我们的文件重新重写 !

优点 :

1,每次修改都会同步,文件的完整会更加好 !

2,每秒同步一次,可能会丢失一秒的数据

3,从不同步,效率最高的 !

缺点:

1,相对于数据文件来说,aof远远大于rdb ,修复速度也比rdb慢!

2,Aof运行效率也比rdb慢,所以我们redis默认的配置就是rdb持久化

拓展 :

1,RDB持久化方式能够在指定时间间隔内对你的数据进行快照存储

2,AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.

3,只做缓存,如果你希望你的数据在服务器运行的时候存在,你也可以不适用任何持久化==

4,同时开启两种持久化方式

1, 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始数据,因为在通常情况下AOF文件的体积不至于过大,文件保存的数据集要完整

2,RDB的数据不实时,同时使用两者时服务器重启也会找AOF文件,那要不要使用AOF文件呢?作者建议不要,因为RDB更适合用于备份数据(AOF在不断变换不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为一格万以的手段.

5,性能建议:

1,因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则

2,如果Enable AIOF,好处是在最恶劣的情况下也只会丢失不超过两秒的数据,启动脚本比1较简单,只load自己的AOF文件就可以了,代价一是带来了持久的IO,二是AOFrewrite 最后

将rewrite过程中产生的数据写到新文件造成的堵塞几乎是不可避免的,只要硬盘许可,应该尽量减少AOFrewrite的频率,AOF重写的基础大小默认64M太小了,可以设置到5G以上,默认超过原大小100%大小重写可以改到适当的数值.

3,如果不Enabl AOF ,仅靠Master-Slave Reollcation实现高可用也可以,能省掉一大笔IO,也减少rewirte时带来的系统波动,代价时如果Master/Slave同时当掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个微博就是这样的架构

Redis 发布订阅

通讯 队列 发送者 ===订阅者

通信 队列 发送者(pub/sub )是一种消息通信模式:发送者(pub发送消息),订阅者(sub)接受消息

.微信,微博,关注系统 !Redis客户端可以订阅任意数量的频道,

订阅/发布消息图 :第一个 :消息发送者, 第二个 :频道 第三种:消息订阅者 !

下图展示频道 channel1 ,以及订阅这个频道的三个客户端---client2,client5和client1之间的关系:

当有新消息通过PUBLISH命令发送给频道channel1时,这个消息就会呗发送给订阅它的三个客户端:

命令

这些命令被广泛用于`即时通讯应用,比如网络聊天室和实时广播,时时提醒等,

测试:订阅端

127.0.0.1:6379> SUBSCRIBE yan      #订阅一个频道  - yan
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yan"
3) (integer) 1
#等待读取推送信息
1) "message"     #消息
2) "yan"         #那个频道的消息
3) "666"         #消息的具体内容
1) "message"      #同上
2) "yan"          #同上
3) "hello,redis"     #消息的具体内容

测试:发布端

127.0.0.1:6379> publish yan 666   #发布者发布消息的频道和内容
(integer) 1
127.0.0.1:6379> publish yan hello,redis
(integer) 1

原理:

      Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅`机制 的底层实现,以此加深对Redis的理解.Redis通过PuBLISH,SUBSCRIBE和PSUBSCRIBE等命令实现发布和订阅功能.

微信:

    通过SUBSCRIBE命令订阅某个频道后,redis-server里维护了一个字典,字典的键就是一个个频道! 而字典的值则是一个链表,链表种保存了所有订阅这个channel的客户端, SUBSCRINBE命令的关键,就是将客户端添加到给定channel的订阅链表中.

      pub/Sub从字面意思理解就是发布(Publish) 与订阅(Subscribe),在redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息,这一功能最明显的用法就是用做试试消息系统,比如微信普通聊天,群聊等功能,

使用场景:

1,实时聊天系统!

2,事实聊天 !(频道当聊天室,将消息回显给所有人即可 !)

3,订阅 , 关注系统都是可以的 !

稍微复杂的场景就会使用 消息中间件 MQ()

Redis主从复制:

概念:主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器,前者称之为主节点(master/leader):数据的复制是单向的,只能由主节点到从节点,Master以写为主,Slave以读为主,

默认情况下,每台Redis服务器是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点,

主从复制的主要作用包括:

1,数据沉余:主从复制实现了数据的热备份,是持久化之外的一种数据沉余方式.

2,故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速故障恢复:实际上是一种服务的沉余.

3,负载均衡:在主从复制的基础上,陪喝读写分离,可以由从节点提供服务,(即写Redis数据时应用主节点,读redis数据时用的是从节点),分担服务器负载:尤其是在写少读多的场景下,通过通过多个从节点分担读负载,可以大大提高了Redis服务器的并发量,

4,高可用基石: (也就是集群)除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础.

一般来说,要将Redis运用于工程项目中,只使用一台Redis是不能的,原因如下

1,从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大:

2,从容量上说,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量256G,也不能将所有内存用作Redis存储内存,一般来说,单台redis最大使用内存不应该超过20G,电商网站上的商品,一般都是一次上传,无数次浏览的,说专业点就是读多写少.对于这种场景,我们可以使用如下这种架构:

主从复制,读写分离! 80%的操作都是在进行`读操作! 减缓服务器压力 ! 架构中经常使用 !一主二从,只要在公司,主从复制就是必须是要使用的,因为在真实的项目种不可能使用单机Redis

环境配置:只配置从库,不用配置主库 !

127.0.0.1:6379> info replication   #主从配置的信息
# Replication
role:master    #角色 master
connected_slaves:0      #没有从机
master_replid:e0d5237c661fc774a4e48c8ad6edbae97b24bc80
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

复制3个配置文件,然后修改对应的信息

1,端口

2,pid名字

3,log文件名字

4,dumo.rdb名字

修改完毕之后,启动3个Redis服务器,可以通过进程信息查看

一主二从

默认情况下,每台Redis服务器都是主节点:我们一般情况下只用配置从机就好了 !认老大 !一主(79) 二从(80,81)

Slaveof

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379   #认老大
OK
127.0.0.1:6380> info relication
127.0.0.1:6380> info replication
# Replication
role:slave          #当前角色是从机
master_host:127.0.0.1    #可以看到主机信息      
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:56
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3ef2b79e414a9fd8a5a8d16bb6c2e1a55239cc14
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:56

#在主机中查看
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1        #多了从机的配置
slave0:ip=127.0.0.1,port=6380,state=online,offset=98,lag=1 #多了从机配置
master_replid:3ef2b79e414a9fd8a5a8d16bb6c2e1a55239cc14
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98

如果两个都配置完了

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=602,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=602,lag=0
master_replid:3ef2b79e414a9fd8a5a8d16bb6c2e1a55239cc14
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:602
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:602

真实的主从配置应该在配置文件中配置,这样配置是永久的,我们这样使用命令配置是暂时的!

细节:

   主机可以写,从机不能写只能读! 主机中的所有信息和数据,都会自动被从机保存 !

主机:

从机:只能读,,,如果要写的时候,从机就会报错

测试:主机端开连接,从机依旧连接到主机的,但是没有写操作,这个时候,主机如果回来,从机依旧可以直接活动主机信息 !如果是使用的命令行,来配置的主从,这个时候如果重启了,就会变回主机!只要变回从机,立马就会变回从机,立马就会从主机中获得获取值!

复制原理 !

Slave 启动成功连接到master后会发送一个sync同步命令,Master接到命令,启动后台的存盘进程,同时收集所有接受到的用于修改数据的命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步.

全量复制: 而slave服务在接受到数据库文件数据后,将其存盘到内存中,

增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

但是只要是重新连接master,一次完全同步(全量复制)将被自动执行 !

我们的数据一定可以在从机中看到 !

层层链路:上一个M连接下一个S !

    这种方式也是主从复制,如果主机断开了,可以使用SLAVEOF(现在是手动选老大),哨兵出来后就可以 自动选老大 !SLAVEOF no one (执行完这个命令后即可设置自己当作主机),如果这个时候主机修复咯,那就需要重新配置

哨兵模式

(自动选举主机(老大)的模式)

概述:

     主从切换技术的方法是:当主服务器宕机后,需要手动把一台服务器切换为主服务器,这就需要人工干 预,会造成一段时间内服务不可用,更多时候,我们会考虑哨兵模式,Redis从2.8开始正式提供Sentinel(哨兵)架构来解决这个问题.

   哨兵模式能够监控后台主机是否故障,如果故障了根据投票数将从机转换为主机.哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是哦一个独立的进程,作为进程,他会独立运行其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行多个Redis实例.

这里哨兵有两个作用:

        通过发送命令,让Redis服务器返回监控运行状态,包括服务器和从服务器.当哨兵检测到master宕机,会自动将slave切换成master,通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换成主机.

      然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多哨兵进行监控,每个哨兵之间还会进行监控,这样就形成了多哨兵模式.

       假设主服务器宕机,哨兵1先检测到这个结果,系统并不会进行fallover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线,当后面的哨兵也检查到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行fallover(故障转移)操作.切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称之为客观下线

测试 !

现在的状态是一主二从 !

1,配置哨兵配置文件 ! sentinel.conf

                 #被监控的名称 host  port 1                   
sentinel monitor myredis 127.0.0.1 6379 1

    后面的这个数字1,代表主机挂了,slave投票看让谁代替主机,票数最多的,就会成为主机 !

    启动主机 ! redis-sentinel yconfig/sentinel.conf

哨兵日志 !

主机重新连接后也没有什么用,需要重新配置 !

主机回来咯,只能当哨兵选出来的主机的从机

如果主机此时回来,只能归并到新的主机下,当作从机,这就是哨兵模式的规则.

哨兵模式:

优点

1,哨兵集群,基于主从复制模式,所有的主从配置的优点,它都有

2,主从可以切换,故障可以转移,系统的可用性就会更好

3,哨兵模式就是主从复制的升级,手动到自动,更加健壮 !

缺点:

1,Redis 不好在线扩容,集群容量一旦到达上限,在线扩容就十分麻烦 !

2,实现哨兵模式的配置其实是很麻烦的,里面有很美多选择 !

哨兵模式的全部配置:

# Example sentinel.conf

#哨兵sentinel实例运行端口 26379    #如果有哨兵集群,还需要配置每一个哨兵端口
port 26379

#  哨兵sentinel的工作目录
dir /tmp

#哨兵sentinel监控的redis'主节点的ip  port
#master-name  可以自己命名的主节点名称 只能由字母A-Z 数字 0-9 这三个字符"._"组成.
#quorum  配置多少歌sentinel哨兵统一认为master主节点失联,那么这时客观上认为主节点失联
#sentinel monitor <master-name><ip>  <redis-port>  <quorum>
sentinel monitor mysaster 127.0.0.1 6379 2

#默认的延时操作
#指定多少毫秒之后,主节点没有响应哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒
#sentinel down-after-milliseconds mymaster 30000

#这个配置项指定了在发生failover主备切换时最多可以有多少歌slave同时对新的master进行同步,这个数字越小,就意味着越多的slave因为replication 而不可用.
可以通过这个值设置为 1 来保证每次只有一个slave 处于不能处理命令请求的状态
#sentinel paraller-syncs mymaster 1  #可以设置并行处理的东西

#故障转移的时间, failover-timeout 可以用在以下这些方面
#1,当一个sentinel对同一master两次failover之间的间隔时间.
#2,当一个slave从一个错误的master哪里同步数据开始计算时间,直到salave呗纠正为正确的master那里同步数据时.
#3,当想要取消一个failover所需要的时间,
进行fallover时,配置所有slaves指向新的master所需要的时间,不过,即使过了这个`超时,slaves依然会呗正确怕配置为指向master,但是就不按parallel-syncs所配置的规则来了]
#默认三分钟
#sentinel failover-timeout <master-name> <millseconds>
sentinel failover-timeout mymaster 180000 

Redis缓存穿透和雪崩

    Redis缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面.但同时他也带来了一些问题.其中最重要的问题是,数据的一致性问题,从严格意义上讲,,这个问题无解.如果对数据的一致性要求很高,就不能使用缓存,还有就是缓存穿透,缓存雪崩和缓存击穿.目前都有比较流行的解决方案.

缓存穿透 ()大面积查不到

概念:

缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询,发现也没有,于是本次查询失败.当用户很多的时候,缓存没有命中于是都去请求了持久层数据库,这会给持久层数据库造成很大压力,这个时候就会出现缓存穿透

解决方案:

布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力 :

概念:

缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询,发现也没有,于是本次查询失败.当用户很多的时候,缓存没有命中于是都去请求了持久层数据库,这会给持久层数据库造成很大压力,这个时候就会出现缓存穿透

解决方案:

布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力 :

缓存空对象

当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个国企时间,之后再访问中国数据将会从缓存中获取,保存了后端数据源 :

缓存击穿(缓存过期,量太大)

概述,缓存击穿和缓存穿透的区别,缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求持久层数据库,

当某个key在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,同时访问数据库来查询最新数据,并且回写缓存,会导致数据库瞬间压力过大.

解决方案 :

设置热点数据永不过期

从缓存层面来看,没有设置过期时间,所以会出现热点 key 过期后产生的问题.

加互斥锁 :

分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可.这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大.

缓存雪崩:

      缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。

解决方案:缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值