什么是Redis
Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API,是跨平台的非关系型数据库。 Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
redis数据结构
Redis 数据结构并不是指 String(字符串)对象、List(列表)对象、Hash(哈希)对象、Set(集合)对象和 Zset(有序集合)对象,因为这些是 Redis 键值对中值的数据类型,也就是数据的保存形式,这些对象的底层实现的方式就用到了数据结构。
为什么需要Redis?
数据从单表,演进出了分库分表 MySQL从单机演进出了集群
- 数据量增加
- 读写数据压力的不断增大
MySQL
数据分冷热 热数据:经常访问的数据
将热数据存储到内存
基本工作原理
数据从内存中读写
保存到硬盘以防止重启数据丢失
- 增量数据保存到AOF文件
- 全量数据RDB文件
单线程处理所有命令
Redis的应用案例
1.连续签到
string数据结构
数据结构sds
- 可以存储字符串,数字,二进制数据,
- 通常和expire配合使用
- 场景:存储计数,Session
假如存储的「字符串是一个字符串值并且长度大于32个字节」就会使用SDS(simple dynamic string)方式进行存储,并且encoding设置为raw;
若是「字符串长度小于等于32个字节」就会将encoding改为embstr来保存字符串。
SDS称为「简单动态字符串」,对于SDS中的定义在Redis的源码中有的三个属性int len、int free、char bu。
- len保存了字符串的长度,
- free表示buf数组中未使用的字节数量
- buf数组则是保存字符串的每一个字符元素。
2.消息通知
用list作为消息队列 数据结构Quicklist由一个双向链表和listpack实现
3.计数
一个用户有多项技术需求,可通过hash结构存储 Hash对象的实现方式有两种分别是ziplist、hashtable,其中hashtable的存储方式key是String类型的,value也是以key value的形式进行存储。
字典类型的底层就是hashtable实现的,明白了字典的底层实现原理也就是明白了hashtable的实现原理,hashtable的实现原理可以与HashMap的是底层原理相类比。
字典
两者在新增时都会通过key计算出数组下标,不同的是计算法方式不同:
- HashMap中是以hash函数的方式,
- hashtable中计算出hash值后,还要通过sizemask 属性和哈希值再次得到数组下标。
rehash 扩容hash 0:从槽位0开始rehash -1:rehash结束 渐进式rehash
4.排行榜
积分变化,排名要实时变更
结合dict后,可实现通过key操作跳表的功能
zset数据结构zskiplist
5.限流
要求1s内放行的请求N,超过则禁止访问
Redis使用注意事项
大key和热key
大key
大key的危害
- 读取成本高
- 容易导致慢查询(过期,删除)
- 主从复制异常,服务阻塞,无法正常响应请求
业务侧使用大key的表现
- 请求Redis超时报错
消除大key
- 拆分。将大key拆成小key
- 压缩。将value写入redis,读取时解压后在再使用,如果存储json字符串,可以考虑messagepack进行序列化。
3.集合hash,list,set,zeset (1)拆分 (2)区分冷热
热key
CPU负载突增或者不均的情况 QPS超过500有可能被识别为为热key
解决热key的方法
1.设置localcache
2.使用redis代理的热key承载能力
慢查询
缓存穿透
热点数据查询绕过缓存,直接查询数据库
减少方法
- 缓存空值
- 布隆过滤器
缓存雪崩
大量缓存同时过期
避免方法
缓存空值 使用缓存集群