redis
背景
数据量的增加 + 业务场景的不断扩充 --》 mysql集群
秒杀等复杂场景mysql难以支撑实时查询 -》 数据可以直接从内存里面直接读取
工作原理
如果没有持久化存储的话,可能宕机之后就没有数据了
如果宕机重启之后 会读取对比RDB文件中有没有没有执行的命令 如果有会将没有执行的命令加载到AOF中 (保证启动后和上一次的状态是一致的 -》 数据库不丢失)
redis通过RDB和AOF方式将数据存入磁盘,实现持久化。 RDB是定期生成快照存入磁盘中,AOF是将写操作存入磁盘中。 二者各有优劣,RDB 是存放数据库中数据,适合做数据备份,但是数据可能不全,最近几分钟的数据可能没有。 AOF是每秒钟执行一次,如果有写操作的命令就存储起来,最多只会丢失1秒钟的数据,适合做数据恢复。 但是这个就不适合做数据备份了,并且由于每秒都会执行多多少少会抢占redis的内存,会影响性能。 但是在实际应用中是二者是配合使用的。 RDB 的全称是 redis database. 顾名思义,RDB就是将redis数据库,用来存储数据的,所以通过RDB方式持久化就是将存在redis内存中的数据写入到RDB文件中保存到磁盘上从而实现持久化的。
实例
连续签到
可以直接设置一个过期时间 来保证签到的连续性,如果今天签到了修改value的时候也要同时更新 expireAt
string 数据结构
string - 节省空间 快速读写的目的
alloc表示实际开辟的空间 len实际用到的空间
消息通知
使用lpush进行推送
list数据结构
为了节省内存 在一个节点上面存储很多数据 将多个数据element压缩在listpack中 然后放到节点的entry中
quicklist
计数
代码中使用了pipeline的功能 防止多次传输
hash结构
时间复杂度 O(1)
当链表很长的时候会进行扩容 防止链表很长增加时间复杂度(增加槽位的话需要进行数据迁移 rehash)
排行榜
如果只用mysql存储每个用户的积分,那么查询完之后在排序性能不高 甚至服务器会宕掉
所以需要redis进行缓存
zset数据结构
跳跃表 zskiplist
如果没有跳跃表的话(只有最下面一行) 如果取数据需要进行链表遍历
但是加入跳跃表的话 可以先找 1 3 7 然后就能找到对应的
限流
key是时间戳 用这个查看reids中已经访问的用户数,如果超了其他的就进制访问了
分布式锁
setnx如果有请求了 就会拒绝其他请求,但是setnx也不能绝对保证
注意事项
大key
危害
解决
冷热分离比较常见:比如查半年内的账单时间比较短(redis) 其他的长(mysql)
热key
多数请求都走某一个服务器
解决
localcache需要每个程序都写一个,比较麻烦
慢查询
缓存穿透 缓存雪崩
解决