首页 > 数据库 >redis常见问题总结

redis常见问题总结

时间:2023-03-18 14:46:36浏览次数:68  
标签:总结 AOF 缓存 Redis redis 常见问题 key lock 服务器

redis 主从是异步模式
AOF和RDB复制都是才有子进程共享内存,写时复制实现的。
Redis 为了避免 AOF 文件越写越大,提供了 AOF 重写机制,当 AOF 文件的大小超过所设定的阈值后,Redis 就会启用 AOF 重写机制,来压缩 AOF 文件。
在整个 AOF 后台重写过程中,除了发生写时复制会对主进程造成阻塞,还有信号处理函数(当子进程完成 AOF 重写工作后,会向主进程发送一条信号同步)执行时也会对主进程造成阻塞,在其他时候,AOF 后台重写都不会阻塞主进程。

主从服务器间的第一次同步的过程可分为三个阶段:

  • 第一阶段是建立链接、协商同步;主从服务器在完成第一次同步后,双方之间就会维护一个 TCP 连接。而且这个连接是长连接的,目的是避免频繁的 TCP 连接和断开带来的性能开销。
  • 第二阶段是主服务器同步数据给从服务器(异步全量RDB文件);
  • 第三阶段是主服务器发送新写操作命令给从服务器。
  • 网络异常阶段,网络断开又恢复后,从主从服务器会采用增量复制的方式继续同步,也就是只会把网络断开期间主服务器接收到的写操作命令,同步给从服务器。如果判断出从服务器要读取的数据还在 repl_backlog_buffer 缓冲区里,那么主服务器将采用增量同步的方式;相反,如果判断出从服务器要读取的数据已经不存在 repl_backlog_buffer 缓冲区里,那么主服务器将采用全量同步的方式。

缓存更新策略
Cache Aside(旁路缓存)策略
写策略的步骤:
先更新数据库中的数据,再删除缓存中的数据。
读策略的步骤:
如果读取的数据命中了缓存,则直接返回数据;
如果读取的数据没有命中缓存,则从数据库中读取数据,然后将数据写入到缓存,并且返回给用户。

缓存的写入通常要远远快于数据库的写入

Cache Aside 策略适合读多写少的场景,不适合写多的场景,因为当写入比较频繁时,缓存中的数据会被频繁地清理,这样会对缓存的命中率有一些影响。如果业务对缓存命中率有严格的要求,那么可以考虑两种解决方案:
一种做法是在更新数据时也更新缓存,只是在更新缓存前先加一个分布式锁,因为这样在同一时间只允许一个线程更新缓存,就不会产生并发问题了。当然这么做对于写入的性能会有一些影响;
另一种做法同样也是在更新数据时更新缓存,只是给缓存加一个较短的过期时间,这样即使出现缓存不一致的情况,缓存的数据也会很快过期,对业务的影响也是可以接受。

什么是 Redis 大 key?
大 key 并不是指 key 的值很大,而是** key 对应的 value 很大**。
可以通过 redis-cli --bigkeys 命令查找大 key:
redis-cli -h 127.0.0.1 -p6379 -a "password" -- bigkeys
一般而言,下面这两种情况被称为大 key:
String 类型的值大于 10 KB;
Hash、List、Set、ZSet 类型的元素的个数超过 5000个;
大 key 会造成什么问题?
大 key 会带来以下四种影响:

  • 客户端超时阻塞。由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
  • 引发网络阻塞。每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
  • 阻塞工作线程。如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
  • 内存分布不均。集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。

大key删除

  • 分批次删除
  • 可以采用异步删除法,用 unlink 命令代替 del 来删除。

Redis 节点实现分布式锁时,对于加锁操作,我们需要满足三个条件
SET lock_key unique_value NX PX 10000

  • lock_key 就是 key 键;
  • unique_value 是客户端生成的唯一的标识,区分来自不同客户端的锁操作;
  • NX 代表只在 lock_key 不存在时,才对 lock_key 进行设置操作;
  • PX 10000 表示设置 lock_key 的过期时间为 10s,这是为了避免客户端发生异常而无法释放锁。

而解锁的过程就是将 lock_key 键删除(del lock_key),但不能乱删,要保证执行操作的客户端就是加锁的客户端。所以,解锁的时候,我们要先判断锁的 unique_value 是否为加锁客户端,是的话,才将 lock_key 键删除。
可以看到,解锁是有两个操作,这时就需要 Lua 脚本来保证解锁的原子性,因为 Redis 在执行 Lua 脚本时,可以以原子性的方式执行,保证了锁释放操作的原子性。

// 释放锁时,先比较 unique_value 是否相等,避免锁的误释放
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

参考链接
图解Redis介绍

标签:总结,AOF,缓存,Redis,redis,常见问题,key,lock,服务器
From: https://www.cnblogs.com/sanguoasd/p/17206198.html

相关文章

  • .NET/C#操作Redis的简单方法
    本文属于Redis初级应用,只起初步引路作用,高手们可略过。支持.NetCore(2.0及以上)/.NetFramework(4.5及以上),可以部署在Docker,Windows,Linux,Mac。Redis作为一款主流......
  • Redis主从复制、哨兵、集群
    首先,我们提出一个问题,Redis做缓存性能这么好,如果挂了怎么办?因此,我们提出来的第一个解决方案就是主从复制原则一、主从复制什么是主从复制:是指将一台Redis服务器的数据,......
  • SpringBoot使用redisTemplate存入Redis中Key会出现乱码
    测试操作Redis把key数据存入Redis,然后通过key取出UserMapper对象。@TestpublicvoidredisCacheTest(){Stringkey=UUID.randomUUID().toString();......
  • 3.17双人总结
    import java.util.LinkedList;public class Graph { public int num;                     //结点总数 /*  * LinkedList<Integer> adj[] ......
  • 2023.3.17结对总结
        今天实现了一条线路的起始站与终止站的查询......
  • 第五周星期五每日总结
       今日继续完善第一次结对作业的部分,经查找资料,设计出换成查询所需的表结构,将站点名称与站点ID存储到一个表szsubstop表中,将线路号与此线路中所有站点ID存储到szsub......
  • 总结20230317
    今天是周五,所以是课最多的一天,但是还是很高兴的,因为上完课迎接我的就是假期,可以说是苦尽甘来吧。今天的课是计算机网络、概率论、web应用开发技术、数学建模。计算机网络......
  • 每日双人总结
    importjava.util.LinkedList;publicclassGraph{publicintnum;//结点总数/**LinkedList<Integer>adj[]*一个存放......
  • golang使用缓存库go-cache的测试用例-短期内存缓存数据类似memcache/redis-【唯一客服
    golang中使用go-cache是非常普遍的,比如,我在对接微信客服接口的时候,获取access_token,默认获取一次有两个小时的有效期这个时候,我就可以使用go-cache来缓存access_token了......
  • C++指针总结
    在程序运行时分配的内存空间是需要在运行中释放的,这部分内存称之为堆。智能指针不用自己释放内存,只要没有指针指向内存了,就会自动释放。下面是两种智能指针:shared_ptr允......