redis
Memcash和redis的区别
Memcash:代码层次类似Hash
支持简单数据类型
不支持数据持久化存储
不支持主从
不支持分片
redis
数据类型丰富
支持数据磁盘持久化储存
支持主从
支持分片
redis为什么能这么快
10万+QPS
1.完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
2.数据结构简单,对数据操作也简单
3.采用单线程,单线程也能处理高并发请求,想多核也可启动多实例
4.使用多路I/O复用模型,非阻塞IO
多路I/O复用模型
FD: File Descriptor 文件描述符
一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元文件的元数据到文件本身的映射
![](https://img.haomeiwen.com/i13450194/cd2e01f7079898d2.png)
![](https://img.haomeiwen.com/i13450194/2425f509ceb6359e.png)
Redis采用的I/O多路复用函数:epoll/kqueue/evport/select?
1.因地制宜
2.优先选择时间复杂度为O(1)的多路复用函数作为底层实现
3.以时间复杂度为O(n)的select作为保底
4.基于react设计模式监听I/O事件
redis 数据类型
![](https://img.haomeiwen.com/i13450194/fae5202294aae6c6.png)
![](https://img.haomeiwen.com/i13450194/9d851e126aeee424.png)
从海量Key里查询出某一固定前缀的Key
1.摸清数据规模,即问清楚边界
![](https://img.haomeiwen.com/i13450194/ff23045074bcf1c7.png)
![](https://img.haomeiwen.com/i13450194/8f39332425c3d976.png)
Redis实现分布式锁
分布式锁需要解决的问题
1.互斥性
2.安全性
3.死锁
4.容错
setnx key value :如果key不存在,则创建并赋值
时间复杂度: O(1)
返回值:设置成功,返回1;设置失败,返回0
expire key seconds
设置key的生存时间,当key过期时(生存时间为0),会被自动删除
缺点:原子性得不到满足,挂掉后会死锁
![](https://img.haomeiwen.com/i13450194/b933e4f500aeb3ef.png)
![](https://img.haomeiwen.com/i13450194/6cb194ef3a7d712e.png)
set uid 11426 ex 10 nx
![](https://img.haomeiwen.com/i13450194/e975c8bf2875f16b.png)
使用Redis做异步队列
使用List作为队列,rpush生产消息,lpop消费消息
缺点:没有等待队列有值就直接消费
弥补:可以通过在应用层引入Sleep机制去调用LPOP重试
BLPOP key [key...] timeout
: 阻塞直到队列有消息或者超时
![](https://img.haomeiwen.com/i13450194/f4391e77d7c52de5.png)
缺点:只能供一个消费者消费
pub/sub 主题订阅者模式
发送者(pub)发送消息,订阅者(sub)接受消息
订阅者可以订阅任意数量的频道
![](https://img.haomeiwen.com/i13450194/7a0f58cde2bd91ed.png)
![](https://img.haomeiwen.com/i13450194/068a7f9983a23ffb.png)
pub/sub 缺点:
消息的发布是无状态的,无法保证可达
redis做持久化
RDB(快照)持久化:保存某个时间点的全量数据快照
redis.conf 找到save,大概218行
save 900 1 900s内有一条写入执行执行一次快照
save 300 10 300s内有10条写入执行一次快照
save 60 10000 60s内有1万写入,执行一次快照
//当备份进程出错时,主进程停止进行新的写入操作,保护持久化数据一致性问题
stop-writes-on-bgsave-err yes
//备份时,将rdb文件进行压缩后进行保存(建议no,cpu比硬盘更值钱)
rdbcompression yes
//同时若要禁用rbd配置,也可以在上面添加 save ""
![](https://img.haomeiwen.com/i13450194/847d841a6a507140.png)
文件在 src/dump.rdb
lastsave 查看最后save的时间
![](https://img.haomeiwen.com/i13450194/8b307a40b11becd2.png)
![](https://img.haomeiwen.com/i13450194/8978e2daec74da00.png)
![](https://img.haomeiwen.com/i13450194/8a7c84fb61164dfc.png)
![](https://img.haomeiwen.com/i13450194/5489789fe2341a35.png)
缺点:
内存数据全量同步,数据量大会由于I/O而严重影响性能
可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据
AOF(Append-Only_File)持久化:保存写状态
记录下除了查询以外的所有变更数据库状态的指令
以append的形式追加保存在AOF文件中(增量)
redis.conf
//改为yes 开启
appendonly no
//文件名
appendfilename "appendonly.aof"
//always 一旦缓存区发生变化 everysec 每秒执行 no 缓存满执行 推荐默认的everysec
appendfsync everysec
![](https://img.haomeiwen.com/i13450194/a1c4eef2edd66037.png)
![](https://img.haomeiwen.com/i13450194/d85992ff6a6e111a.png)
![](https://img.haomeiwen.com/i13450194/acb2acdeed360a95.png)
![](https://img.haomeiwen.com/i13450194/99167283d0784099.png)
BGSAVE做镜像全量持久化,AOF做增量持久化
使用pipeline的好处
Pipeline 和 linux的管道类似
redis 基于请求/响应模型,单个请求处理需要一一应答
pipeline批量执行指令,节省多次IO往返的时间
有顺序依赖的指令建议分批发送
Redis的同步机制
![](https://img.haomeiwen.com/i13450194/2233030cbda102fa.png)
![](https://img.haomeiwen.com/i13450194/82fc2dffbebb1044.png)
![](https://img.haomeiwen.com/i13450194/8b5f9428683fdc66.png)
![](https://img.haomeiwen.com/i13450194/d7f9431878e96b39.png)
![](https://img.haomeiwen.com/i13450194/e39f4feed19cd69c.png)
redis 集群
![](https://img.haomeiwen.com/i13450194/f638c8ae15349797.png)