一、Redis是什么

        Redis,即远程字典服务,是一个开源的用C语言开发的基于内存的高性能key-value数据库。由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,所以,Redis提供了持久化存储机制,将数据以某种形式保存在文件中,每次重启时,可以自动从文件加载到内存中。

二、Redis优缺点

优点:

  • Redis不仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不只能作为key-value数据库使用,还提供了消息中间件的部分功能。

缺点:

  • 由于Redis是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小有关。虽然Redis本身有key过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
  • Redis是单线程的(6.0变为多线程),单台服务器无法充分利用多核服务器的CPU。

三、典型的使用场景

Redis可以作为数据库、缓存中间件、消息中间件

  1. 缓存:合理的利用缓存可以提升系统访问速度,还能大大降低数据库的压力。Redis提供了键过期功能,以及灵活的键淘汰策略,现在Redis用在缓存的场合非常多。如:分布式session、静态页缓存、会话Token缓存、购物车等。
  2. 排行榜:Redis提供的有序集合数据结构能实现各种复杂的排行榜应用。
  3. 计数器:如浏览量、播放量等。Redis提供的incr命令来实现计数器功能,内存操作,性能非常好。
  4. 分布式会话:集群环境下,在应用不多的情况下,一般使用容器自带的session复制功能就能满足,当应用增多相对复杂的系统中,一般都会搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,而是由session服务及内存数据库管理。
  5. 分布式锁:分布式技术带来的技术挑战是对同一个资源的并发访问,如全局id,减库存,秒杀等场景。并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在高并发场合中,使用数据库锁控制资源的并发访问大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁。
  6. 社交网络 点赞、踩、关注/被关注、共同好友等基本功能:访问量通常来说比较大,Redis提供的哈希、集合等数据结构能很方便的实现这些功能。
  7. 最新列表:Redis列表结构,LPUSH可以再列表头部插入一个内容ID作为关键字,LTRIM可用来限制列表的数量,这样列表永远为N个id,无需查询最新的列表,直接根据id去到对应的内容页即可。
  8. 消息系统:主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统,当然,这不能和专业的消息中间件(ActiveMQ、RabbitMQ、Kafka)相比。

四、Redis5支持的淘汰算法

1、LRU

        LRU(Least recently  userd,最近最久未使用算法):算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近没有被访问过,那么将来被访问的几率也会比较低”。

2、LFU

        LFU(Least Frequently Used,最近最少使用算法):算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果一个数据在最近一段时间很少被访问到,那么可以认为在将来他被访问的可能性也很小”。

3、LRU和LFU的区别

        LRU淘汰最长时间未被使用的数据,LFU淘汰一定时期内被访问次数最少的数据。

4、Random

        Ramdom(随机删除):随机删除key。

注意:LRU和LFU都是采样淘汰,即每次只扫描部分的key来按照算法删除,而不是扫描所有的key,每次扫描的key数量通过maxmemory-samples<count>来配置,默认扫描5个就可以。

五、数据持久化

        Redis虽然是一个内存数据库,但是其中保存的数据应该提供持久化(数据保存到硬盘),以避免Redis重启后从数据库加载数据。Redis的持久化实现方式有三种:RDB、AOF、混合持久,默认使用RDB。AOF和RDB可以同时启用,但是加载时优先使用AOF。

1、RDB(Redis DataBase)

        RDB文件本质上是一份压缩的二进制内存快照,保存了创建RDB文件那个时间点的Redis的全量数据,具有数据文件小,全量创建、恢复快的优点,但是由于快照的特性无法保存创建RDB之后的增量数据。

  • 优点:RDB是一个紧凑的二进制文件,代表Redis在某个时间点上的数据快照。使用与备份、全量复制等场景。Redis加载RDB恢复数据远远快于AOF的方式。
  • 缺点:RDB不能做到实时持久化。Redis进程会执行fork操作创建子进程,RDB持久化进程由子进程负责,完成后自动结束,阻塞会发生在fork阶段。

2、AOF(Append  Only File) 

        AOF文件的本质是一份执行日志,保存所有对Redis进行更改的命令。AOF文件基本上是人类可读的文本,所以其体积相对较大,在从AOF文件恢复数据时就是做日志回放,执行AOF文件中记录的所有命令,所以相对RDB而言恢复耗时较长。

  • 优点:AOF日志文件以append-only模式写入,写入性能比较高,所以写入频率可以配置的高点(默认1秒,故障时最多丢1秒的数据)。AOF日志文件的命令通过非可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复,当然要在重写前拷贝AOF文件。
  • 缺点:相对RDB数据快照文件更大,做数据恢复的时候,会比较慢,还有做冷备,定期的备份,不太方便。

3、混合持久

        4.0加入的新功能, AOF文件过大时,Redis会重写AOF文件,重写时先以RDB格式写入全量数据再追加增量日志,该选项默认开启:aof--use-rdb-preamble yes

六、Redis分布式锁

         为了实现不同的进程以互斥方式访问共享资源,需要使用分布式锁。Redis的key-value可以模拟实现分布式锁。

   Redis单实例模式:

  • 加锁过程:在Redis中放入一个带有过期时间的key-value,使用nx表示只有不存在key时才放入(如果存在,表示其他客户端放了,也就是已被其他客户端加锁),使用失效时间避免死锁,value中要能表示客户端,避免误解锁。
  • 解锁过程:获取key对应的value,如果value是当前客户端放入的value,则删除。

Redis主从、集群模式:

  • 加锁过程: 在主从、集群模式上,如果也采用单实例模式加锁过程,可能会导致锁失效的问题,如:客户端A放入了key-value,但是当Redis将数据从主节点复制到从节点时,发生了故障,kv复制不成功,而主从切换完成后,原来的从实例,现在的主实例上没有锁key,则客户端B可以获取锁,这时A、B客户端都持有一个锁。
  • 对于主从、集群模式下的分布式锁,有RedLock算法,在多个不相关的(非集群、非主从)实例上加锁(放入key),如果半数以上节点加锁成功,则本客户端加锁成功。如:5个独立的实例中加锁,如果3个实例加锁成功,则本客户端加锁成功。解锁过程也需要在多个实例上解锁。这可以实现主从、集群模式下的安全加锁,但是需要自己实现,或者而采用已经实现RedLock算法的客户端。如:Redisson