Welcome to Doris′s Blog

Redis必知

Java后端知识点汇总——Redis专题

全套Java知识点汇总目录,见https://www.cnblogs.com/ying-dong/p/11831922.html

——参考于码农求职小助手公众号

1,Redis支持的数据类型?

String(字符串类型)

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

常用命令: set,get,incr,decr,mget 等:set key value 设置值、 get key 获取值、 incr key 加一、 decr key 减一​

hash(哈希)

   Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。

常用命令: set,get,decr,incr,mget 等:
hset key field value 设置值
hget key field 获取值
hincrby key field num 设置增数量

list(列表)

  Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。

  Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,消息列表等功能都可以用Redis的 list 结构来实现。

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

常用命令: lpush,rpush,lpop,rpop,lrange等:
lpush list a b c d (从list左边添加元素)、 rpush list 1 2 3 4 (从list右边添加元素)
lrange list 0 -1(从0 到 -1 元素查看:也就表示查看所有)
lpop list (从list左边取,删除)、 rpop list (从list右边取,删除)

set(集合)

  Redis的Set是string类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

常用命令: sadd,spop,smembers,sunion 等:
sadd set1 a b c d d (向set1中添加元素) 元素不重复
smembers set1(查询元素)、 srem set1 a(删除元素)
sorted set(zset,有序集合)

zset/sortedset(有序集合)

  和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。

  例:在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 Sorted Set 结构进行存储。

 

常用命令: zadd,zrange,zrem,zcard等:
zadd zset1 1 a 2 b 3 c (添加元素 zadd key score member,这里添加元素a:1分、元素b:2分、元素c:3分 )
zrange zset1 0 -1 (查看zset1的所有元素,默认从小到大)
zrange zset1 0 -1 withscores (查看zset1的所有元素,包括分数score)
zrevrange zset1 0 -1 (查看zset1的所有元素,从大到小)
zincrby zset1 5 a (对zset1的a元素增加5分)

2,什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么

 1). 持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

   (Redis 数据都放在内存中。如果机器挂掉,内存的数据就不存在。所以需要做持久化,将内存中的数据保存在磁盘,下一次启动的时候就可以恢复数据到内存中。)

 2). Redis 提供了两种持久化方式:RDB(默认) 和AOF 。

  RDB (快照):

  Redis可以通过创建快照来 获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性能),还可以将快照留在原地以便重启服务器的时候使用。

  快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照

  AOF(只追加文件):  

  与快照持久化相比,AOF持久化的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:appendonly yes

  开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof。

  在Redis的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进行同步

  为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

 3)优缺点

  RDB (快照):快照形式 ,定期将当前时刻的数据保存磁盘中。会产生一个dump.rdb文件

    特点:性能较好,数据备份。但可能会存在数据丢失。

  AOF(只追加文件) :append only file (所有对redis的操作命令记录在aof文件中),恢复数据,重新执行一遍即可。

    特点:每秒保存,数据比较完整。但耗费性能。  

  【注】如果两个都配了优先加载AOF。(同时开启两个持久化方案,则按照 AOF的持久化放案恢复数据。)

3,Redis 有哪些架构模式?讲讲各自的特点?

  主从模式(redis2.8版本之前的模式): 主负责写,从负责读,读写分离分散了主服务器的一部分压力,但如果主服务器奔溃,从服务器不能主动上升,使得不能进行写操作,此时就引申下一个哨兵模式

  哨兵sentinel模式(redis2.8及之后的模式) : 在主从复制模式下添加一个"哨兵",监视主服务器的运行状况,一旦当机其余的从服务器根据选举模式"推举"从服务器上升,而从服务器还原后自动成为从

       redis cluster集群模式(redis3.0版本之后): 尽管主从复制模型分散了主服务的一部分压力,但主服务器仍然处于"中心位",压力仍然很大,此时使用集群模式,每个集群中的成员都具有读和写的功能,此时就需要一种机制来确定某一数据存放于哪个服务器➡类似于Hash表,一个服务器相当于一个槽,根据某种算法来计算key对应的值,在不同的区间,对应存于不同的槽位 , 而获取时每个服务器会根据算法计算key的值判断区间从而确定将请求路由到哪台服务器,这种"去中心化"机制将中心位的压力分散,具有良好的性能

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

  缓存穿透 : 

    一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。

    而同一时间利用一些手段制造大量的恶意请求,故意查询不存在的key , 就会对后端系统造成很大的压力,甚至导致系统奔溃 , 这就叫做缓存穿透。

      同一时间大量恶意的不存在的key查询

    如何避免?

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

    2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤

    3:也可以使用流行的bloom filter布隆过滤器

  缓存雪崩 : 

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

       同一时间大量存在的key失效后的查询

   如何避免?

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

    2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

    3:不同的key,设置不同的过期时间(随机的过期时间),让缓存失效的时间点尽量均匀,不集中于同一时间点。

posted on 2020-04-14 11:15  Doris董  阅读(298)  评论(0编辑  收藏  举报

导航