redis常见问题

在redis的集群中,如何根据键定位到对应的节点

redis集群把数据分布到16384个哈希槽上,每个key通过CRC16算法算出哈希值,在对16384取模得到槽位编号

为啥是16384个槽
  1. 心跳包大小 :集群节点之间通过心跳包同步槽信息,16384 个槽的位图正好是 2KB(16384/8 = 2048 字节)
  2. 集群规模:集群不太可能超过1000个节点,这个大小刚好
  3. CRC16 算法:CRC16 生成 16 位结果,范围 0-65535,取 16384 是 2^14,适合位图存储
Redis集群中节点怎样通信

通过Gossip协议在集群中传播节点状态,故障信息,槽位分配等,使得集群的拓扑信息能快速的传播至所有节点,实现了去中心化,

什么是MOVED重定向?它和ASK重定向有什么区别?

MOVED重定向表示这个槽永久性地属于另一个节点,客户端应更新本地槽映射并以后直接目标节点。而ASK重定向表示这个槽正在迁移中,数据可能在源节点也可能在目标节点,这次去目标节点问一下,但不用更新本地缓存

MOVED错误:比如客户端要找的key不在这个节点上,这个节点就会返回一个MOVED错误,里面带着相应节点的ip和端口

ASK的ASKING请求:因为迁移还没完成,目标节点理论上还没正式接管这个槽,相当于时一个临时授权,如果不发的话,目标节点可能会拒绝管理

跳跃表的结构以及与红黑树相比它的优势在哪里?

跳跃表时一种基于有序链表的多层索引结构,每一层都是下一层的的快速通道,查找时从最高层开始,逐步缩小范围,最后在底层找到目标,平均时间复杂符o(log n)。

redis作者解释过选择跳跃表而不是红黑树基于以下几点

  1. redis的设计哲学是keep it Simple,Stupid。跳跃表的实现比红黑树简单的多,代码只要几百行,而红黑树需要几千行且容易出错
  2. 跳跃表的结构更容易可视化和调试,出现问题,则打印每一层链表就能定位
  3. redis的Sorted Set的需求是范围查询直接利用底层链表,排名计算则利用跨度字段(它记录当前层到下一个节点的距离,用于计算元素的排名),跳跃表完美符合。红黑树实现复杂且性能也差
  4. 跳跃表虽然比红黑树更占内存,但对内存数据库来说,这点开销完全能接收,换来的是代码的简洁性和可维护性

为什么要用redis,用场景举例,优化了什么

  1. redis数据存储在内存中读写速度时百万级QPS,而mysql是基于磁盘,读写是千级QPS,内存比磁盘快1000倍以上
  2. redis核心处理是单线程的,避免了多线程的竞争和锁开销,加上epoll这样的IO复用机制,使得在高并发下非常稳定
    场景1:电商页面
    未用redis,每次请求都去查mysql,mysql在高并发下出现磁盘i/o延迟,索引丢失和单表数据量过大导致查询性能骤降,使用后并发骤降
    场景2:分布式锁
    秒杀系统,只有很少的库存然后几十万人同时抢,多个请求读到还剩一件,容易出现超卖,而mysql本身的锁性能很差,使用setnx实现分布式锁实现了高并发下的数据一致性

既然redis是单线程那它为什么还能这么快?

redis的核心瓶颈从来不是cpu而是网络I0,之所以单线程就能支撑如此高的并发是因为它IO多路复用,让单个线程同时监听多个客户端,当有事情线程采取处理,没有任务就阻塞或处理其他任务。单线程就是解决网络IO的高效方法之一,因为它避免了多线程下的复杂加锁机制

那为什么这几年单线程设计被打破了

因为随着硬件的发展,网络IO的延迟被降低了,然后redis存的数据越来越复杂了,它引入的多线程并不是将读写命令变成多线程,而是只用于处理网络IO的读写,核心的执行命令依然是单线程

瓶颈是什么

搞垮redis的不是QPS,而是慢查询:特别复杂的命令,这样会使单线程的redis陷入长时间的阻塞

相关推荐
运维行者_2 分钟前
理解应用性能监控
大数据·服务器·网络·数据库·人工智能·网络协议·安全
2301_769340673 分钟前
Golang怎么限制请求Body大小_Golang如何防止客户端发送过大的请求体【避坑】
jvm·数据库·python
fengxin_rou7 分钟前
Feed 三级缓存架构详解:分层设计、缓存一致性与高性能实战
spring·缓存·架构
Jetev11 分钟前
Django怎么优雅发送邮件_Python配置SMTP后端实现异步通知
jvm·数据库·python
爱编程的小新☆11 分钟前
redis缓存
redis·分布式·缓存
woxihuan12345615 分钟前
golang如何读写YAML配置文件_golang YAML配置文件读写解析
jvm·数据库·python
彳亍10116 分钟前
mysql如何实现数据库按月分表_利用分区表优化查询性能
jvm·数据库·python
木子墨51616 分钟前
系统设计面试 | 实现一个限流器:滑动窗口 → 令牌桶 → 漏桶
java·开发语言·数据结构·数据库·面试·职场和发展
m0_4636722017 分钟前
Golang怎么获取当前工作目录_Golang如何用os.Getwd获取程序运行路径【基础】
jvm·数据库·python
2401_8844541519 分钟前
mysql如何处理大量重复值索引_mysql索引存储特征分析
jvm·数据库·python