阿里P6之七NoSQL数据库Redis

2019-11-28  本文已影响0人  Java及SpringBoot

个人专题目录


7. NoSQL数据库Redis

7.1 在你的项目中,哪些数据是数据库和Redis缓存双写一份的?如何保证双写一致性?

高并发场景下的redis缓存和数据库双写不一致问题分析与解决方案设计

7.2 系统上线,Redis缓存系统是如何部署的

redis cluster,10台机器,5台机器部署了redis主实例,另外5台机器部署了redis的从实例,每个主实例挂了一个从实例,5个节点对外提供读写服务,每个节点的读写高峰qps可能可以达到每秒5万,5台机器最多是25万读写请求/s。

机器是什么配置?32G内存+8核CPU+1T磁盘,但是分配给redis进程的是10g内存,一般线上生产环境,redis的内存尽量不要超过10g,超过10g可能会有问题。

5台机器对外提供读写,一共有50g内存。

因为每个主实例都挂了一个从实例,所以是高可用的,任何一个主实例宕机,都会自动故障迁移,redis从实例会自动变成主实例继续提供读写服务

你往内存里写的是什么数据?每条数据的大小是多少?商品数据,每条数据是10kb。100条数据是1mb,10万条数据是1g。常驻内存的是200万条商品数据,占用内存是20g,仅仅不到总内存的50%。

目前高峰期每秒就是3500左右的请求量

7.3 系统上线,Redis缓存给了多大的总内存?命中率有多高?抗住了多少QPS?数据流回源会有多少QPS?

http://fivezh.github.io/2019/02/11/cache-things/

命中率计算:

info命令:比如

keyspace_hits:14414110
keyspace_misses:3228654
used_memory:433264648
expired_keys:1333536
evicted_keys:1547380

7.4 热Key大Value问题,某个key出现了热点缓存导致缓存集群中的某个机器负载过高?如何发现并解决

解决热点key问题,可以有以下几种方案:

  1. 互斥锁:查询数据库的过程,只让一个线程独占,这个线程构建缓存的过程,其他线程都要等待,直到第一个线程构建完成可以从中读取数据。
  2. 提前使用互斥锁:提前使用互斥锁,和互斥锁差不多,都是让一个线程独占构建缓存,不一样的是,在构建缓存的时候。在value内部设置一个超时值timeout1,这个过期时间比实际的缓存过期时间短。当从缓存中读到timeout1已经过期的时候,就认为数据也快过期了,直接执行查询数据库,进行构建缓存的过程。这样在所有快过期的数据前,就重新构建了缓存。
  3. 永远不过期
    1. 从redis上看,确实没有设置过期时间,这就保证了,不会出现热点key过期问题,也就是“物理”不过期。
    2. 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期

Redis使用过程中经常会有各种大key的情况, 比如:

  1. 单个简单的key存储的value很大
    1. 改对象需要每次都整存整取
      1. 可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;
    2. 该对象每次只需要存取部分数据
      1. 可以像第一种做法一样,分拆成几个key-value, 也可以将这个存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性
    3. hash、set、zset、list 中存储过多的元素
      1. 类似于场景一种的第一个做法,可以将这些元素分拆。以hash为例,原先的正常存取流程是 hget(hashKey, field) ; hset(hashKey, field, value)
        现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000, 确定了该field落在哪个key上。set, zset, list 也可以类似上述做法.

7.5 超大Value打满网卡的问题如何规避

7.6 你过往的工作经历中,是否出现过缓存集群事故?说说怎么保证高可用的?

redis cluster vs. replication + sentinal

如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了

replication,一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,去保证redis主从架构的高可用性,就可以了

redis cluster,主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster

7.7 平时如何监控缓存集群的QPS和容量

Redis监控

7.8 缓存集群如何扩容?

Redis集群水平扩展

7.9 说下redis的集群原理和选举机制

Redis 集群模式的工作原理

7.10 Key寻址算法都有哪些?

分布式寻址算法

7.11 Redis线程模型画个图说说

Redis线程模型

7.12 Redis内存模型画个图说说

Redis内存模型

7.13 Redis中的Lua有没有使用过? 可以用来做什么? 为什么可以这么用?

Lua:
https://www.cnblogs.com/huangxincheng/p/6230129.html

  1. 减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延和请求次数。
  2. 原子性的操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
  3. 代码复用:客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本来完成相同的逻辑。

7.14 缓存穿透和缓存雪崩?

缓存穿透含义:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就去DB查找。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对DB造成很大的压力。这就叫做缓存穿透。

缓存穿透解决方案:

缓存雪崩含义:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给DB带来很大压力;
缓存雪崩解决方案:

上一篇 下一篇

猜你喜欢

热点阅读