Redis整理

Redis整理

1. Redis数据类型,特性,使用场景
1)string
1. set key value
2. get key
取值赋值
3. getset key value
数字
4. incr key
加number
5. incrby key number
6. decr key
7. decrby key number
不存在添加并赋值
8. setnx key value
9. append key value
10. strlen key
11. mset
12.mget

自增主键

2)hash
1. hset key field value
2. hmset key field value [field value ...]
3. hsetnx key field value
4. hget key field
5. hmget key field [field ...]
6. hgetall key
7. hdel key field

hash类型适合存储那些对象数据,特别是对象属性经常发生【增删改】操作的数据。 string类型也可以存储对象数据,将java对象转成json字符串进行存储,这种存储适合【查询】操作。

3)list

​ 双向链表

lpush key value
rpush key value
lrange key start stop
lpop key
rpop key
llen key
LREM 命令会删除列表中前 count 个值为 value 的元素,返回实际删除的元素个数
lrem key count value
lindex key index

储存有序的数据,例如:评论列表

4)set

​ set 类型即集合类型,其中的数据是不重复且没有顺序

sadd key member
srem key member
获取所有元素
smembers key
sismember key member

集合运算
集合的差集运算
sdiff key1 key2
交集运算
sinter key1 key2
并集
sunion key1 key2
5)zset (sortedset)

​ 在 set 集合类型的基础上,有序集合类型为集合中的每个元素都 关联一个分数 ,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。

zadd key score member
zrange key start stop
zsocre key member
zrem key member

排行榜

2.redis集群相关

Redis保证集群高可用?

1) 主从复制

Redis 的主从同步,分为全量同步和增量同步。

只有从机第⼀次连接上主机是全量同步。

断线重连有可能触发全量同步也有可能是增量同步( master 判断 runid 是否⼀致)

  • 全量同步

    • 同步快照阶段: Master 创建并发送快照RDB给 Slave , Slave 载⼊并解析快照。 Master 同时将此阶段所产⽣的新的写命令存储到缓冲区。
    • 同步写缓冲阶段: Master 向 Slave 同步存储在缓冲区的写操作命令。
    • 同步增量阶段: Master 向 Slave 同步写操作命令。
  • 增量同步

    • Redis 增量同步主要指 Slave 完成初始化后开始正常⼯作时, Master 发⽣的写操作同步到 Slave的过程。
    • 通常情况下, Master 每执⾏⼀个写命令就会向 Slave 发送相同的写命令,然后 Slave 接收并执⾏。
2)哨兵模式

​ Redis 主从复制的缺点:没有办法对 master 进⾏动态选举(master宕机后,需要重新选举master),需要使⽤ Sentinel机制完成动态选举。

​ Sentinel (哨兵)进程是⽤于监控 Redis 集群中 Master主服务器⼯作的状态在 Master 主服务器发⽣故障的时候,可以实现 Master 和 Slave 服务器的切换,保证系统的⾼可⽤( HA )。

作用:

  • 监控( Monitoring ):哨兵( sentinel ) 会不断地检查你的 Master 和 Slave 是否运作正常。

  • 提醒( Notification ): 当被监控的某个 Redis 节点出现问题时, 哨兵( sentinel ) 可以通过 API 向管理员或者其他应⽤程序发送通知。

  • ⾃动故障迁移( Automatic failover ):当⼀个 Master 不能正常⼯作时,哨兵( sentinel ) 会开始⼀次⾃动故障迁移操作。

    故障判定:

    1. 每个 Sentinel (哨兵)进程以每秒钟⼀次的频率向整个集群中的 Master 主服务器, Slave 从服务器以及其他 Sentinel (哨兵)进程发送⼀个 PING 命令。

    2. 如果⼀个实例( instance )距离最后⼀次有效回复 PING 命令的时间超过 down-aftermilliseconds 项所指定的值, 则这个实例会被 Sentinel (哨兵)进程标记为主观下线( SDOWN )。

    3. 如果⼀个 Master 主服务器被标记为主观下线( SDOWN ),则正在监视这个 Master 主服务器的所有 Sentinel (哨兵)进程要以每秒⼀次的频率确认 Master 主服务器的确进⼊了主观下线状态。

    4. 当有⾜够数量的 Sentinel (哨兵)进程(⼤于等于配置⽂件指定的值)在指定的时间范围内确认Master 主服务器进⼊了主观下线状态( SDOWN ), 则 Master 主服务器会被标记为客观下线( ODOWN )。

    5. 在⼀般情况下, 每个 Sentinel (哨兵)进程会以每 10 秒⼀次的频率向集群中的所有 Master 主服务器、 Slave 从服务器发送 INFO 命令。

    6. 当 Master 主服务器被 Sentinel (哨兵)进程标记为客观下线( ODOWN )时, Sentinel (哨兵)进程向下线的 Master 主服务器的所有 Slave 从服务器发送 INFO 命令的频率会从 10 秒⼀次改为每秒⼀次。

    7. 若没有⾜够数量的 Sentinel (哨兵)进程同意 Master 主服务器下线, Master 主服务器的客观下线状态就会被移除。若 Master 主服务器重新向 Sentinel (哨兵)进程发送 PING 命令返回有效回复, Master 主服务器的主观下线状态就会被移除。

      故障迁移:

    8. 它会将失效 Master 的其中⼀个 Slave 升级为新的 Master , 并让失效 Master 的其他 Slave 改为复制新的 Master ;

    9. 当客户端试图连接失效的 Master 时,集群也会向客户端返回新 Master 的地址,使得集群可以使⽤现在的 Master 替换失效 Master 。

    10. Master 和 Slave 服务器切换后, Master 的 redis.conf 、 Slave 的 redis.conf 和sentinel.conf 的配置⽂件的内容都会发⽣相应的改变,即, Master 主服务器的 redis.conf配置⽂件中会多⼀⾏ slaveof 的配置, sentinel.conf 的监控⽬标会随之调换。

3)Redis-Cluster

​ 如果我们读多写少 并发量⼤ 数据只有2G 100W读 主从+哨兵

​ 如果并发写多 数据量⼤ 40G数据,10W并发 Rediscluster

3. Redis持久化
1)RDB

​ RDB⽅式是通过快照( snapshotting )完成的,当符合⼀定条件时Redis会⾃动将内存中的数据进⾏快
照并持久化到硬盘。

​ 1. Redis 在进⾏快照的过程中不会修改 RDB ⽂件,只有快照操作结束后才会将旧的⽂件替换成新的,也就是说任何时候 RDB ⽂件都是完整的。

  1. 我们可以通过定时备份 RDB ⽂件来实现 Redis 数据库的备份, RDB ⽂件是 经过压缩的⼆进制⽂件 ,占⽤的空间会⼩于内存中的数据,更加利于传输。

​ ① 优缺点

缺点:使⽤ RDB ⽅式实现持久化,⼀旦 Redis 异常退出,就会丢失最后⼀次快照以后更改的所有数据。这个时候我们就需要根据具体的应⽤场景,通过组合设置⾃动快照条件的⽅式来将可能发⽣的数据损失控制在能够接受范围。如果数据相对来说⽐较重要,希望将损失降到最⼩,则可以使⽤ AOF ⽅式进⾏持久化

优点: RDB 可以最⼤化 Redis 的性能:⽗进程在保存 RDB ⽂件时唯⼀要做的就是 fork 出⼀个⼦进程,然后这个⼦进程就会处理接下来的所有保存⼯作,⽗进程⽆需执⾏任何磁盘 I/O 操作。同时这个也是⼀个缺点,如果数据集⽐较⼤的时候, fork 可以能⽐较耗时,造成服务器在⼀段时间内停⽌处理客户端的请求;

​ ② 触发时机

  1. 符合⾃定义配置的快照规则 redis.conf

    save “” : 不使⽤RDB存储

    save 900 1 : 表示15分钟(900秒钟)内⾄少1个键被更改则进⾏快照。

    save 300 10 : 表示5分钟(300秒)内⾄少10个键被更改则进⾏快照。

    save 60 10000 :表示1分钟内⾄少10000个键被更改则进⾏快照。

  2. 执⾏save或者bgsave命令

  3. 执⾏flushall命令

  4. 执⾏主从复制操作 (第⼀次)

2)AOF

​ 开启 AOF 持久化后,每执⾏⼀条会更改 Redis 中的数据的命令, Redis 就会将该命令写⼊硬盘中的AOF ⽂件,这⼀过程显然会降低 Redis 的性能,但⼤部分情况下这个影响是能够接受的,另外使⽤较快的硬盘可以提⾼ AOF 的性能。

​ AOF ⽂件有序地保存了对数据库执⾏的所有写⼊操作, 这些写⼊操作以 Redis 协议(RESP)的格式保存, 因此 AOF ⽂件的内容⾮常容易被⼈读懂, 对⽂件进⾏分析( parse )也很轻松。

​ Redis 在创建新 AOF ⽂件的过程中,会继续将命令追加到现有的 AOF ⽂件⾥⾯,即使重写过程中发⽣停机,现有的 AOF ⽂件也不会丢失。 ⽽⼀旦新 AOF ⽂件创建完毕, Redis 就会从旧 AOF ⽂件切换到新 AOF ⽂件,并开始对新 AOF ⽂件进⾏追加操作。

配置:

# 可以通过修改redis.conf配置⽂件中的appendonly参数开启
appendonly yes 
# AOF⽂件的保存位置和RDB⽂件的位置相同,都是通过dir参数设置的。
dir ./ 
# 默认的⽂件名是appendonly.aof,可以通过appendfilename参数修改
appendfilename appendonly.aof
# 每次执⾏写⼊都会进⾏同步, 这个是最安全但是是效率⽐较低的⽅式
appendfsync always 
# 每⼀秒执⾏(默认)
appendfsync everysec 
# 不主动进⾏同步操作,由操作系统去执⾏,这个是最快但是最不安全的⽅式
appendfsync no
# 表示当前aof⽂件⼤⼩超过上⼀次aof⽂件⼤⼩的百分之多少的时候会进⾏重写。如果之前没有重写过,
以启动时aof⽂件⼤⼩为准
auto-aof-rewrite-percentage 100
# 限制允许重写最⼩aof⽂件⼤⼩,也就是⽂件⼤⼩⼩于64mb的时候,不需要进⾏优化
auto-aof-rewrite-min-size 64mb
3)如何选择持久化方式
  • ⼀般来说,如果对数据的安全性要求⾮常⾼的话,应该同时使⽤两种持久化功能。如果可以承受数分钟以内的数据丢失,那么可以只使⽤ RDB 持久化。

  • 混合持久化方式

    混合持久化是结合了 RDB 和 AOF 的优点,在写⼊的时候,先把当前的数据以 RDB 的形式写⼊⽂件的开头,再将后续的操作命令以 AOF 的格式存⼊⽂件,这样既能保证 Redis 重启时的速度,⼜能减低数据丢失的⻛险。

    开启混合持久化
    aof-use-rdb-preamble yes
    
4. Redis的内存淘汰机制

设置最⼤缓存在

redis 中,允许⽤户设置最⼤使⽤内存⼤⼩maxmemory,默认为0,没有指定最⼤缓存,如果有新的数据添加,超过最⼤内存,则会使redis崩溃,所以⼀定要设置。

淘汰策略

redis淘汰策略配置:maxmemory-policy voltile-lru,⽀持热配置。

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使⽤的数据淘汰

  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使⽤的数据淘汰

  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  6. no-enviction(驱逐):禁⽌驱逐数据

1)LRU

​ Least recently used,最近最少使⽤。

2)LFU

​ Least Frequently Used,最不经常使用。

5. Redis事务

​ 在⽣产环境⾥,经常会利⽤redis乐观锁来实现秒杀,Redis乐观锁是Redis事务的经典应⽤。

Redis 的事务是通过 multi、 exec、 discard和 watch这四个命令来完成的。

Redis 的单个命令都是原⼦性的,所以这⾥需要确保事务性的对象是命令集合。

Redis 将命令集合序列化并确保处于同⼀事务的命令集合连续且不被打断的执⾏

Redis 不⽀持回滚操作。

watch 实现乐观锁

watch之后,multi,如果该key的值被修改,exec对改key值的修改会失败。

watch实现秒杀,谁能让watchkey的值增长说明谁就秒杀成功了,反之秒杀失败。

弱事务

  1. 不是原⼦操作

  2. 不⽀持回滚

    • ⼤多数错误都是代码 和数据的问题 ,可以预判断

    • 性能考虑

6. 在Redis中整合lua

写lua⽂件 redis.call()

7. lua如何解决Redis并发问题?

原⼦性(隔离性)

8. Redis下的分布式锁实现原理、优势劣势和使⽤场景?

利用redis的单线程特性对共享资源进行串行化处理。

9. 缓存问题
1)缓存穿透

查询缓存中不存在的值,这个值在数据库也没有。

  • 服务器过滤

  • 缓存降级

  • 布隆过滤器

2)缓存雪崩

大量缓存集中失效,压力突然加到数据库上

  • key的失效期分散开 不同的key设置不同的有效期

  • 设置⼆级缓存

  • ⾼可⽤

3)缓存击穿

单个缓存过期失效,然后突然来一波请求,大量的请求直接访问了数据库。

  • 持久化
  • ⼆级缓存
4)数据最终一致性
  • 先更新数据库同时删除缓存项(key),等读的时候再填充缓存

  • 2秒后再删除一次缓存项(key)

  • 设置缓存过期时间Expired Time 比如10秒或1小时

  • 将缓存删除失败记录到日志中,利用脚本提取失败记录再次删除(缓存失效期过长7*24)

  • 通过数据库的binlog来异步淘汰key,利用工具(canal)将binlog日志采集发送到MQ中,然后通过ACK机制确认处理删除缓存。

10. KV,DB读写模式

CAP模式

读的时候 先读缓存,缓存没有的话 就读数据库,然后把取出的数据放⼊到缓存 ,同时返回响应。

更新的时候,先更新数据库,然后再删除缓存。

11. Redis的线程模型
1)线程

单线程:

  • ⽂件处理器 由于⽂件处理器是单线程的 所以我们说redis是单线程。

  • redis基于内存而且使用多路复用技术,单线程数度很快,又保证了多线程的特点。所以不需要多线程。

多线程:

  • 因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升。

  • Redis可以使用del命令删除一个元素,如果这个元素非常大,可能占据了几十兆或者是几百兆,那么在短时间内是不能完成的,这样一来就需要多线程的异步支持。

总结:

​ Redis选择使用单线程模型处理客户端的请求主要还是因为cpu不是Redis服务器的瓶颈,所以使用多线程模型带来的性能提升并不能抵消它带来的开发成本和维护成本,系统的性能瓶颈也主要在网络I/O操作上;而redis引入多线程操作也是出于性能上的考虑,对于一些大键值对的删除操作,通过多线程非阻塞地释放内存空间也能减少对redis主线程阻塞的时间,提高执行的效率

2)Redis的核⼼组件

Socket

多路复⽤程序

⽂件命令分配(分派)器

⽂件处理器(命令接受器,命令处理器,命令响应处理器)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值