Redis 热点名词

1. redis的几种数据结构

redisTemplate 实现

private void fiveBasicDataType(){
    long expires = 1000;
    // string
    redisTemplate.opsForValue().set("string", 1, expires, TimeUnit.SECONDS);
    // hash
    String hashKey = "hash";
    redisTemplate.opsForHash().put(hashKey, "A", "aaa");
    redisTemplate.opsForHash().put(hashKey, "B", "bbb");
    redisTemplate.expire(hashKey, expires, TimeUnit.SECONDS);
    // list
    redisTemplate.opsForList().leftPushAll("list", "A", "B", "C", "D", "A");
    redisTemplate.expire("list", expires, TimeUnit.SECONDS);
    // set
    redisTemplate.opsForSet().add("set", "A", "B", "C", "D", "A");
    redisTemplate.expire("set", expires, TimeUnit.SECONDS);
    // sorted set
    redisTemplate.opsForZSet().add("zset", "A", 2.0);
    redisTemplate.opsForZSet().add("zset", "B", 1.0);
    redisTemplate.opsForZSet().add("zset", "C", 3.0);
    redisTemplate.expire("zset", expires, TimeUnit.SECONDS);
}

2. 缓存雪崩

现象:在原缓存失效,新缓存尚未到达的期间,由于使用了相同过期时间策略,缓存数据在同一时间失效,所有原本应该查询缓存的请求在该时间去查数据库,给数据库的CPU和内存造成了巨大的压力。从而使数据库宕机,

解决:

[1] 均匀分布。缓存数据根据key,采用不同的时间策略(比如加上随机数生成的几秒钟),使之不在同一时间失效。

[2] 熔断机制。访问QPS达到一定级别后自动熔断。

3. 缓存穿透

现象:访问一个redis和数据库均不存在的key值。每次请求该key值后,都会先走redis,再走数据库,进行无效查询。

解决:

[1] 布隆过滤。将redis的所有key值统一放在一个map,查询时先查询map有无此值,没有该值则直接返回空。

[2] 缓存空值。数据库中查询key对应value不存在后,将空值缓存起来,下次查询直接查询redis返回空值。

4. 缓存击穿

现象: 单一key缓存在某一时间点过期,而未被更新时,被超高并发地访问。大并发的请求瞬间把DB压垮。

解决:

[1] 失效后使用互斥锁加锁刷新,仅有第一个查询达到数据库,执行缓存更新后释放锁;其他未拿到锁的等待50ms后继续查询缓存。

5. 分布式锁,分布式锁的原子性

利用redis的setNX set if not exist

[1] 单实例下的实现。使用 key + value + requestId 去获取锁,获取成功,执行成功后,根据 key + requestId 释放锁。requestId

[问题] 加锁的时间。过长:业务执行完,释放锁失败,需要redis自动释放,其他线程阻塞。过短:业务执行超时,锁提前释放,下一个线程进来,造成数据不一致;循环后,多个线程同事进来,失去了锁的效果。

[解决] 设置一个差不多的时间,同时启动一个守护线程。在业务代码仍在执行期间,自动延长锁的超时时间。

6. 实现原理,一致性hash

[问题] redis集群的核心是路由算法,及任一key最终缓存到哪一个服务器。简单的hash取余(key%服务器数量)算法,在缓存服务器上线、下线的时候,将有一大部分key值不能命中。为了提高redis集群中的缓存命中率,引入一致性hash。

[原理] 关键词:一致性hash环,虚拟节点。对于集群中的每台服务器,先按照2的32次方取余,得到各自服务器所在的位置。对于系统中每一个缓存key,也按照2的32次方取余,从而得到各自所在的位置,距离缓存key位置最近的服务器,就是缓存的目标服务器。同时为了保证服务器的均匀分布,引入虚拟节点的概念,即将物理服务器复制多份,复制的服务器最终指向实际的物理服务器。

7. redis跳跃表

[场景] 在redis的有序集合数据结构(sorted set)中使用。解决链表的查询效率问题。

[原理] 关键词:多层链表,随机层数。类似于链表+二分法。跳跃表可以看成由多个链表组成,第一层的链表为所有数据,链表的单个数据有1/4的概率存储进上一层,数据的最高层数可指定,但是不能超过2的32次方。进行数据查询的时候,先从顶层查起,类似于二分法的定位。新插入数据的层数随机决定,从而大大降低了跳跃表的维护难度。

8. redis的单线程优缺点

[优点] 复杂数据结构修改前提下,不需要考虑锁的开销。不需要考虑线程上下文切换线程的开销。

[缺点] 无法发挥多核CPU的高性能。

9. redis消息队列

redis 可以用来做消息队列。但是大家更喜欢用MQ或者kfaka。

10. redis集群方式,redis高可用

redis的三种集群方式
[1]主从复制。一主多从,主写从读。主从定时同步数据。

[2]哨兵模式。主从模式之外,哨兵定时检测主机状态,确认主机不能提供服务后,手动切换主机。

[3]分布式部署,无中心模式。应用一致性hash,不同的key均匀存储到不同的服务器节点。

11 业务场景性质问题

  1. 获取商城商品排行榜,如果用redis提高性能,你会如何去做

[1] 使用redis有序列表,缓存排序数据

  1. 用redis,设计秒杀系统

[2] 缓存热点数据。库存

原文地址:https://www.cnblogs.com/tuofan/p/12558731.html