金蝶面试题

Redis数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

缓存穿透,击穿,雪崩是什么?如何避免?

缓存处理流程

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

 

一、缓存穿透(数据库中不存在的数据)

1.什么是缓存穿透?

缓存穿透指的是:同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。由于大量的并发请求到达数据库,而数据库承受不住这么高的并发,从而导致数据库奔溃,这就是缓存穿透。 

 

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

2.如何避免?

1.将空数据存入缓存

对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。

2.布隆过滤器

采用布隆过滤器,将所有可能存在的数据存到一个bitMap中,不存在的数据就会进行拦截。

二、缓存击穿(缓存失效的问题)

      1.什么是缓存击穿?

缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db(数据库)

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

热点key:某个key访问非常频繁,当key失效的时候有大量线程来构建缓存,导致负载增加,系统奔溃。

 

2.如何避免?

异步更新缓存

1.自动更新

redis是支持查询某个key剩余有效时间,所以这里我们只需要设定一个时间差,比如3分钟,请求的时候查询的有效时间如果小于3分钟,那么刷新这个key的有效时间,刷新这个操作可以使用异步实现(提高性能)。

 

可能你想到了,这种方式存在缺陷,没错,如果再快失效的3分钟内没有请求,那么缓存中的key将不会被刷新,还是会存在缓存击穿的问题,所以这种方式不是特别推荐。

2.定时刷新

      定时刷新有两种方案

      第一种:定时任务

      查询快要过期的key,更新内容,并刷新有效时间,这种比较消耗服务器性能,也不是特别推荐。

      第二种:延迟队列

      如果大家了解它的话可能一下就知道我说的是什么意思了,将数据存入缓存的那一刻同时发送一个延迟队列(安指定时间消费),时间小于缓存中key的过期时间,到了指定时间,消费者刷新key的有效时间再发送一个延迟队列,以此循环,这种方式还是不错的,但是实现方式相对于第一种来说就要复杂一点了,他需要依靠消息中间件来完成,如果消息中间件某个时间宕机,那就gg了,虽然这种方式虽然比较推荐,但是成本偏高,因为为了防止消息中间件宕机,我们有可能需要对消息中间件做集群处理。

3.程序加锁

1.使用锁,单机用synchronized,lock等,分布式用分布式锁

我个人推荐使用这个,为什么呢?因为它不需要额外的服务器开销,也不需要额外的资源消耗,他仅仅只是让线程串行而已,但是这个时候你可能就会有疑问了,加锁不是会严重影响程序的效率吗?为什么你还推荐这种方式呢?

其实并不是所有的锁都会很大的降低程序的性能,这里我们当然不能使用synchronized,原因很简单,他的效率比较慢,不太适合这种情况,我要介绍的这种锁名字为:读写锁。

三、缓存雪崩

1.什么是缓存雪崩?

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。

雪崩:缓存大量失效的时候,引发大量查询数据库。

雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

2.如何避免

1.用锁/分布式锁或者队列串行访问

在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。

2.缓存失效时间均匀分布

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀。在原来过期时间的基础上生成一个随机时间,这个随机时间比较小,然后两者相加即可。

如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中

3.设置热点数据永远不过期。

将一些常用的数据设置成为永久有效,注意哦,是经常使用的而不是全部,这点需要特别注意。

总结

什么是缓存穿透?

同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。

什么是缓存击穿?

缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db(数据库)。

什么是缓存雪崩?

缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机

缓存击穿和缓存穿透区别

缓存击穿和缓存穿透有点像但是性质又不相同,都是缓存中没有数据,请求命中数据库,缓存穿透指的是数据库中不存在的数据,缓存击穿则是指缓存失效的问题。

缓存雪崩和缓存击穿区别

和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

Redis介绍

https://www.cnblogs.com/xuanyuan/p/13665170.html

Redis持久化怎么实现的?

11.1.简介

数据存放于:

内存:高效、断电(关机)内存数据会丢失

硬盘:读写速度慢于内存,断电数据不会丢失

11.2.RDB

8月  23  20:26 bin

8月  31  12:09 dump.rdb

8月  23  20:30 redis.conf

RDB:是redis的默认持久化机制。RDB相当于照快照,保存的是一种状态。几十G数据----》几KB快照**

快照是默认的持久化方式。这种方式就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

优点:

快照保存数据极快、还原数据极快,适用于灾难备份

缺点:

小内存机器不适合使用,RDB机制符合要求就会快照

快照条件:

​         1、服务器正常关闭时  ./bin/redis-cli shutdown

​         2、key满足一定条件,会进行快照

vim redis.conf  搜索save

:/save

save 900 1   //每900秒(15分钟)至少1个key发生变化,产生快照

save 300 10 //每300秒(5分钟)至少10个key发生变化,产生快照

save 60  10000  //每60秒(1分钟)至少10000个key发生变化,产生快照

11.3.AOF

由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式

 

Append-only file:aof 比快照方式有更好的持久性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write 函数追加到文件中(默认是appendonly.aof)。当Redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

 

有三种方式如下(默认是:每秒fsync 一次)

- appendonly yes //启用aof持久化方式

- #appendfsync always  //收到写命令就立即写入磁盘,慢慢,但是保证完全的持久化

- appendfsync everysec  //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中

- #appendfsync no //完全依赖os,性能最好,持久化没保证

产生的问题:

aof的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用 incr test 命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。

面向对象的三个基本特征

封装、继承、多态

 

posted @ 2020-11-18 17:01  海绵-宝宝  阅读(208)  评论(0编辑  收藏  举报