目录
基础知识
知识点:
redis默认16个数据库 默认选择0号库。
更换库:更换成7号库,select 7;
redis采取的是乐观锁。
keys命令 模糊查询
scan命令可以无阻塞的提取指定模式的key列表,不耽误线上服务运行
String字符串 最大的值能存储512M
Redis 可以使用主从同步,从从同步。
配置文件:
bind 127.0.0.1 支支持本地访问 注释掉
把 protected-mode yes 修改为no
上边两个配置修改完别人也可以访问
timeout 0 0是永不超时,可以设置时间,时间是秒为单位(多少秒以后断开连接)
tcp-keepalive 300 300s检测一次是否连接还存在 如果不存在就不提供服务了。
daemonize yes 可以后台启动,默认是no 下载redis第一把就是把他修改为yes
database 16 默认是16个库
redis默认没有密码。 设置数据库密码命令:config set requirepass "123456"
操作库命令:
select 8;(选择8号库)
dbsize 查看当前库的key数量
flushdb 清空当前库,只清空当前数据库的,不清空其他库
flushdball通杀全部库
keys * 查看当前库所有的key
set k1 zhangsan 设置键值对。
exists k1 返回1存在/0不存在
type k1 返回k1类型
del k1 删除key
expire k2 10 设置10秒后删除
ttl k2 查看k2还有多少秒过期 -1 永不过期 -2已过期
数据类型
-
字符串String
-
列表 List
-
集合 Set
-
哈希Hash
-
有序集合 zset
-
bitmaps 他本身不是一种数据类型 之际上就是字符串 但是可以对字符串的位进行操作
-
HyperLogLog
-
Geospatial
其中bitmaps、HyperLogLog、Geospatial是新数据类型
String类型
String 类型的value最大512M
append k1 abc 将abc追加到k1值的后边 返回总长度
strlen k1 得到k1的值的长度
setnx k2 v2 当键不存在才可设置成功
incr k1 key的值增加1 如果k1原来为空 则为1 只对数值操作
decr k2 key的值减少1 如果k1原来为空 则为-1 只对数值操作
incr k1 10 key的值增加10 如果k1原来为空 则为10 只对数值操作
decr k2 10 key的值减少10 如果k1原来为空 则为-10 只对数值操作
mset k1 v1 k2 v2 k3 v3 同时设置多个
mget k1 k2 k3 同时得到多个
msexnx k1 v1 k2 v2 k3 v3 当有一个失败则全部失败(原子性的特性)
set name lacky
setrange name 3 abc 得到 lacabcky 抵挡额位置之后设置
setex k1 10 v1 设置值同时设置过期时间(10)
getset name zhangsan 将新值换进去
字符串长度小于1M扩容都是加倍的 超过1M 扩容的时候都是每次增加1M 最大长度512M
List操作
字符串列表,按照插入顺序,可以添加到头部或者尾部,是双链表结构,对两端的操作性比较高。
单键多值
lpush k1 v1 v2 v3 左边插入多个值 结果是 v3 v2 v1这样的顺序
rpush k2 a bv c 右边插入多个值
lpop 左边吐出来一个
rpop 右边吐出来一个 值在键在,值光键亡
rpoplpush k1 k2 右边吐出来一个值插入到k2的左边
lrange k1 0 -1 取出来左边到所有
lindex key 3 按照索引搜索第三个值
llen k 获得列表长度
linsert
lrem
lset
set列表
和list区别
不能重复
string类型的无序集合
命令:
sadd k v1 v2
smembers k 取出该集合的所有值
sismember k v 判断集合是否含有这个v的值
scard k 返回元素的个数
srem k v1 v2 删除k中的v1和v2
spop k 随机吐出来一个值
等等命令
Hash操作
类似于Map 特别适合存储对象
key是id 值可以是 name:zhangsan age:14 sex:男
hset k name 张三 给key的name赋值为张三
hset k age 14
hset k sex 男
这时候 hget k sex 得到男
hget k name 得到张三
等等命令
zset
不会重复
和set非常相似 但是 zet有个评分机制 成员是唯一的 评分是重复的
zadd K1 100 K2 200....
事务等等命令
第一个客户端订阅频道 subscribe channel1
第二个频道发布 publish channel1 hello
第一个频道 直接就能看到
注意 发布的消息没有持久化
事务
概念和操作
概念
redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序执行。事务在执行的过程中,不会被其他的客户端发送来的命令请求所打断。
redis事务的主要作用就是串联多个命令防止别的命令插队。
操作
multi 类似于开始
命令1 命令2 命令3
exec 类似于结束 会执行那一连串命令
在组队过程中 discard命令可以放弃组队
第一种情况 组队的过程中,命令出错 然后到最后exec 里边的命令都不会成功
第二种情况 组队过程中命令不出错(比如设置字符串,然后增加1),执行exec的时候,成功的成功,失败的失败,互相不干扰。
冲突:
悲观锁:每次去拿数据的时候,拿到就上锁,然后用完就开锁。传统数据库就是这种 表锁,行锁,读表锁等。
乐观锁:操作的时候给原来的一个版本号,第二个去操作的时候检查版本号,如果不一致,不能继续去操作。redis就是采取这种的。
冲突解决方案:
watch key(监控key)
在执行multi之前,先执行watch key1 key2,可以监听一个或者多个key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。
第一个客户端 1.set balance 100
第一个客户端 2.watch balance
第二个客户端 3.watch balance
第一个客户端 4.multi
第二个客户端 5.multi
第一个客户端 4.incrby balance 20
第二个客户端 5.incrby balance 30
第一个客户端 6.exec 能执行成功
第二个客户端 7.exec 返回nil(没执行成功)
如果组队过程中失败,那么都失败。
如果组队成功,执行阶段有一个失败,后续的都照常执行成功。
特性:
- 单独的隔离操作
事务的所有命令都会序列化,按照顺序执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 - 没有隔离级别的概念
队列中的命令没有提交之前都不会被实际执行 - 不保证原子性
事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。
数据备份方式(3种)
RDB
默认的方式就是rdb
RDB:时间间隔将内存中的数据写入到磁盘 fork弄临时文件,同步完成,再将临时文件替换掉rdb
默认文件就是 dump.rdb 配置文件中能看到
stop-writes-on-bgsave-error 当redis无法写入磁盘的时候,直接关闭掉redis的写操作 默认yes
备份是如何执行的:
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化的过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对数据恢复的完整性不是特别敏感,那rdb方式比aof方式更加的高校。rdb的缺点是最后一次持久化的数据可能丢失。
优势:
- 适合大规模的数据恢复
- 对数据的完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
劣势 :
- fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑。
- redis在fork的时候还是比较消耗性能的。
- 在备份周期的时间内做一次备份,如果down掉,就会丢失最后一次快照后的所有修改。
AOF
以日志的形式来记录每个写的操作(增量保存),将redis所有的写的命令记录下来,只追加文件,但是不可以改写文件,redis启动之初会读取该文件重新构建数据。
优势:
- 1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
- 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
- AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))
劣势:
- AOF 文件比 RDB 文件大,且恢复速度慢。
- 数据集大的时候,比 rdb 启动效率低
RDB+AOF
两种方式同时使用 使用rdb的同时会用异步去追加到aof文件中
启动redis的时候去检查是否是混合,如果是混合模式,rdb和aof的都会去加载。
过期删除策略
-
定时删除
  在设置键的过期时间的同时,创建一个定时器 timer). 让定时器在键的过期时间来临时,立即执行对键的删除操作。
-
惰性删除
  放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
-
定期删除
  每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
缓存穿透
概念:
- 应用服务器压力变大了 大量请求过来找redis
- redis命中率低
- 一直查询数据库。
- redis没用到就叫穿透
缓存穿透是指查询一个缓存中和数据库中都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空。当用户使用这条不存在的数据疯狂发起查询请求的时候,对数据库造成的压力就非常大,甚至可能直接挂掉。
解决方案:
- 对空值(不管数据是否不存在),仍然把结果(null)进行缓存处理。对缓存时间进行5分钟失效
- 设置白名单 对bitmps数据类型设置白名单 对ip进行拦截
- 采用布隆过滤器
- 对redis进行实时监控
最终目的:
不让请求进入到服务器,从而造成服务器压力
缓存击穿
概念:
- 访问数据库的压力瞬时增加。
- redis里面没有出现大量key过期
- redis是正常运行,但是数据库崩溃
缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。
解决方案:

缓存雪崩
概念:
缓存雪崩是指当缓存中有大量的key在同一时刻过期,或者Redis直接宕机了,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。

解决方案:


分布式锁
问题描述:

image.png

image.png

解决方案:
服务中加 sex key uuid nx ex 10
这样 设置key的同时给他设置过期时间 他具有原子性
删除锁的时候 判断是自己的所,再删除但是如果自己设置的锁到期了,就删除错误。因此使用lua脚本保证原子性操作
lua脚本具有原子性操作。
数据淘汰策略
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
面试题
redis为什么那么快?
1.redis数据在内存中
2.单线程,不用上下文进行切换
3.渐进式rehash,缓存时间戳
怎么提高命中率?
1.提前加载
2.增加缓存的存储空间,提高缓存的数据提高命中率
3.调整缓存的数据类型
4.提升缓存的更新频次
如何保证高可用?
主从模式
概念:部署多台Redis节点,其中只有一台节点是主节点(master),其他的节点都是从节点(slave)。主从模式实现读写分离,只有master节点提供数据的事务性操作(增删改),slave节点只提供读操作。所有slave节点的数据都是从master节点同步过来的,结构图如下:

上图是一种简单的主从结构模式,它的slave节点都挂在master节点上,这样做的优点是slave节点与master节点的数据延迟较小。缺点是如果slave节点数量很多,master同步一次数据的时间花费较长。可以只在master节点下只挂载一个slave节点,其他节点挂载在这个salve节点上,数据同步经过传递完成,如下图所示。Redis和大部分中间件的主从模式中的数据同步都是由slave节点主动发起的,这样可以减少master的性能消耗。

高可用原理和优点:主从模式做到了数据冗余,数据拥有备份,当主节点发生故障时,可以选择一个slave节点继续提供服务(但是主从模式没有解决怎么选择slave节点作为master节点的方法,无法保证高可用)。
优点:实现读写分离,降低master节点的读数据压力,提高系统的性能。写操作交给master节点,读操作交给slave节点,提供多个副本。
配置简单,容易搭建。只需要在slave节点上维护master节点的地址信息就可实现。
缺点:当master节点宕机时,由于无法选择哪一个slave节点当master节点,无法保证高可用。
所有的写数据的压力都集中在master节点,没有解决master节点写的压力。
2.哨兵模式
在主从模式中,一旦master节点发生宕机,为了保证高可用,需要找一个slave节点作为新的master节点。谁来确定宕机,选择哪一个slave节点,这些问题都没有解决。哨兵(sentinal)模式则是为了解决这些问题而产生的,它用于对主从模式中每个节点进行监控,当出现故障时通过投票机制,选择新的master节点,并将所有的slave节点连接到master节点,架构如下图所示。

哨兵模式有三个作用:监控、通知和自动故障转移。
监控(Monitoring):不断地检查master和salve是否运行正常。master存活检测、master和slave运行情况检测。
通知(Notification):当被监控的某个节点出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障转移(Automatic failover):断开master与slave之间的连接,选取一个salve作为master,将其他slave连接到新的master,并告知客户端新的节点地址。
优点:哨兵机制,保证高可用。能够监控各个节点运行状况,进行自动故障转移。
缺点:
中心化集群实现方式,基于主从模式,切换节点时,会发生数据的丢失。
集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响master的性能。
数据写的操作都集中在master上,仍然没有解决master写数据的压力。
3.集群模式
哨兵模式基本已经实现了高可用,但是每个节点都存储相同的内容,很浪费内存。而且,哨兵模式没有解决master写数据的压力。为了解决这些问题,就有了集群模式,实现分布式存储,每个节点存储不同的内容。集群部署的方式能自动将数据进行分片,每个master上放一部分数据,提供了内置的高可用服务,即使某个master宕机了,服务还可以正常地提供,架构如下图所示:
集群模式中数据通过数据分片的方式被自动分割到不同的master节点上,每个Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽。数据在集群模式中是分开存储的,那么节点之间想要知道其他节点的状态信息,包括当前集群状态、集群中各节点负责的哈希槽、集群中各节点的master-slave状态、集群中各节点的存活状态等是通过建立TCP连接,使用gossip协议来进行集群信息传播。
故障判断方法:判断故障的逻辑其实与哨兵模式有点类似,在集群中,每个节点都会定期的向其他节点发送ping命令,通过有没有收到回复来判断其他节点是否已经下线。具体方法是采用半数选举机制,当A节点发现目标节点疑似下线,就会向集群中的其他节点散播消息,其他节点就会向目标节点发送命令,判断目标节点是否下线。如果集群中半数以上的节点都认为目标节点下线,就会对目标节点标记为下线,从而告诉其他节点,让目标节点在整个集群中都下线。
优点:
无中心结构,部署简单。所有的Redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
可扩展性,可扩展master节点,释放单个master的写数据压力,节点可动态添加或删除。
能够实现自动故障转移,节点之间通过gossip协议交换状态信息,用投票机制完成slave到master的角色转换。
原文链接:https://blog.csdn.net/weixin_44183721/article/details/126195582
文章详细介绍了Redis的基础知识,包括配置文件的修改、数据类型如String、List、Set、Hash和Zset的操作,以及事务的使用和冲突解决。还讨论了Redis的数据备份策略,包括RDB和AOF的优缺点,以及过期删除策略。此外,提到了缓存问题如穿透、击穿和雪崩的解决方案,并概述了Redis的主从模式、哨兵模式和集群模式以保证高可用性。
5737

被折叠的 条评论
为什么被折叠?



