哈喽大家好,阻塞我是情况阿Q!
前两天去美团面试的美团面细陈同学回来了,看他满脸泄气的阻塞样子,准是情况没拿到 Offer。
听了他面试的美团面细经过,真替他感到惋惜。阻塞究其原因,情况是美团面细被一道面试题拦住了去路:看你简历上写着精通 Redis,请你总结一下 Redis 阻塞中存在的阻塞问题吧。
正好阿Q这几天正在研究 Redis,情况就顺便在这儿给大家做个总结。
使用不当的命令造成客户端阻塞:
这些命令时间复杂度是O(n),有时候也会全表扫描,随着n的增大耗时也会越大从而导致客户端阻塞。
大家都知道 Redis 在进行 RDB 快照的时候,会调用系统函数 fork() ,创建一个子线程来完成临时文件的写入,而触发条件正是配置文件中的 save 配置。
当达到我们的配置时,就会触发 bgsave 命令创建快照,这种方式是不会阻塞主线程的,而手动执行 save 命令会在主线程中执行,阻塞主线程。
当 Redis 直接记录 AOF 日志时,如果有大量的写操作,并且配置为同步持久化
appendfsync always
即每次发生数据变更会被立即记录到磁盘,因为写磁盘比较耗时,性能较差,所以有时会阻塞主线程。
阻塞就是出现在第2步的过程中,将缓冲区中新数据写到新文件的过程中会产生阻塞。
AOF 的日志记录不像关系型数据库那样在执行命令之前记录日志(方便故障恢复),而是采用先执行命令后记录日志的方式。
原因就是 AOF 记录日志是不会对命令进行语法检查的,这样就能减少额外的检查开销,不会对当前命令的执行产生阻塞,但可能会给下一个操作带来阻塞风险。
这是因为 AOF 日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,就会导致写盘很慢,进而导致后续的操作也无法执行了。
大 key 并不是指 key 的值很大,而是 key 对应的 value 很大。
大 key 造成的阻塞问题如下:
当我们在使用 Redis 自带的 --bigkeys 参数查找大 key 时,最好选择在从节点上执行该命令,因为主节点上执行时,会阻塞主节点。
redis-rdb-tools:Python 语言写的用来分析 Redis 的 RDB 快照文件用的工具
rdb_bigkeys:Go 语言写的用来分析 Redis 的 RDB 快照文件用的工具,性能更好。
删除操作的本质是要释放键值对占用的内存空间。
释放内存只是第一步,为了更加高效地管理内存空间,在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序。
所以,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞,如果主线程发生了阻塞,其他所有请求可能都会超时,超时越来越多,会造成 Redis 连接耗尽,产生各种异常。
删除大 key 时建议采用分批次删除和异步删除的方式进行。
清空数据库和上面 bigkey 删除也是同样道理,flushdb、flushall 也涉及到删除和释放所有的键值对,也是 Redis 的阻塞点。
Redis 集群可以进行节点的动态扩容缩容,这一过程目前还处于半自动状态,需要人工介入。
在扩缩容的时候,需要进行数据迁移。而 Redis 为了保证迁移的一致性,迁移所有操作都是同步操作。
执行迁移时,两端的 Redis 均会进入时长不等的阻塞状态,对于小Key,该时间可以忽略不计,但如果一旦 Key 的内存使用过大,严重的时候会触发集群内的故障转移,造成不必要的切换。
责任编辑:武晓燕 来源: 阿Q说代码 Redis阻塞客户端(责任编辑:百科)
富瀚微(300613.SZ)公布消息:就收购眸芯科技32.43%股权已完成工商变更登记
江山欧派(603208.SH)公布消息:公开发行可转债申请获审核通过
代销基金业务“增援”银行营收 “赎旧买新”或与银行经理绩效挂钩
2022年全球人工智能软件市场规模将达625亿美元 相比2021年增长21.3%