Redis学习笔记

Redis学习

常用的操作

1、对字符串string的操作

下表列出了常用的 redis 字符串命令

1 设置值 获取值
set ydlclass value
get ydlclass
2 mset mget 一次性操作多组数据
mset ydlclass value ydlclass1 value1 ydlclass2 value2
mget ydlclass ydlclass1 ydlclass2
3 没有这个键我们才设置
setnx dlclass value
4 将key的值 加一,减一
incr stock 
decr stock
5设置 a值存活时间5秒,值是b    验证码
setex a 5 b

2.对hash表的存储

  • 1设置值 获取值
    hset user username itlils
    hset user age 18
    hget user username
    2批量
    hmset user1 username itnanls age 19 
    3获取所有的键值对
    hgetall user
    4获取所有小key
    hkeys  user
    5获取所有值
    HVALS user
    6删除 
    hdel user age
    

3、对list列表的操作

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 2的32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

1 设置值
lpush list1 1 2 3 4 1
rpush list1 6
2查看数据
lrange list1 0 -1
3 移除数据
lpop list1
rpop list1

对set集合的操作

  • Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
  • Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
  • 集合中最大的成员数为 2的32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
1添加数据
sadd set1 1 2 3 4 5
2获取数据
smembers set1
3获取成员数量
scard set1
4业务 uv 当天登陆用户数
sadd uv:20220222 001 002 003 002
scard uv:20220222

5、对key的操作

下表给出了与 Redis 键相关的基本命令:

1删除
del user1
2查看所有的key  
keys *     生产环境下,别用
3存在key
exists user1
4存活时间
expire ydlclass 5
5剩余存活时间   登陆续期
pttl user1
6随机获取 key
randomkey

6、对ZSet的操作-重要(热搜)

  • Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员
  • 它用来保存需要排序的数据,例如排行榜,一个班的语文成绩,一个公司的员工工资,一个论坛的帖子等。
  • 有序集合中,每个元素都带有score(权重),以此来对元素进行排序
  • 它有三个元素:key、member和score。以语文成绩为例,key是考试名称(期中考试、期末考试等),member是学生名字,score是成绩。
    • 互联网,微博热搜,最热新闻,统计网站pv
1添加
zadd pv 100 page1.html 200 page2.html 300 page3.html
2查看
zcard pv
3查询指定权重范围的成员数
ZCOUNT pv 150 500
4增加权重
ZINCRBY pv 1 page1.html
5交集
ZADD pv_zset1 10 page1.html 20  page2.html
ZADD pv_zset2 5 page1.html 10  page2.html
ZINTERSTORE pv_zset_result 2 pv_zset1  pv_zset2
6成员的分数值
ZSCORE pv_zset page3.html   
7 获取下标范围内的成员。 排序,默认权重由低到高
ZRANGE pv 0 -1
8获取由高到低的几个成员(reverse)使用最多的
效率很高,因为本身zset就是排好序的。
ZREVRANGE key start stop

1、RDB持久化方案

#1.1 介绍

Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。

image-20220301090011542

可以在配置文件中配置Redis进行快照保存的时机:

save [seconds] [changes]  

1

意为在seconds秒内如果发生了changes次数据修改,则进行一次RDB快照保存,例如

save  60 100
save  600 500

1
2

会让Redis每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。可以配置多条save指令,让Redis执行多级的快照保存策略。Redis默认开启RDB快照。也可以通过SAVE或者BGSAVE命令手动触发RDB快照保存。SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:

  • SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
  • BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。

1.2 RDB方案优点

  1. 对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
  2. 每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。
  3. 使用RDB文件进行数据恢复比使用AOF要快很多。

1.3 RDB方案缺点

  1. 快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据
  2. 如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力

1.4 RDB配置

  1. 修改redis的配置文件
cd  
/export/server/redis-6.2.6/  
vim  redis.conf  
# 第 行  
save  900 1  
save  300 10  
save  60 10000  
save 5 1  

这三个选项是redis的配置文件默认自带的存储机制。表示每隔多少秒,有多少个key发生变化就生成一份dump.rdb文件,作为redis的快照文件

例如:save 60 10000 表示在60秒内,有10000个key发生变化,就会生成一份redis的快照

  1. 重新启动redis服务

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

 ps -ef | grep redis  
 bin/redis-cli -h 192.168.200.131 shutdown  
 bin/redis-server redis.conf 

AOF持久化

每次请求都保存请求到日志当中。在redis重启时会把这个日志文件执行

随着AOF不断地记录写操作日志,因为所有的写操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。

2.5 AOF优点

  1. 最安全,在启用appendfsync为always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据
  2. AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复
  3. AOF文件易读,可修改,在进行某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。

#2.6 AOF的缺点

  1. AOF文件通常比RDB文件更大
  2. 性能消耗比RDB高
  3. 数据恢复速度比RDB慢

Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:

  • AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
  • AOF + fsync every second是比较好的折中方案,每秒fsync一次
  • AOF + fsync never会提供AOF持久化方案下的最优性能

使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置

Redis事务

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

image-20220301144547489

总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令

  • Redis事务没有隔离级别的概念

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

  • Redis不保证原子性

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

一个事务从开始到执行会经历以下三个阶段:

  • 第一阶段:开始事务
  • 第二阶段:命令入队
  • 第三阶段:执行事务

Redis事务相关命令:

  • MULTI

开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令队列

  • EXEC

执行事务中的所有操作命令

  • DISCARD

取消事务,放弃执行事务块中的所有命令

  • WATCH

监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令

  • UNWATCH

取消WATCH对所有key的监视

#2、 Redis事务演示

1. MULTI开始一个事务:给k1、k2分别赋值,在事务中修改k1、k2,执行事务后,查看k1、k2值都被修改。

192.168.200.131:6379> set key1 v1
OK
192.168.200.131:6379> set key2 v2
OK
192.168.200.131:6379> multi
OK
192.168.200.131:6379(TX)> set key1 11
QUEUED
192.168.200.131:6379(TX)> set key2 22
QUEUED
192.168.200.131:6379(TX)> exec
1) OK
2) OK
192.168.200.131:6379> get key1
"11"
192.168.200.131:6379> get key2
"22"
192.168.200.131:6379> 

2. 事务失败处理:语法错误(编译器错误),在开启事务后,修改k1值为11,k2值为22,但k2语法错误,最终导致事务提交失败,k1、k2保留原值。

192.168.200.131:6379> set key1 v1
OK
192.168.200.131:6379> set key2 v2
OK
192.168.200.131:6379> multi
OK
192.168.200.131:6379(TX)> set key1 11
QUEUED
192.168.200.131:6379(TX)> sets key2 22
(error) ERR unknown command `sets`, with args beginning with: `key2`, `22`, 
192.168.200.131:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
192.168.200.131:6379> get key1
"v1"
192.168.200.131:6379> get key2
"v2"
192.168.200.131:6379> 

3.Redis类型错误(运行时错误),在开启事务后,修改k1值为11,k2值为22,但将k2的类型作为List,在运行时检测类型错误,最终导致事务提交失败,此时事务并没有回滚,而是跳过错误命令继续执行, 结果k1值改变、k2保留原值。

1.2 主从复制概念

知道了三高的概念之后,我们想:你的“Redis”是否高可用?那我们要来分析单机redis的风险与问题

问题1.机器故障

  • 现象:硬盘故障、系统崩溃
  • 本质:数据丢失,很可能对业务造成灾难性打击
  • 结论:基本上会放弃使用redis.

问题2.容量瓶颈

  • 现象:内存不足,从16G升级到64G,从64G升级到128G,无限升级内存
  • 本质:穷,硬件条件跟不上
  • 结论:放弃使用redis

结论:

为了避免单点Redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起,并保证数据是同步的。即使有其中一台服务器宕机,其他服务器依然可以继续提供服务,实现Redis的高可用,同时实现数据冗余备份。

多台服务器连接方案:

image-20220301173728213

  • 提供数据方:master

主服务器,主节点,主库主客户端

  • 接收数据方:slave

从服务器,从节点,从库

从客户端

  • 需要解决的问题:

数据同步(master的数据复制到slave中)

这里我们可以来解释主从复制的概念:

概念:主从复制即将master中的数据即时、有效的复制到slave中

特征:一个master可以拥有多个slave,一个slave只对应一个master

职责:master和slave各自的职责不一样

master:

写数据
执行写操作时,将出现变化的数据自动同步到slave
读数据(可忽略)

slave:

读数据
写数据(禁止)

image-20220301173950207

1.3 主从复制的作用

  • 读写分离:master写、slave读,提高服务器的读写负载能力
  • 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数 量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
  • 故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
  • 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
  • 高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

2、主从复制工作流程

主从复制过程大体可以分为3个阶段

  • 建立连接阶段(即准备阶段)
  • 数据同步阶段
  • 命令传播阶段(反复同步)

image-20220301175309628

而命令的传播其实有4种,分别如下:

image-20220301175429148

posted @ 2023-01-05 10:00  Z_WINTER  阅读(41)  评论(0)    收藏  举报