Redis 复盘
2021-12-29 本文已影响0人
莫妮卡笔记

Redis 复盘
一、应用层
Redis是内存数据库、他的所有操作都是在内存中去执行、所以他效率也非常高;虽然他也有持久化的操作、比如 RDB 全量 、AOF 的增量 但是他在不开启AOF的情况下效率是不会被影响的。而RDB存储也只是镜像备份,通过fork子线程来操作,所以不影响客户端对Redis服务端的读写性能。
Redis也提供了很丰富的数据结构我们可以根据业务情况去选择比如常用的string/hash/set/list等等....
二、网络层
Redis网络层是通过单线程Reactor模型来处理客户端/服务端连接的。而Reactor 底层用的IO多路复用Epoll技术来实现,而Epoll 处理多少连接是受限于系统句柄数,而系统句柄数受限于系统物理内存,所以在物理内存够用的情况下能够同时处理非常高的连接数;理论上是无上限的。
这也是Redis官网数据说能够秒级处理10WQPS的勇气。
在Redis6.0以后使用的是多线程来实现、其实也是Reactor的加强版;单Reactor多线程,其实弥补了大Key处理的能力,因为在单Reactor模型的情况下,如果有大Key处理会有阻塞的情况影响了整体处理指令效率,通过多线程来弥补了这个缺点,提高了整体吞吐率(所以很多时候别人说memcached处理大Key能力优于Redis就是用了多线程)。
三、存储层
Redis存储层有两种模式分别RDB、AOF;
- RDB 是全量备份存储的是 key value二进制文件,但是一般是秒级备份一次;如果是在极端的情况下会造成丢失数据的可能性。比如说在通过BGSAVE fork子线程备份期间服务器挂了。
- AOF 是增量备份 存储的是 所有语句包括key vale内容;文件占用内存比较大(不过AOF有个优化机制就是重写,定期会把AOF文件合并一次如果多个指令针对同一个Key操作会合并起来 降低冗余存储压力),可以设置每个指令都刷磁盘,所以在极端的情况下只会丢失1个指令数据。就是会性能会非常低。
如果系统同时开启RDB/AOF 其实就是一个NOSQL数据库了、但是在系统挂了恢复的时候会优先使用AOF来恢复。
四、数据结构层
- Redis 数据结构是属于Hash散列结构;这种数据结构查找时间复杂度是O(1)的非常快,比如Redis默认是有16384的槽位;我一个key存储的时候,他会通过crc16(Key)%16384去定位到那个槽位去存储。
- 那么取值的时候也也根据过crc16(Key)%16384去定位到那个槽位去取数据。不像mysql B+数(时间复杂度O(logn))的数据结构还要通过索引去遍历,去比较才能够查到最终的值;在Redis集群的时候比如有三个节点他会把槽位均衡去分配到各个节点。
五、架构层
redis特点就是协调者+主从+集群+分片
- 协调者:监控主从状态、如果挂了通过协调者做切换达到故障转移的效果。
- 主从:主从提高性能、可用性、主从都可以提供读能力 分担压力提高吞吐率、当主节点挂了、可切换从节点提高可用性。
- 集群:多个主从组成小集群;主要提高写能力;毕竟数据写入只有master才能写;
- 分片:降低存储压力、把数据分片到多个节点中;扩展充分提高存储能力。
六、Redis缺点
- redis 宕机可能会造成数据丢失问题。
- redis 做分布式锁;主从切换会导致重复获锁问题。
- redis 高峰20W QPS - 会造成偶发耗时较长的情况、可能达到他的瓶颈。如果追求极致性能不建议使用。
- redis 大Key处理可能会导致整体性能下降(毕竟6.0之前的版本都是单线程处理)。
- redis 集群扩容需要重新分配槽位;线上扩容迁移槽位非常麻烦,带来不可控风险。
- redis 缓存穿透/雪崩问题、需要通过布隆过滤器、或者null key、或者分布式锁来解决。
- redis mysql强一致性问题;需要通过Cannl来同步实现;让Cannl作为mysql从节点;同步binlog文件;Cannl会把binlog转换成json数据;解析json数据再写到redis中!
七、使用场景
。。。。结合自己业务来看。