前言
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
import com.jt.anno.CacheFind;
import com.jt.util.ObjectMapperUtil;
import org.apache.catalina.Cluster;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.ShardedJedis;
import java.util.Arrays;
代码如下(示例):
@Component//我是一个javabean
@Aspect//我是一个切面
public class CacheAOP {
@Autowired
//private Jedis jedis;
//private ShardedJedis jedis;
private JedisCluster jedis;
@Around("@annotation(cacheFind)")//pointCut()
public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
try {
Object result = null;
//1.如何动态获取注解中的数据
String prekey = cacheFind.key();
System.out.println(prekey);
//动态获取方法中的参数。将数组转华为字符串。
String args = Arrays.toString(joinPoint.getArgs());
String key = prekey + "::" + args;
if (jedis.exists(key)) {
String json=jedis.get(key);
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
result=ObjectMapperUtil.toObject(json,methodSignature.getReturnType());
System.out.println("aop查询redis缓存");
} else {
System.out.println("环绕通知开始");
result = joinPoint.proceed();//执行目标方法
System.out.println("aop执行数据库操作");
System.out.println("环绕通知结束");
String json = ObjectMapperUtil.toJSON(result);
if (cacheFind.seconds() > 0) {
jedis.setex(key, cacheFind.seconds(), json);
} else {
jedis.set(key, json);
}
}
return result;
}catch (Throwable e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
redis中如何选择持久化方式
如果redis允许数据少量的丢失,则首选RDB(快)如果不允许丢失数据,则使用AOF模式/
redis运行的空间是内存,内存的资源比较紧缺。所以应该维护redis内存数据,让redis保留热点数据。
LRU算法
LRU是最近最少使用的意思。根据此算法淘汰最近最少使用的页面。
LFU算法
LFU是最不经常使用页置换算法,根据页面平均使用次数,将使用次数最少的页面删除掉。
Redis高可用機制的實現
redis分片并没有实现高可用机制,
redis主从的搭建,实现高可用。
前提条件:如果要实现redis高可用机制,则必须首先实现主从搭建。
主从关系设定:6379主机,6380,6381从机
配置redis
实现主从的配置
slaveof 主机ip 主机端口(2主机,1从机)
主从配置问题说明
当redis服务器已经配置了主从结构之后。如果将服务器宕机,之后在重启,则发現从服务器又会变为主机。
执行了主从挂载的命令,该命令一直保存在内存中,当redis服务器重启之后,该命令失效,故此想要一直保持主从的关系,则必须将主从关系结构写入redis.conf的配置文件中。
哨兵机制的原理说明。
1.首先启动redis哨兵,由哨兵监控整个redis主从状态,主要监控主机,同时获取其从机的信息。
2.哨兵利用心跳检测机制(ping-pong)的方式监控主机是否宕机,如果连续3次
主机没有响应,则哨兵判断主机宕机,之后开始进行选举。
选举机制
3.根据从主机中 获取的从机信息。之后利用选举机制算法,挑选新的主机。
之后将剩余的redis修改为当前主机的从,并修改配置文件信息。
redis分片/redis哨兵总结
分片可以实现redis内存数据的扩容,可以存储海量的内存数据,redis分片機制没有实现高可用。如果分片中一个节点宕机,则直接影响整个服务的运行。
哨兵可以实现redis节点的高可用,但是redis中 的数据不能实现内存的扩容。哨兵服务本身没有实现高可用,如果哨兵发生了异常则直接影响用户的使用。
如果想让集群尽可能不宕机,则适当增加从节点的数量,2-3个即可。