学习 redis的持久化

目录

1. redis应用场景

2. redis的持久化

(1)什么时候会触发RDB模式

 (2) save和bgsave的区别

4.3 rdb数据恢复

4.4 AOF持久化

4.5 RDB和AOF的优缺点

5. redis得集群

5.1 为什么要使用redis集群

5.2 第一种集群方式--主从模式

5.3 第二种集群模式---哨兵模式

5.4 第三种模式---集群模式


1. redis应用场景


1. 缓存
作为Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单,只需要通过string类型将序列化后的对象存起来即可,不过也有一些需要注意的地方:

必须保证不同对象的 key 不会重复,并且使 key 尽量短,一般使用类名(表名)加主键拼接而成。

选择一个优秀的序列化方式也很重要,目的是提高序列化的效率和减少内存占用。

缓存内容与数据库的一致性,这里一般有两种做法:

只在数据库查询后将对象放入缓存,如果对象发生了修改或删除操作,直接清除对应缓存(或设为过期)。
在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存(或设为过期)。
2. 数据共享分布式
String 类型,因为 Redis 是分布式的独立服务,可以在多个应用之间共享

例如:分布式Session

<dependency> 
 <groupId>org.springframework.session</groupId> 
 <artifactId>spring-session-data-redis</artifactId> 
</dependency>

3、分布式锁
如今都是分布式的环境下java自带的单体锁已经不适用的。在 Redis 2.6.12 版本开始,string的set命令增加了一些参数:

EX:设置键的过期时间(单位为秒)

PX:设置键的过期时间(单位为毫秒)

NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。

XX :只在键已经存在时,才对键进行设置操作。

由于这个操作是原子性的,可以简单地以此实现一个分布式的锁,例如:

  set lock_key locked NX EX 1 
1
如果这个操作返回false,说明 key 的添加不成功,也就是当前有人在占用这把锁。而如果返回true,则说明得了锁,便可以继续进行操作,并且在操作后通过del命令释放掉锁。并且即使程序因为某些原因并没有释放锁,由于设置了过期时间,该锁也会在 1 秒后自动释放,不会影响到其他程序的运行。
  
推荐使用 redisson 第三方库实现分布式锁。
参考 java分布式锁终极解决方案之 redisson

4、全局ID
int类型,incrby,利用原子性

incrby userid 1000

分库分表的场景,一次性拿一段

5、计数器
int类型,incr方法

例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库

计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中,string、hash和sorted set都提供了incr方法用于原子性的自增操作,下面举例说明一下它们各自的使用场景:

如果应用需要显示每天的注册用户数,便可以使用string作为计数器,设定一个名为REGISTERED_COUNT_TODAY的 key,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用incr命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。
每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用hash进行计数会更好,将该计数器的 key 设为weibo:weibo_id,hash的 field 为like_number、comment_number、forward_number和view_number,在对应操作后通过hincrby使hash 中的 field 自增。
如果应用有一个发帖排行榜的功能,便选择sorted set吧,将集合的 key 设为POST_RANK。当用户发帖后,使用zincrby将该用户 id 的 score 增长 1。sorted set会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。
6、限流
int类型,incr方法

以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false

7、位统计
String类型的bitcount(1.6.6的bitmap数据结构介绍)

字符是以8位二进制存储的

set k1 a
setbit k1 6 1
setbit k1 7 0
get k1 
/* 6 7 代表的a的二进制位的修改
a 对应的ASCII码是97,转换为二进制数据是01100001
b 对应的ASCII码是98,转换为二进制数据是01100010

因为bit非常节省空间(1 MB=8388608 bit),可以用来做大数据量的统计。
参考 使用Redis的bitmaps统计用户留存率、活跃用户

用户日活月活怎么统计 - Redis HyperLogLog 详解

8. 时间轴(Timeline)
  list作为双向链表,不光可以作为队列使用。如果将它用作栈便可以成为一个公用的时间轴。当用户发完微博后,都通过lpush将它存放在一个 key 为LATEST_WEIBO的list中,之后便可以通过lrange取出当前最新的微博。

9. 消息队列
Redis 中list的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过lpush将消息放入 list,消费者便可以通过rpop取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择sorted set。而pub/sub功能也可以用作发布者 / 订阅者模型的消息。无论使用何种方式,由于 Redis 拥有持久化功能,也不需要担心由于服务器故障导致消息丢失的情况。

List提供了两个阻塞的弹出操作:blpop/brpop,可以设置超时时间

blpop:blpop key1 timeout 移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
brpop:brpop key1 timeout 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
上面的操作。其实就是java的阻塞队列。学习的东西越多。学习成本越低

队列:先进先除:rpush blpop,左头右尾,右边进入队列,左边出队列
栈:先进后出:rpush brpop
10、抽奖
利用set结构的无序性,通过 Spop( Redis Spop 命令用于移除集合中的指定 key 的一个或多个随机元素,移除后会返回移除的元素。 ) 随机获得值


11、点赞、签到、打卡
假如上面的微博ID是t1001,用户ID是u3001

用 like:t1001 来维护 t1001 这条微博的所有点赞用户

点赞了这条微博:sadd like:t1001 u3001
取消点赞:srem like:t1001 u3001
是否点赞:sismember like:t1001 u3001
点赞的所有用户:smembers like:t1001
点赞数:scard like:t1001
是不是比数据库简单多了。

12 商品标签
老规矩,用 tags:i5001 来维护商品所有的标签。

sadd tags:i5001 画面清晰细腻
sadd tags:i5001 真彩清晰显示屏
sadd tags:i5001 流程至极
13、好友关系、用户关注、推荐模型
这个场景最开始是是一篇介绍微博 Redis 应用的 PPT 中看到的,其中提到微博的 Redis 主要是用在在计数和好友关系两方面上,当时对好友关系方面的用法不太了解,后来看到《Redis 设计与实现》中介绍到作者最开始去使用 Redis 便是希望能通过set解决传统数据库无法快速计算集合中交集这个功能。后来联想到微博当前的业务场景,确实能够以这种方式实现,所以姑且猜测一下:

对于一个用户 A,将它的关注和粉丝的用户 id 都存放在两个 set 中:

A:follow:存放 A 所有关注的用户 id

A:follower:存放 A 所有粉丝的用户 id

那么通过sinter命令便可以根据A:follow和A:follower的交集得到与 A 互相关注的用户。当 A 进入另一个用户 B 的主页后,A:follow和B:follow的交集便是 A 和 B 的共同专注,A:follow和B:follower的交集便是 A 关注的人也关注了 B。

举例
follow 关注 fans 粉丝

相互关注:

sadd 1:follow 2
sadd 2:fans 1
sadd 1:fans 2
sadd 2:follow 1
我关注的人也关注了他(取交集):

sinter 1:follow 2:fans
可能认识的人:

用户1可能认识的人(差集):sdiff 2:follow 1:follow
用户2可能认识的人:sdiff 1:follow 2:follow
14 .排行榜
使用sorted set(有序set)和一个计算热度的算法便可以轻松打造一个热度排行榜,zrevrangebyscore可以得到以分数倒序排列的序列,zrank可以得到一个成员在该排行榜的位置(是分数正序排列时的位置,如果要获取倒序排列时的位置需要用zcard-zrank)。

id 为6001 的新闻点击数加1:

zincrby hotNews:20190926 1 n6001
1
获取今天点击最多的15条:

zrevrange hotNews:20190926 0 15 withscores
1
15 .倒排索引
倒排索引是构造搜索功能的最常见方式,在 Redis 中也可以通过set进行建立倒排索引,这里以简单的拼音 + 前缀搜索城市功能举例:

假设一个城市北京,通过拼音词库将北京转为beijing,再通过前缀分词将这两个词分为若干个前缀索引,有:北、北京、b、be…beijin和beijing。将这些索引分别作为set的 key(例如:index:北)并存储北京的 id,倒排索引便建立好了。接下来只需要在搜索时通过关键词取出对应的set并得到其中的 id 即可。

16 .显示最新的项目列表
比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。

每次新评论发表时,我们会将它的ID添加到一个Redis列表。可以限定列表的长度为5000

LPUSH latest.comments

在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在超出了这个范围的时候,才需要去访问数据库。
 


2. redis的持久化


(1)什么时候会触发RDB模式

三种方式: save bgsave 通过配置文件

1、执行save命令

客户端可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令

 2、执行bgsave命令

客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会调用fork来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。

这个命令执行后会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响。

 (2) save和bgsave的区别

save模式

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。

 bgsave模式

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


自动触发

需要指定配置文件---一般不建议改---采用默认值----底层自动执行bgsave命令

4.3 rdb数据恢复

只需要把dump.rbd文件放入按照目录,当redis服务启动时,会读取dump.rdb文件 并加载到内存中。

4.4 AOF持久化

它会把每个写命令通过write函数记录到日志文件中。默认改持久化没有开启。需要修改配置文件来开启aof模式。

4.5 RDB和AOF的优缺点

rdb的优点:1、体积更小;2、恢复更快;3、性能更高。

rdb的缺点:1、故障丢失;2、耐久性差。

aof的优点:1、数据保证;2、自动缩小。

aof的缺点:1、性能相对较差;2、体积相对更大;3、恢复速度更慢。其中,rdb体积更小是指相同的数据量rdb数据比aof的小,因为rdb是紧凑型文件。


5. redis得集群

5.1 为什么要使用redis集群

1.可以减少单机的压力,解决单机故障问题。

5.2 第一种集群方式--主从模式

配置主从模式---配从不配主。

启动三台redis服务.依靠端口号:6380主节点 6381从节点 6382从节点

(1)复制三个redis配置文件放入master-slave目录

 (2)修改三个文件的配置

 (4)三台客户端访问redis相应的服务器

启动命令

redis-cli -p 6380

redis-cli -p 6381

redis-cli -p 6382

(5)查看redis的角色

info replication

 

 我们看出他们之间没有主从关系

(6)配置主从关系---从节点

slaveof 主节点ip 主节点port

                        

 

 (7) 往主节点添加数据

如果主节点挂掉--从节点是否可以上位。---不会。

如果新增一个小弟--该小弟是否可以把之前的数据同步过来。----可以

小弟是否可以进行写操作------只负责读操作不能负责写操作

主节点是否可以进行写操作和读操作。-----> 可以负责读写操作。

5.3 第二种集群模式---哨兵模式

上面的主从模式的缺点:----如果主节点宕机后,从节点无法上位,该redis服务就无法执行写操作了。----哨兵模式。

 开启哨兵服务

redis-sentinel sentinel.conf

 演示: 挂掉主节点

6380客户端 shutdown

 如果原来的主节点回来---它需要跟在现在的主节点混。


5.4 第三种模式---集群模式

哨兵模式的缺点: 它只有一个主节点---如果现在写操作并发高,那么还会导致主节点压力过大。

去中心化---

 准备: 6台redis服务。---6个服务中不能有数据。

7001=====主节点

7002

7003=====主节点

7004

7005

7006=====从节点

修改配置文件: 都需要改

bind 0.0.0.0 

port 7001

daemonize yes

# 打开aof 持久化

appendonly yes

 # 开启集群 

cluster-enabled yes

# 集群的配置文件,该文件自动生成

cluster-config-file nodes-7001.conf  

 # 集群的超时时间

cluster-node-timeout 5000

开启上面6台redis服务器

 为6台redis配置槽以及主从关系

redis-cli --cluster create --cluster-replicas 1 192.168.86.128:7001 192.168.86.128:7002 192.168.223.166:7003 192.168.223.166:7004 192.168.223.166:7005 192.168.86.128:7006

 -- --cluster-replicas 1: 从节点的个数

 

 开始成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值