redis常用的类型有String、List、Set、Hash、sorted Set。不同类型存储的value值大小是不一样的,比如Stirng是512M。
redis的缓存场景:用户发送请求给服务器,首先是在Redis里面查询数据,如果redis里面没有数据,那么会到数据库里面查询数据,将查询结果回写到redis里面,并且将结果返回给用户.
springboot是集成redis的,。
1.String
string类型,任何关于字符的操作都是可以的
常见的指令 | 含义 | 例子 |
get key | 根据key获取value值 | |
set key value | 添加string | |
mset key1 value1,key2 value2,key3 value3 | 批量添加 | |
mget key1,key2 | 批量获取 | |
incr key | 对key的value进行递增,递增的value一定是int类型的 | set age 11 incr age 结果age为12 |
incrby key | 指定对key的value值递增多少 | set age 11 incrby age -2 结果age为9 |
incrbyfloat |
1.1 场景
可以做缓存
如果是单个的查询接口,在10ms外是可以优化的。如果mysql优化不了,那么用redis优化。
在后端,通过数据库查询到的值保存在redis中,对于保存的值,要设置一个过期时间,为什么要设置这个过期时间呢,因为这个会与数据库有数据一致性问题的,设置过期时间的目的是为了解决缓存的最终一致性。
可能会出现缓存击透,就是在并发条件下,有多个请求同时进行查询数据,而这是缓存里的数据可能因为过期了失效,这些请求就同时访问数据库。
incr 计数相关的场景都可以做,并且由于是单线程,不会有并发问题。比如说
分布式ID
点赞数、评论数
软限流
短信验证参数、库存
2. Hash
hash也是一个k-v结构,但其中v也是k-v结构,所以也叫k-k-v结构。
指令 | 含义 | 例子 |
hset KEY key value | 设置值 | hset huihui age 18 hset huihui name huihui |
hget KEY key | 得到值 | |
hincrby KEY key newValue | 设置新值 | |
hgetall KEY | 获取所有值 |
应用场景:
- 缓存对象型数据
- 统计型数据会经常用到,用hincrby
3. List
存储有序的列表,里面的元素可以重复的,添加元素的时候可以左边加也可以右边加。
指令 | 含义 | 例子 |
lpush key value1 value2 | 往左边加元素 | |
rpush key value1 value2 | 往右边加元素 | |
rpop key | 往右边移除元素 |
使用场景
- 适用于有序的列表,比如按时间顺序,朋友圈
- 堵塞队列,可以用blpop或brpop,但不建议做,因为已经有完善的mq组件了,比如rabbit、kafka等。
4. set
set是一个无序的集合,里面的元素不能重复,可以添加进去,但会覆盖原来的元素。查询效率接近O(1)
在里面的元素全部是整型的时候是有序的。
存入到set里面是无序的,但是拿的时候,每一次拿都是一样的排序。
指令 | 含义 | 例子 |
sadd key v1 v2 v3 ... | 添加元素 | |
smembers key | 获取元素 | |
scard key | 获取元素个数 | |
srandmember key m | 随机获取元素 | |
spop key | 随机弹出一个元素(移除) | |
sdiff key1 key2 | key1 和 key2 的差值,也就是key2 没有key1的元素 | sadd zsc1 a b f sadd zsc2 a c sdiff zsc1 zsc2 结果为 b f |
sinter key1 key2 | 交集 | |
sunion key1 key2 | 并集 |
场景:
- 抽奖
- 所有集合类场景,比如共同好友
5、sortSet
里面的元素不可重复,但有序的,有个sort决定顺序。
指令 | 含义 | 例子 |
zadd key sort v1 sort v2 | 添加元素 | |
zrange key 0 -1 | 从小到大查询所有的元素 | |
zrevrange key 0 -1 | 从大到小查询 | |
zrangebyscroe key n m | 查询范围内的元素,从n到m |
应用场景
- 排行榜
6. bitMap
可以做统计,因为是做了位运算,所以速度非常快。还可以做权限
指令 | 含义 | 例子 |
setbit key offset v | 保存bit数据 | |
bitcount key | 统计所有key的数据 | |
getbit key offset | 统计key的offset情况的次数 |
7.案例
@Service
public class UserService implements com.zsc.zsc.app.service.UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private RedisTemplate redisTemplate;
@Override
public List<User> selectList(User user) {
//将查询条件转为key
Gson gson = new GsonBuilder().create();
String key =gson.toJson(user);
//先去查Redis,Redis没有再查数据库
List<User> userList = (List<User>) redisTemplate.opsForValue().get(key);
if(CollectionUtils.isEmpty(userList)){
//针对并发条件再去查询redis
synchronized (UserService.class){
if (CollectionUtils.isEmpty(userList)){
//数据库查询
userList = userRepository.selectList(user);
//如果数据库有结果,则保存在redis中
if(!CollectionUtils.isEmpty(userList)){
//过期时间为5分钟
redisTemplate.opsForValue().set(key,userList,5, TimeUnit.MINUTES);
}
}
}
}
return userList;
}
}