单线程为什么执行速度那么快
(1) 纯内存操作
(2) 避免了不必要的上下文切换
避免了多线程之间的竞争和切换而消耗CPU,避免了各种锁操作
(3) 采用了非阻塞I/O多路复用技术
2. 底层存储
2.1 String
Simple dynamic string (SDS)
struct sdshdr{ int len;//保存字符串的长度 int free;//空闲的字符串长度 char buf[];//保存字符串 }
优点
(1) 不会出现字符串变更造成内存溢出
(2) 获取字符串长度的时间复杂度为1
(3) 空间预分配,惰性释放free,会默认留够一定的空间防止多次分配内存
场景
缓存:作为Mysql的缓存层。
计数器:记录播放量,记录访问次数
共享session,存储用户的登录信息
限速,手机验证码
2.2 Hash
数组+链表
重写rehash
将迁移工作分配到每一次CRUD中,避免了服务繁忙
场景
管理用户信息,完成简单的查询
2.3 List
场景
阻塞队列,栈,链表,队列
关注列表
最新消息排行
2.4 Set
Value为null的HashMap。
场景
共同喜好,共同关注
2.5 Zset
HashMap和跳跃表
HashMap存放成员到score的映射,跳跃表里存放的是所有的成员
场景
排行榜
延时队列
3. Redis事务
(1) Multi开启事务
(2) Exec执行事务代码块
(3) Discard取消事务
(4) Watch监制一个或多个key,如果事务执行前key被改动,事务将打断
3.1 redis事务的实现特征
(1) 所有命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其他客户提供请求。
(2) Redis事务中如果有某一条命令执行失败,之后的命令仍然会被继续执行
(3) 在事务开始之前,如果客户端与服务器之间出现通信故障并导致网络断开,之后的所有待执行语句都不会执行。如果exec之后网络中断后,事务中的所有命令都会被服务器执行
(4) 当使用Append-Only模式时,Redis会通过调用write全部写入磁盘。
当写入时断电,会发生数据不一致的信息,使用redis-check-aof对数据进行回滚
4. Redis集群
官方cluster集群3主3从
客户端只需要连接其中的任何一个节点
4.1 容错性
投票
集群中所有的master节点投票,半数以上的master挂掉集群不可用
节点分配
新增节点时,从每个节点的前半部分分配给新的节点
4.2 主从复制
(1) 从机连通会给主机发送sync指令
(2) 主机进行存盘操作,发送RDB文件给从机
(3) 从机收到后,进行全盘加载
(4) 每次主机写操作,都会立刻发送给从机,从机执行相同的命令
4.3 性能优化
(1) 主机不进行持久化,从机AOF备份数据
(2) 主从位于同一局域网
(3) 避免在压力大的主库上增加从库
(4) 使用链式结构增加从机
4.4 集群不可用
(1) 主机挂掉,当前主机没有从机
(2) 半数以上的主机挂掉
5. 持久化
5.1 RDB
定期的全盘缓存
触发机制
900s有一个key,300s有10个key,60s有一万个key(默认)
5.2 AOF
日志文件
触发机制
每次记录,每1s记录
5.3 比较
(1) AOF文件比RDB更新频率高
(2) 优先使用AOF
(3) AOF更安全
(4) RDB比AOF性能好
6. 缓存
6.1 缓存淘汰
(1) 先进先出(FIFO)
(2) 近期较少使用(LFU)
(3) 最长时间未被使用哪个(LRU)
6.2 Key过期的删除策略
(1) 惰性删除
当使用时,如果过期就删除,如果没过期就返回
(2) 定时删除
key过期后设置一个定时器
(3) 定期删除
一段时间对key进行检查,删除
6.3 缓存穿透
当获取一个数据但是缓存中没有,数据库中也没有,多次查询使数据库宕机
解决
(1) 布隆过滤器
将mysql中的key放入布隆过滤器,查询之前,查看数据库中是否有这个key
(2) 在redis存储不存在的key设置value为null
6.4 缓存击穿
当获取一个数据但是缓存中没有(过期时间到,宕机),数据库中有,多次查询使数据库宕机
解决
redis集群
redis和数据库中,添加缓存层或限流
6.5 缓存雪崩
同一时刻大量缓存失效,直接请求数据库
解决
(1) 设置不同失效时间
(2) 双层缓存
(3) 定期更新
(4) 增加过期标志
6.6缓存阻塞
(1) 数据结构不合理
(2) CPU饱和
(3) 持久化阻塞
6.6 热点key缓存倾斜
(1) 使用本地缓存
(2) 利用分片算法,对key加前缀,把一个热点key分散成多个key
7. 应用
7.1 key搜索
scan指令,无阻塞
7.2 redis异步队列
list作异步队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,sleep一会继续判断,或者使用blpop阻塞
7.3 生产一次多次消费
pup/sub主体订阅者模式,实现1:N的消息队列
7.4 延时队列
使用sortedset,将时间戳作为score,消息内容作为key,使用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据进行处理
