什么是Redis?
Redis是一个基于内存的高性能key-value数据库
Redis数据类型
- string:最基本的数据类型,二进制安全
- hash:String元素组成的字典,适合用于存储对象
- list:列表,按照String元素插入顺序排序
- set:无序集合,通过哈希表实现,不允许重复
- zset :有序集合
Redis为何这么快
- 完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
- 数据结构简单,对数据操作也简单
- 采用单线程,单线程也能处理高并发请求,想要多核也可启动多Redis实例
- 使用多路I/O复用模型,非阻塞IO
多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力。
在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,当前线程就从阻塞状态中被唤醒,然后去轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。
缓存中间件-Memcache和Redis的区别
Memcache:代码层次类似Hash
- 支持简单数据类型
- 不支持数据持久化存储
- 不支持主从(主从服务器复制)
- 不支持分片
Redis:
- 数据类型丰富(String、list、hash、set、zset)
- 支持数据磁盘持久化存储
- 支持主从
- 支持分片
从海量Key里查询出某一固定前缀的Key
-
方法一:
使用KEYS pattern命令:查找所有符合给定模式pattern的key
例如查找前缀为he的key:keys he*
特点:- KEYS指令一次性返回所有匹配的key,速度很慢
- 键的数量过大会使服务卡顿(影响线上项目运行速度)
-
方法二:
使用scan cursor [MATCH pattern] [COUNT count] 命令
例如查找前缀为he的key:scan 0 [MATCH he*] [COUNT 4]
表示的是返回前4个he*前缀的key
特点:- 基于游标的迭代器,以0作为游标起点
- 不保证每次执行都返回给定数量的元素,支持模糊查询
因此采用scan命令进行海量数据查询,查询快速,不会造成服务卡顿。
11.redis的并发竞争问题如何解决?
Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:
- 客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
- 服务器角度,利用setnx实现分布式锁。
注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题,如设置键值的操作和设置键过期时间要保证这两个操作原子的,不可分割。
如何通过Redis实现分布式锁
分布式锁需要解决的问题:
- 互斥性
- 安全性
- 死锁
- 容错
Redis数据持久化
-
RDB(快照)持久化:保存某个时间点的全量数据快照
- SAVE:阻塞Redis的服务器进程,直到RDB文件被创建完毕
- BGSAVE:Fork出一个子进程来创建RDB文件,不阻塞服务器进程
-
AOF(Append-Only-File)持久化:保存写状态
- 记录下所有变更数据库状态的指令
- 以append的形式追加保存到AOF文件中(增量)
-
RDB和AOF的优缺点
- RDB优点:全量数据快照,文件小,恢复快。
- RDB缺点:无法保存最近一次快照之后的数据
- AOF优点:可读性高,适合保存增量数据,数据不易丢失
- AOF缺点:文件体积大,恢复时间长
-
RDB-AOF混合持久化方式:
- BGSAVE做镜像全量持久化,再使用AOF重放快照之后的操作指令来做增量持久化。
Redis数据的恢复
在RDB和AOF文件共存情况下的恢复流程:
- 先查看AOF文件是否存在,如果存在就加载AOF文件进行恢复
- 如果AOF文件不存在,则查看RDB文件是否存在,存在则加载RDB文件进行回复