一、基础概念
1、定义
redis是一个基于内存的高性能 Key-Value 数据库。
2、特点
a、速度快:因为数据存在内存中,类似于 HashMap ,HashMap 的优势就是查找和操作的时间复杂度都是O (1) 。
b、支持丰富数据类型:支持 String ,List,Hash,Set,Sorted Set五种基础的数据结构。用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性能消息队列服务。
c、单线程模型效率高:c语言实现、纯内存操作、非阻塞io多路复用、单线程避免线程上下文切换、丰富数据结构都使hash结构读取速度快。
d、6种Key 过期策略
e、支持订阅发布 Pub / Sub 功能
f、支持持久化
g、支持高可用
3、存储方式
【全量】RDB 持久化,是指在指定的时间间隔内将内存中的数据集快照写入磁盘。实际操作过程是,fork 一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
【增量】AOF持久化,以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
4、问题思考:
a、如何保证热点数据不被淘汰?
方案:volatile-lfu ,根据最近最少使用淘汰数据,更加符合“热”的概念,频率越高,代表越热。
b、雪崩现象处理。
含义:雪崩是指redis缓存集中过期。
方案:一般需要在过期时间上加一个随机值,使得过期时间分散一些。
5、数据类型应用场景
以下数据demo使用springboot封装的的StringRedisTemplate模板。
maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
注入模板类:
@Autowired
private StringRedisTemplate stringRedisTemplate;
a、字符串 String:作为常规的key-value缓存应用。例如点赞数、粉丝数、login用户信息。
// 点赞数520,5s后过期,kv只能是string类型
stringRedisTemplate.opsForValue().set("likes", "520", 5, TimeUnit.SECONDS);
String str = stringRedisTemplate.opsForValue().get("likes");
System.out.println("string likes = " + str);
Assert.assertEquals("520", stringRedisTemplate.opsForValue().get("likes"));
b、字典Hash:存储对象(因为对象可能会包含很多属性)
image.png
// hash H、V、hk、hv, 只能是string
stringRedisTemplate.opsForHash().put("user", "age", "18");
stringRedisTemplate.opsForHash().put("user", "name", "lois");
stringRedisTemplate.expire("user", 5, TimeUnit.SECONDS);
Map<Object,Object> user = stringRedisTemplate.opsForHash().entries("user");
System.out.println("hash user = " + user);
c、列表List:粉丝列表、消息列表、热点文章列表
// list kv只能是string
stringRedisTemplate.opsForList().leftPush("fans", "王小明");
stringRedisTemplate.opsForList().leftPush("fans", "王小飞");
stringRedisTemplate.opsForList().leftPush("fans", "王小龙");
stringRedisTemplate.expire("fans",5,TimeUnit.SECONDS);
System.out.println("list fans = " + stringRedisTemplate.opsForList().range("fans", 0, -1));
d、集合Set: 求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好等功能。
// set kv只能是string
stringRedisTemplate.opsForSet().add("follow1","1", "2", "3","4");
stringRedisTemplate.expire("follow1", 5, TimeUnit.SECONDS);
stringRedisTemplate.opsForSet().add("follow2","5", "6", "3","4");
stringRedisTemplate.expire("follow2", 5, TimeUnit.SECONDS);
Set intersects = stringRedisTemplate.opsForSet().intersect("follow1","follow2");
System.out.println("set intersects = " + intersects);
结果:
set intersects = [3, 4]
e、有序集合 SortedSet
排行榜:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,跳跃表按score从小到大保存所有集合元素。使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
// zset kv只能是string
stringRedisTemplate.opsForZSet().add("ranking", "王小明", 3);
stringRedisTemplate.opsForZSet().add("ranking", "王小飞", 1);
stringRedisTemplate.opsForZSet().add("ranking", "王小龙", 5);
stringRedisTemplate.opsForZSet().add("ranking", "王小红", 9);
stringRedisTemplate.opsForZSet().add("ranking", "王小绿", 7);
stringRedisTemplate.expire("ranking",5,TimeUnit.SECONDS);
System.out.println("升序 zset ranking = " + stringRedisTemplate.opsForZSet().range("ranking",0, -1));
System.out.println("降序 zset ranking = " + stringRedisTemplate.opsForZSet().reverseRange("ranking",0, -1));
结果:
升序 zset ranking = [王小飞, 王小明, 王小龙, 王小绿, 王小红]
降序 zset ranking = [王小红, 王小绿, 王小龙, 王小明, 王小飞]
网友评论