常问得面试题之Redis

前言;最近我看BAT里面得面试都含有Redis相关得问题,所以就想写一片关于它得理解,希望对大家有所帮助。

我们应该首先了解什么是Redis?

  Redis 是一个使用 C 语言写成的,开源的 key-value 数据库。。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
  在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。目前,Vmware在资助着redis项目的开发和维护。

Redis与Memcached的区别与比较

   1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。

   2 、Redis支持数据的备份,即master-slave模式的数据备份。

   3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中

   4、 redis的速度比memcached快很多

   5、Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190425195618797.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NlY3V0aXJ5Xw==,size_16,color_FFFFFF,t_70)

使用redis有哪些好处?

    (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

    (2)支持丰富数据类型,支持string,list,set,sorted set,hash

    (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

    (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

项目中那些地方用到Redis?

   在中央缓存,计算机应用,实时攻防系统,排行榜,消息订阅系统,自动去重,队列,设定有效期得应用

Redis常见数据结构使用场景

  1. String
    常用命令: set,get,decr,incr,mget 等。
    String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。
    常规key-value缓存应用;
    常规计数:微博数,粉丝数等。

  2. Hash
    常用命令: hget,hset,hgetall 等
    Hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。 比如我们可以Hash数据结构来存储用户信 息,商品信息等等。
    举个例子: 最近做的一个电商网站项目的首页就使用了redis的hash数据结构进行缓存,因为一个网站的首页访问量是最大的,所以通常网站的首页可以通过redis缓存来提高性能和并发量。我用jedis客户端来连接和操作我搭建的redis集群或者单机redis,利用jedis可以很容易的对redis进行相关操作,总的来说从搭一个简单的集群到实现redis作为缓存的整个步骤不难

    3.List
    常用命令: lpush,rpush,lpop,rpop,lrange等
    list就是链表,Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,最新消息排行等功能都可以用Redis的list结构来实现。

    Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
    4.Set
    常用命令:
    sadd,spop,smembers,sunion 等
    set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的。
    当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

    在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常方便的实现如共同关注、共同喜好、二度好友等功能。
    5.Sorted Set
    常用命令: zadd,zrange,zrem,zcard等
    和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。
    举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用Redis中的SortedSet结构进行存储。

MySQL里有3000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据(redis有哪些数据淘汰策略???)

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(回收策略)。redis 提供 6种数据淘汰策略:
1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
6. no-enviction(驱逐):禁止驱逐数据

Redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
2.服务器角度,利用setnx实现锁。

注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。

Redis常见性能问题和解决方案:

1.Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
2. 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
3.为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
4. 尽量避免在压力很大的主库上增加从库

Redis与消息队列

不要使用redis去做消息队列,这不是redis的设计目标。我在做网站过程接触比较多的还是使用redis做缓存,比如秒杀系统,首页缓存等等。

缓存穿透

缓存穿透指的是使用不存在的key进行大量的高并发查询,这导致缓存无法命中,每次请求都要穿透到后端数据库系统进行查询,数据库压力过大。

常用解决方案:将空值缓存起来。

其他解决方案:使用布隆过滤器(guava 19开始已支持布隆过滤器),布隆过滤器原理与应用

缓存雪崩

缓存雪崩指缓存服务器重启或者大量缓存集中在某一个时间段内失效

常用解决办法:对不同的数据使用不同的失效时间,甚至对相同的数据、不同的请求使用不同的失效时间。

缓存优秀实践

   1)使用前对数据大小进行评估,包括缓存的数据结构、大小、数量、失效时间

   2)根据业务进行隔离,尽量不要多个业务共用一个缓存实例

   3)缓存的key尽可能的设定缓存失效时间,且失效时间不能集中在某一点

   4)缓存尽量不要存大对象

   5)写缓存时一定要写入完全正确的数据。如果缓存数据部分有效,部分无效,宁可放弃缓存

   6)一定要对操作超时时间进行设置。一般我们设计缓存作为加速数据库读取的手段,也会对缓存操作做降级处理,因此推荐使用更短的缓存超时时间,如果一定要给出一个数字,则希望是100毫秒以内

猜你喜欢

转载自blog.csdn.net/Secutiry_/article/details/89527084