- Redis能够存储的数据有字符串和序列化后的数据,一个java对象想存储到redis,需要转成Json字符串或序列化才行
- Redis是NOsql,通过key-value的形式进行数据存储,结构松散,不支持聚合计算
- Redis数据主要存放到内存中,又是key-value的形式,所以查询速度快
- Redis由于数据存放到内存中,如果服务器宕机,存在丢失数据的风险
- Redis的事务能力、安全性、聚合计算性、可扩展性远不及数据库
Redis相关JAVA API的jar包
Redis.clients,没有提供将java对象转换为字符串
Spring-data-redis:提供了序列化器,redisTemplate
Redis数据结构
Redis数据结构类型有很多种,常用的有5种。
字符串(String)
数据结构:Key-value,key、value都是字符串,且value可以是数字。当value数字(整数或浮点数)时,可以进行一些简单的加减运算。
哈希(Hash)
数据结构:key-(field,value),key、field都是字符串,value可以是字符串也可以是java对象。
链表(List)
左右节点
集合(Set)
Redis的集合不是一个线性结构,是一个哈希表结构,内部是根据哈希因子存储和查找数据。所以对于redis集合的插入、删除和查找复杂度都是O(1)
- 集合成员都是String类型
- 集合是无序的
- 集合每个成员都是不能重复的
有序集合(Zset)
数据结构:key->(score,value)。有序集合与集合类似,只不过它是有序的,还多了一个score分数字段,score字段是浮点数,value也是String类型,也是基于hash的存储结构,插入、删除和查找复杂度也都是O(1)
Redis事务
- 使用multi-exec进行事务管理。Multi是开启事务,exec是事务执行。
- 在multi和exec中间要执行的redis指令,会先被存储到队列缓存里,当做exec执行时,队列里的指令才会逐个被执行。
- Discard是回滚事务,原理就是清空队列里的所有redis指令
- Redis事务一般结合watch、unwatch使用。Watch使用的是乐观锁(CAS,不存在ABA的问题),注意在finnally释放锁unwatch key
- Redis事务是先把执行的命令缓存起来,然后再去执行。当执行到watch指令时,发现监控的key的值被修改了,这个时候会回滚事务,清空指令队列
- Redis事务要放到sessioncallback处理,保证多条指令在同一条redis连接里完成
- Redis事务是弱事务,就是假如指令队列里有5条指令,前面2条指令都执行通过了,第三条执行失败了,第4、5条指令也会继续执行,而且执行后的结果还会存在,不会被回滚,根据数据库事务不一样。
Redis流水线
将多条指令放到队列里,批量提交给服务端执行
发布订阅模式
Subcribe chat 订阅主题
Publish chat “hello world” 发布信息
订阅chat主题的客户端就能收到发布的信息
超时命令
Expire 超时命令
当key超时后,不会立即被回收,会先进行标记哪些Key是超时的。
Redis提供了8种回收策略。当回收的数据量很大时,在回收的过程中redis服务可能产生停顿。如果不回收,会浪费比较多的空间
Lua语言
在redis中,执行lua语言是原子性的。可以编写lua脚本,然后去调用。Redis会将Lua脚本缓存起来,然后返回SHA1-1签名,然后通过SHA1-1签名去调用lua脚本,这样可以避免lua脚本传输占用带宽的问题。
Redis配置
Redis数据备份(持久化)
- 快照备份:备份redis内存数据
- AOF备份:记录执行过得写命令,进行数据恢复的时候可以根据这些写命令进行恢复
内存回收策略
- 快照备份:备份redis内存数据
- AOF备份:记录执行过得写命令,进行数据恢复的时候可以根据这些写命令进行恢复
内存回收策略
8种回收策略
Redis主从数据同步
- 主服务器只有一台,多服务器可以有多台。
- 主服务器负责写入数据,从服务器负责读取数据
- 主服务器在写入数据后,即刻会将执行的命令发送给从服务器执行
- 当主服务器宕机后,可以从从服务器选取一台来当主服务器
哨兵模式
哨兵作用:
- 通过Ping命令,监控主从服务器运行状态
- 如果主服务器宕机,多个哨兵会在他们中间通过投票选出一个leader,然后由这个leader将一台从服务器切换为主服务器,并通过发布订阅模式(广播),通知哨兵、从服务器进行新的主服务器切换
哨兵客户端连接:
Redis客户端连接是对着哨兵连接的,当redis客户端发出指令时,会从哨兵连接池随机挑选一台可用的哨兵进行处理连接请求。如果redis客户端是对着主服务器连接的,加重了主服务器任务,另外主服务器在运行期间可能宕机,切换为其他新的服务器上,redis客户端没法识别是哪台。
故障切换-failover过程:
- 主观下线:当一台哨兵检测到主服务器不可用时,会认为主服务器下线了,但这个时候不会进行故障切换,因为这个时候只有这台哨兵任务主服务器下线了。这台哨兵会通知其他哨兵它发现的情况
- 客观下线:当多台哨兵检测到主服务器不可用时,并且检测到主服务器不可用的哨兵数量大于等于配置的数量,这个时候所有哨兵都会认为主服务器不可用了,这个时候开始进行故障切换
- 故障切换:从哨兵里面投票选出一个leader,这个leader再从从服务器里面选出一台主服务器,然后通过发布订阅模式(广播),通知哨兵、从服务器进行新的主服务器切换。
Redis相关问题
执行多条指令,怎么保证在同一个redis连接里执行
当执行多条指令时,如果每条执行都在不同的redis连接里执行,redis连接需要维护,消耗资源,会降低性能效率,期望多条指令在同一个redis连接里执行。使用redisTemplate提供的sessionCallBack
在redis连接逐个发送指令和批量发送指令性能对比
批量发送指令性能会高些。Redis逐个发送指令,可能会存在网络延迟,前面的指令执行成功了,后面的指令才能接着执行。批量发送指令是将指令先存放到缓存队列中,最后一起发送到服务端,这样就省略了多次网络传输的过程。
从redis读取数据注意内存溢出
从redis读取数据时,如果返回的数据量很大,可能会造成JVM内存溢出。像读取哈希、集合里面的数据。当返回的数据量很大时,也会占用大量的带宽,注意网络传输。
Redis事务与数据库事务的区别
Redis事务是弱事务,数据库事务是强事务。
Redis事务出现错误时,前后指令执行的结果还会存在,不会全部回滚
数据库是全部回滚
Redis回收超时数据会产生什么影响
当回收的数据量很大时,可能会造成redis服务端产生停顿。如果不回收,又浪费很多的空间。Redis提供了8种回收策略
在哨兵模式下,redis客户端连接是对着主服务器还是对着哨兵连接的
对着哨兵连接的,当redis客户端发出指令时,会从哨兵连接池随机挑选一台可用的哨兵进行处理连接请求。如果redis客户端是对着主服务器连接的,加重了主服务器任务,另外主服务器在运行期间可能宕机,切换为其他新的服务器上,redis客户端没法识别是哪台



