1、什么是Redis?
Redis是一种基于内存的并且提供一定持久化功能的非关系型数据库,与关系型数据库不同,它使用KV键值对的形式存储数据。它的性能十分优越,可以支持每秒十几万次的读**(110000/s)操作,以及几万次的写(81000/s)**操作(官方数据);
2、应用场景
适合使用Redis 的应用场景很多,包括但不仅限于缓存热点或常用数据(评论)、消息队列(支付)、高速读写的场景(现场投票);
当出现如下情况时就不适合使用Redis:业务数据如果命中率很低 就没有必要写入Redis;业务数据写的操作多,需要频繁写入数据库,也没有必要使用Redis;业务数据要存储几百兆字节的文件,及比较大的文件存储会给Redis带来很大的压力,也没有必要使用Redis。
3、Redis中的五种数据存储类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)以及zset(sorted set:有序集合)。
①、string(字符串):string 是 redis 最基本的类型,使用一个 key 对应一个 value。string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
②、hash(哈希):Redis 的hash是一个键值(key=>value)对集合; 一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
③、list(列表):Redis 列表是简单的字符串列表,按照插入顺序排序,允许有重复的元素;
④、set(集合):Redis 的 Set 是 string 类型的无序集合,不允许重复。
⑤、zset():Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
存储类型 | 添加元素 | 查看元素 |
---|---|---|
string | set 键 值 | get 键 |
hash | hset 键 字段 值、hmset 键 字段1 值1 字段2 值2 字段n 值n | hget 键 字段(获得某个键的字段对应的值)、hmget 键 字段1 字段2 字段3 字段n(获得该键的多个字段对应的值)、hgetall 键(获得该键所有的值) |
list | lpush 键 值1 值2 值3 | lrange 键 开始下标 结束下标(获得该键目标下标范围内的键值<逆序>) |
set | sadd 键 值1 值2 值3 | smembers 键 |
zset | zadd 分数1 值1 分数2 值2 分数n 值n | zrange 键 开始下标 结束下标(获得下标范围的键值)、zrangebyscore 键 开始分值 结束分值(按照分值获得键值) |
4、Redis常用命令
命令 | 用法 |
---|---|
keys * | 获取所有键值 |
dbsize | 获取键总数 |
exists key 键 | 查询键是否存在 |
del key 键 | 删除键 |
type 键 | 查询键类型 |
ttl key(秒语法)或pttl key(毫秒语法) | 查询键的生命周期(-1为永远不过期,-2该键不存在) |
expire key seconds(秒语法)或pexpire key milliseconds(毫秒) | 设置过期时间、 |
persist 键 | 设置永不过期 |
rename 键 新键 | 更改键的名称 |
5、对于Redis常见问题的总结
1、Redis为什么这么快?
Redis快是因为它采用内存作为存储介质、KV键值对结构相对简单,不会带来额外的性能的开销; 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;使用C/C++开发,数据库操作更加贴近底层。
2、缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起id为-1的请求数据或者id特别大的不存在的数据,这时的用户可能是攻击者,攻击会导致数据库压力过大。解决的方案:①、接口层增加校验,如用户鉴权校验,id做基础校验,对id<0的直接拦截;
②、从缓存取不到数据,在数据库中也没有取到,这时也可以将key-value写为key-null,缓存有效时间可以设置的相对较短,如30秒(设置太长会导致正常情况下也没有办法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
3、缓存击穿
缓存击穿是指缓存中没有但是数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没有读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决方案:设置热点数据永远不过期;定时任务更新缓存数据 ;加互斥锁。
4、缓存雪崩
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机,和缓存击穿不同的是,缓存击穿是指并发查同一条数据,缓存雪崩是不同的数据在同一时间都过期了,大量的查询操作全部涌入数据库。
解决方案:缓存数据的过期时间设置随机。防止同一时间大量数据过期的现象发生;如果缓存数据库是分布式部署的,将热点数据均匀分布在不同的缓存数据库中;设置缓存数据永不过期。