什么是redis?
Redis 是一个使用 C 语言写成的,开源的 key-value 数据库。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
redis为什么这么快?
- 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);
- 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;
- 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
- 使用多路 I/O 复用模型,非阻塞 IO;
- 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
redis有哪些数据类型?
五种基本数据类型
- string:字符串类型,常被用来存储计数器,粉丝数等。简单的分布式锁也会用到该类型
- hashmap:key-value类型,value是一个map
- list:基本的数据类型,列表。在redis中可以把redis用作栈、队列、阻塞队列
- set: 集合,不能有重复元素,可以用作点赞,收藏
- zset:有序集合,不能有重复元素,有序集合中的每个元素都需要指定一个分数,根据分数进行排序。可以用作排行榜
三种特殊的数据类型
- geospatial:redis在3.2推出Geo类型,该功能可以推算出地理位置信息,两地之间的距离
- hyperloglog:基数 数学上集合的元素个数,是不能重复的。这个数据结构常用于统计网站的UV
- bitmap
redis过期键的删除策略
-
惰性删除:只有访问这个键时才会检查它是否过期,如果过期则清除。
优点: 最大化地节约CPU资源。
缺点: 如果大量过期键没有被访问,会一直占用大量内存。
-
定时删除:为每个设置过期时间的key都创造一个定时器,到了过期时间就清除。
优点: 该策略可以立即清除过期的键。
缺点: 会占用大量的CPU资源去处理过期的数据。
-
定期删除:每隔一段时间就对一些键进行检查,删除其中过期的键。该策略是惰性删除和定时删除的一个折中,既避免了占用大量CPU资源又避免了出现大量过期键不被清除占用内存的情况。
redis内存淘汰机制
在redis4.0之前一共有6中淘汰策略
- volatile-lru:当Redis内存不足时,会在设置了过期时间的键中使用LRU算法移除那些最少使用的键。(注:在面试中,手写LRU算法也是个高频题,使用双向链表和哈希表作为数据结构)
- volatile-ttl:从设置了过期时间的键中移除将要过期的
- volatile-random:从设置了过期时间的键中随机淘汰一些
- allkeys-lru:当内存空间不足时,根据LRU算法移除一些键
- allkeys-random:当内存空间不足时,随机移除某些键
- noeviction:当内存空间不足时,新的写入操作会报错
在redis4.0之后可以增加2个
- volatile-lfu:从设置过期时间的键中移除一些最不经常使用的键(LFU算法:Least Frequently Used))
- allkeys-lfu:当内存不足时,从所有的键中移除一些最不经常使用的键
redis的持久化
RDB
RDB是redis默认的持久化方式,按照一定的时间间隔将内存的数据以快照的形式保存到硬盘,恢复时是将快照读取到内存中。RDB持久化实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
优点:
- 适合对大规模的数据恢复,比AOF的启动效率高
- 只有一个文件 dump.rdb,方便持久化
- 性能最大化,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
缺点:
- 数据安全性低,在一定间隔时间内做一次备份,如果Redis突然宕机,会丢失最后一次快照的修改
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
AOF
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
优点:
- 具备更高的安全性,Redis提供了3种同步策略,分别是每秒同步、每修改同步和不同步。相比RDB突然宕机丢失的数据会更少,每秒同步会丢失一秒种的数据,每修改同步会不会丢失数据。
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作,可以通过该文件完成数据的重建。
缺点:
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
- 根据AOF选择同步策略的不同,效率也不同,但AOF在运行效率上往往会慢于RDB
什么是redis的事务
Redis的事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断,所以Redis事务是在一个队列中,一次性、顺序性、排他性地执行一系列命令。
Redis 事务的主要作用就是串联多个命令防止别的命令插队。
redis事务的特性
- Redis事务不保证原子性,单条的Redis命令是原子性的,但事务不能保证原子性。
- Redis事务是有隔离性的,但没有隔离级别,事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。(顺序性、排他性)
- Redis事务不支持回滚,Redis执行过程中的命令执行失败,其他命令仍然可以执行。(一次性)
redis事务的相关命令
EXEC、MULTI、WATCH 等等
redis集群
在说Redis集群前,先说下为什么要使用Redis集群,Redis单机版主要有以下几个缺点:
- 不能保证数据的可靠性,服务部署在一台服务器上,一旦服务器宕机服务就不可用。
- 性能瓶颈,内存容量有限,处理能力有限
Redis集群就是为了解决Redis单机版的一些问题,Redis集群主要有以下几种方案
- Redis 主从模式
- Redis 哨兵模式
- Redis 自研
- Redis Clustert
redis主从模式
Redis单机版通过RDB或AOF持久化机制将数据持久化到硬盘上,但数据都存储在一台服务器上,并且读写都在同一服务器(读写不分离),如果硬盘出现问题,则会导致数据不可用,为了避免这种问题,Redis提供了复制功能,在master数据库中的数据更新后,自动将更新的数据同步到slave数据库上,这就是主从模式的Redis集群。
主从模式解决了Redis单机版存在的问题,但其本身也不是完美的,主要优缺点如下:
优点:
- 高可靠性,在master数据库出现故障后,可以切换到slave数据库
- 读写分离,slave库可以扩展master库节点的读能力,有效应对大并发量的读操作
缺点:
- 不具备自动容错和恢复能力,主节点故障,从节点需要手动升为主节点,可用性较低
redis哨兵模式
为了解决主从模式的Redis集群不具备自动容错和恢复能力的问题,Redis从2.6版本开始提供哨兵模式
哨兵模式的核心还是主从复制,不过相比于主从模式,多了一个竞选机制(多了一个哨兵集群),从所有从节点中竞选出主节点。
哨兵模式相比于主从模式,主要多了一个哨兵集群,哨兵集群的主要作用如下:
- 监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,处理监控主服务器、从服务器外,哨兵之间也相互监控。
- 故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。
哨兵模式的优缺点:
优点:
- 哨兵模式是基于主从模式的,解决可主从模式中master故障不可以自动切换故障的问题。
缺点:
- 浪费资源,集群里所有节点保存的都是全量数据,数据量过大时,主从同步会严重影响性能
- Redis主机宕机后,投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。
- 只有一个master库执行写请求,写操作会单机性能瓶颈影响