Redis基础总结

Redis应用场景:缓存,快速读写,分布式锁等.

Redis优势:内存,约束少.

Redis核心问题:数据一致性,访问控制.

在Java中是Redis有两种方式,一种是使用Redis官方推荐的Jedis API,或者使用Spring的RedisTemplate.

使用连接池后,如果要使用同一个连接来操作需要使用SessionCallback接口.

Redis的六种数据类型

String字符串(KV结构)

List列表(支持两端操作的双端队列(物理结构:链表))

Set集合(无序,不重复)

Hash散列表(KV无序列表)

zset(有序)

HyperLogLog基数(只提供运算,不提供返回).

Redis的事务

一般而言,可以在multi命令之前使用watch命令监控某些键值对,然后使用multi命令开启事务,执行各类对数据结构进行操作的命令,这个时候这些命令就会进入队列.当Redis使用exec命令执行事务的时候,它首先回去比对被watch命令所监控的键值对,如果没有发生变化,那么它会执行事务队列中的命令,提交事务;如果发生变化,那么它不会执行任何事务中的命令,而去事务回滚.无论事务是否回滚,Redis都会去取消执行事务前的watch命令.

  • multi开启事务.
  • watch key1 [key2...]监听某些键,在事务执行前被修改,则会回滚.
  • unwatch key1 [key2...]取消监听某些键.
  • exec执行事务.
  • discard回滚事务.

Redis的操作具有原子性(单线程).

Redis事务的三个阶段:开启事务,命令进入队列,执行事务.

Redis监听某些键,决定是否回滚,采用乐观锁,且不存在ABA问题(版本号解决).使用multi命令后,使用get等方法的返回值一律为空,只有在执行exec后才会将所有命令的返回结果一起返回(List接收).

Redis事务遇到命令格式正确而数据类型不符合的情况下,除了本条命令外,其他命令都会被执行,不会被回滚.需要注意.

批量执行命令,可以使用Redis的流水线Pipeline功能.Redis的流水线是一种通信协议.需要注意返回的执行结果的大小,如果太大,可能导致内存不足,进而引发JVM溢出异常.可以考虑使用迭代的方式处理.

Redis发布订阅模式

SUBSCRIBE name.订阅一个渠道/频道.

publish name "hh" 向渠道发送消息.

Spring中如何使用:提供接受消息的类,它实现MessageListener接口,并重写onMessage方法.配置RedisMessageListenerContainer监听容器,用来监听消息.RedisTemplate的convertAndSend方法可以向渠道发送消息.

Redis的超时回收

如果key超时了,Redis不会立刻回收该key,而是标识哪些键值对超时了(因为如果太大,会导致长时间停顿).然后根据配置决定使用定时回收还是惰性回收.

定时回收就是在某个时间触发一段代码,回收超时的键值对.

惰性回收就是当一个超时的键,被再次用get命令访问是,将触发Redis将其从内存中清空.

Redis持久化

Redis备份的两种方式:RDB(数据快照,适合备份数据),AOF(追加文件,适合主从复制时同步写缓存中的数据).

save同步保存命令,执行时不允许客户端对Redis进行读写操作,存储格式为RDB.

bgsave是一个异步保存命令,用于把Redis数据保存到对应的数据文件中,它允许执行时,客户端同时读写Redis,存储格式为RDB.

Redis内存回收策略

Redis内存回收策略在Redis内存即将溢出时触发.

noeviction:不淘汰键值对,内存满时,申请内存的命令将会报错.
allkeys-lru:最近最少使用的键(包括没有设置超时时间的)会被淘汰.
volatile-lru:最近最少使用的键(设置了超时时间的)会被淘汰.
allkeys-random:随机淘汰键(包括没有设置超时时间的).
volatile-random:随机淘汰键(包括没有设置超时时间的)
volatile-ttl:优先淘汰剩余存活时间短的键(设置了超时时间的).

Redis4.0后新增两种:

volatile-lfu:优先淘汰最不常用的键(设置了超时时间的).

allkeys-lfu:优先淘汰最不常用的键(包括没有设置超时时间的).

Redis主从复制

主服务器负责写操作,从服务器负责读操作.主服务器执行写命令后,将写入数据的命令发送给从服务器,从服务器执行命令,使得竹筒数据同步.如果主服务器宕机,则进行主从切换,从从服务器中选举一台服务器当做主服务器,原先的主服务器恢复后变为从服务器.

如果出现多台同步,可能会出现频繁等待和频繁操作bgsave命令的情况,导致主机在较长时间里性能不佳,这时候可以考虑使用主从链进行同步.

哨兵模式

哨兵是一个独立的进程,它会发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例,当检测到master宕机,哨兵会发起故障切换操作,将slave切换成master,然后通过发布订阅模式通知其他从服务器修改配置,完成客观下线.还可以使用多个哨兵进行监控,防止哨兵挂掉,多哨兵情况下,单个哨兵检测到master宕机称为主观下线,当有一定数量的哨兵将master标为主观下线后,将由一个哨兵发起故障切换,完成客观下线.

Redis哨兵默认超时3分钟后才会进行投票切换主机.

Redis分片

Redis分片是实现水平扩容的一种方式,将数据拆分存放在不同的Redis实例上.采用一致性哈希算法,一致性哈希算法由客户端实现(Jedis的ShardedJedis).服务器端其实没有任何改变.

一致性哈希算法会对key和节点名同时哈希,然后进行映射匹配,节点减少时,不会产生由于重新匹配造成对所有数据重新哈希,一致性哈希算法只影响相邻节点的分配.为了避免一致性哈希算法对相邻节点分配造成压力,ShardedJedis会对每个节点根据名字虚拟化出160个虚拟节点进行散列,在节点增加或减少时,让key在节点之间的移动分配更加均匀,而不是只对相邻节点有影响.

Redis集群

Redis集群采用哈希槽来映射数据,对key进行散列(CRC16后%16384),将数据放入某一个槽中,每个节点负责一部分哈希槽,当节点增加或减少时,需要对哈希槽进行重新分配到节点中,槽中的数据也要进行迁移.集群要保证16384个哈希槽都能正常工作,所以将节点配置为主从结构,如果主节点失效,集群会根据选举算法选出一个从节点升级为主节点,整个集群继续对外提供服务,以实现自动故障转移.如果客户端操作的key没有分配在该客户端连接的节点上,服务器会返回转向指令,指向正确的节点.

Redis集群选举原理:每个节点都会保存集群中所有的主从状态信息,节点间通过互相的ping-pong判断对方的存活状态.如果有半数以上的节点去ping一个节点的时候没有成功,集群就认为这个节点宕机,然后去连接该节点的备用节点.

使用Spring缓存机制整合Redis

Spring提供了缓存管理器接口CacheManager来支持Redis.

spring-data-redis.jar提供的则是RedisCacheManager接口.

@EnableCaching

@Cacheable

@CachePut

@CacheEvict

要注意自调用失效的问题.和spring的事务管理一样,因为底层采用的是动态代理.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章