1 、在项目中缓存是如何使用的?

2、为啥在项目里要用缓存呢?

用缓存,主要用途,高性能和高并发

高性能

场景举例:假如有这么一个操作,用户发起请求,操作数据库,查出结果,耗时600ms,然后这个结果,在一段时间内都不会改变,或者说改变了也不用立即向用户反馈,那么这个时候就可以用缓存了,把查出来的结果直接放到缓存里,下次再有人来请求,就直接在缓存里通过key value键值对给到用户,性能提高!

简单的说就是,把一个复杂耗时的操作的结果,后面不怎么需要改变的结果,但是有很多的读取操作,就可以使用缓存,后面读取的时候直接从缓存中读就可以了。

高并发:因为数据库不支持高并发,像mysql最高也就支持到2000,然后我们把数据放到缓存中去,轻轻松松的十几万的并发,是mysql的几十倍。

3 、使用缓存有什么缺点?

1)缓存与数据库双写不一致

2)缓存雪崩

3)缓存穿透

4)缓存并发竞争

4、redis和memcached有什么区别?

redis:线程模型是单线程NIO异步的工作模型。

  1. 数据结构 :redis拥有更多的数据结构和更多的数据结构,很多复杂的操作跟高效

2.集群redis官方就是支持redis cluster集群模式,而menacahe不支持,需要依赖客户端。

5、redis都有哪些数据类型?

String

用来抢购,用来限制库存数量做一个计数器,就可以用string类型

分布式锁

string类型的setnx的作用是“当key不存在时,设值并返回1,当key已经存在时,不设值并返回0”,“判断key是否存在”和“设值”两个操作是原子性地执行的,因此可以用string类型作为分布式锁,返回1表示获得锁,返回0表示没有获得锁。

list

是一个有序列表,

可以用来做简单的点对点消息队列,和可以用来做粉丝列表,评论列表,

还可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这个很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走

set

无序集合,自动去重

可以用于去重,将需要去重的数据放进去。自动去重,

如果需要对一些数据进行进行快速的全局去重,可以使用jvm的hashSet进行去重,但是如果是在多台机器上的话就需要用redis的set进行去重,

也可以基于set对数据进行交集,并集,差集操作。比如,微博里的粉丝可以做一个交集,就可以查看两个人的共同好友

黑名单/白名单

sorted set

可以去重,有序。

可以用来做排行榜,比如商品的销量排行 收藏排行等

hash

这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在redis里,然后每次读写缓存的时候,可以就操作hash里的某个字段。 比如项目中可以哟来做购物车用户id为key 商品id为field,商品数量为value;

结构:

key=150

value={

“id”: 150,

“name”: “zhangsan”,

“age”: 20

}

6、redis的过期策略都有哪些?

设置过期时间定期删除和惰性删除最后走内存淘汰机制

7、内存淘汰机制都有哪些?

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用

2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的key给干掉啊

4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适)

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

8、手写一下LRU代码实现?

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
   
private final int CACHE_SIZE;    // 这里就是传递进来最多能缓存多少数据
   public LRUCache(int cacheSize) {
       super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); // 这块就是设置一个hashmap的初始大小,同时最后一个true指的是让linkedhashmap按照访问顺序来进行排序,最近访问的放在头,最老访问的就在尾
       CACHE_SIZE = cacheSize;
  }    @Override
   protected boolean removeEldestEntry(Map.Entry eldest) {
       return size() > CACHE_SIZE; // 这个意思就是说当map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据
  } }

9、如何保证redis的高并发以及高可用?

redis单机的瓶颈 能够承受的QPS大概就是在1万到几万

使用redis replication 主从实现读写分离支撑10万+的高并发,将架构做成主从架构,一主多从,主负责写,将数据同步到从节点上,从节点负责读,所有的读取请求都走从节点,这个架构支持水平扩容,只需要再在增加从节点就OK

10、redis replication的核心机制

(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量 (2)一个master node是可以配置多个slave node的 (3)slave node也可以连接其他的slave node (4)slave node做复制的时候,是不会block master node的正常工作的 (5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了 (6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量slave,高可用性,有很大的关系

11、master持久化对于主从架构的安全保障的意义

如果采用了主从架构,那么建议必须开启master node的持久化!

不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了

master -> RDB和AOF都关闭了 -> 全部在内存中

master宕机,重启,是没有本地数据可以恢复的,然后就会直接认为自己的数据是空的

master就会将空的数据集同步到slave上去,所有slave的数据全部清空

100%的数据丢失

master节点,必须要使用持久化机制

第二个,master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的

即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障

12、主从架构的核心原理

当启动一个slave node的时候,它会发送一个PSYNC命令给master node

如果这时slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization

开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

2、主从复制的断点续传

从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份

master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制

但是如果没有找到对应的offset,那么就会执行一次resynchronization

3、无磁盘化复制

master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

repl-diskless-sync repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来

4、过期key处理

slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

13、redis主从架构下如何实现高可用?

主备切换。或者叫故障转移,需要我们在主从架构中加入entinal node(哨兵)负责监控master node 和slave node的进程是否正常工作。 一旦检查到master挂掉之后,就会发送消息通知到管理员,同时将其中一个salve升级为master 提供写和同步的功能,因为salve上的数据和master上的数据是一样的。最后通知client客户端新的master地址

哨兵作为维护主从架构的高可用,其自身是一个分布式的,并且至少需要3个哨兵实例来保证自己的健壮性

其次:哨兵+redis主从架构,是不会保证数据不丢失,只能保证redis集群的高可用性。

redis的一些常见面试题的更多相关文章

  1. redis知识点及常见面试题

    redis知识点及常见面试题 参考: https://zm8.sm-tc.cn/?src=l4uLj4zF0NCIiIjRnJGdk5CYjNGckJLQrIqNiZaJnpOWjIvQno2Llpy ...

  2. 测开常见面试题什么是redis

    企业中redis是必备的性能优化中间件,也是常见面试题,首先Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Rem ...

  3. 整理的最全 python常见面试题(基本必考)

    整理的最全 python常见面试题(基本必考) python 2018-05-17 作者 大蛇王 1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in ...

  4. PHP常见面试题汇总(二)

    PHP常见面试题汇总(二)   //第51题:统计一维数组中所有值出现的次数?返回一个数组,其元素的键名是原数组的值;键值是该值在原数组中出现的次数 $array=array(4,5,1,2,3,1, ...

  5. python爬虫常见面试题(二)

    前言 之所以在这里写下python爬虫常见面试题及解答,一是用作笔记,方便日后回忆:二是给自己一个和大家交流的机会,互相学习.进步,希望不正之处大家能给予指正:三是我也是互联网寒潮下岗的那批人之一,为 ...

  6. 整理的最全 python常见面试题

      整理的最全 python常见面试题(基本必考)① ②③④⑤⑥⑦⑧⑨⑩ 1.大数据的文件读取: ① 利用生成器generator: ②迭代器进行迭代遍历:for line in file; 2.迭代 ...

  7. java常见面试题及答案 1-10(基础篇)

    java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...

  8. Web开发的常见面试题HTML和HTML5等

    作为一名前端开发人员,HTML,HTML5以及网站优化都是必须掌握的技术,下面列举一下HTML, HTML5, 网站优化等常见的面试题: HTML常见面试题: 1. 什么是Semantic HTML( ...

  9. 常见面试题之ListView的复用及如何优化

    经常有人问我,作为刚毕业的要去面试,关于安卓开发的问题,技术面试官会经常问哪些问题呢?我想来想去不能一股脑的全写出来,我准备把这些问题单独拿出来写,并详细的分析一下,这样对于初学者是最有帮助的.这次的 ...

随机推荐

  1. 开源项目SMSS发开指南(五)——SSL/TLS加密通信详解(下)

    继上一篇介绍如何在多种语言之间使用SSL加密通信,今天我们关注Java端的证书创建以及支持SSL的NioSocket服务端开发.完整源码 一.创建keystore文件 网上大多数是通过jdk命令创建秘 ...

  2. Codeforces_798

    A.暴力把每个位置的字符改成另外25个字符,判断是否回文. #include<bits/stdc++.h> using namespace std; string s; int main( ...

  3. Codeforces_723_A

    http://codeforces.com/problemset/problem/723/A 取中间那个数就可以了,答案为最大值减最小值. #include<iostream> #incl ...

  4. js - 构造函数-静态属性/方法-原型对象 - 前端第八课

    先来个普通对象 var duixiang={ a:"111", b:function (s) { return s+"886"; } }; console.lo ...

  5. java11类和对象

    import java.util.Scanner; public class jh_01_如何认识事物 { public static void main(String[] args) { Scann ...

  6. 题解 UVA1479 【Graph and Queries】

    \[ \text{Preface} \] 算是一道思维难度稍易,代码难度稍难的题吧. \[ \text{Description} \] 给出一张 \(n\) 个点,\(m\) 条边的图,点带权.需要支 ...

  7. Go语言实现:【剑指offer】二叉搜索树的后序遍历序列

    该题目来源于牛客网<剑指offer>专题. 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. Go ...

  8. Go语言实现:【剑指offer】正则表达式匹配

    该题目来源于牛客网<剑指offer>专题. 请实现一个函数用来匹配包括 . 和 * 的正则表达式.模式中的字符.表示任意一个字符,而 * 表示它前面的字符可以出现任意次(包含0次). 在本 ...

  9. vue学习(四)登陆、注册、首页模板页区分

    按照上面文章配置完毕后,会发现有个问题,我登陆页面.注册页面是不需要视图页的. 开始配置路由 重新配置main.js 引入 import App from './App' //引入vue组件 更改启动 ...

  10. 阿里云ECS服务器,mysql无法外网访问

    可参考https://www.jianshu.com/p/7a41734b502e 问题原因 未授权远程IP地址登录.root用户默认只能在localhost也就是本机登录 解决方案 在服务器上登录数 ...