redis(2)

redis分片

采用多台redis服务器,共同维护一整块内存空间大小,最终实现了内存数据的扩容.

1.在redis的根目录中创建shards文件夹    mkdir shards

2.将redis.conf文件复制3分到shards中    cp redis.conf shards

3.修改端口号   vim redis.conf

4.启动3台redis  

Hash一致性规则

1.Hash一致算法介绍

1)确定节点node的位置.

2)对key进行hash运算.获取唯一的位置

3)之后顺时针找到最近的节点.

4)之后链接节点进行set/get操作.

 2.均衡性

为了解决数据分配不均,采用虚拟节点的方式实现数据的均衡(均衡性算法)

 3.单调性

当节点新增时,数据可以实现自动的迁移.

重点:一旦节点宕机,则内存缺失.整个分片不能正常使用.

原则:如果节点新增,则尽可能保证原有的数据不发生变化.

 4.分散性

由于分布式的部署导致某些服务器不能使用全部的内存空间,同一个key有多个位置

5.负载

由于分布式的部署导致某些服务器不能使用全部的内存空间.同一个位置可能会有多个key

 防止:尽可能使用全部的内存空间.能够有效的降低分散性和负载.

Spring管理Redis分片

1.编辑properties配置文件

#redis分片写法
redis.nodes=192.168.175.129:6379,192.168.175.129:6380,192.168.175.129:6381

2.编辑配置类

/**
 * 实现spring容器管理redis配置类
 * @author Administrator
 *
 */
@Configuration //标识配置类
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
    @Value("${redis.nodes}")
    private String nodes;   //node,node,node
/**
* redis分片
*/ @Bean @Scope("prototype") public ShardedJedis shardedJedis() { List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); String[] redisNodes = nodes.split(","); for (String redisNode : redisNodes) { //redisNode=IP:PORT String[] hostAndPort = redisNode.split(":"); String host = hostAndPort[0]; int port = Integer.parseInt(hostAndPort[1]); JedisShardInfo info = new JedisShardInfo(host, port); shards.add(info); } return new ShardedJedis(shards); } }

3.编辑切面信息

@Component    //将类交给容器管理
@Aspect        //标识切面
public class CacheAspect {
    
    @Autowired
    //private Jedis jedis;
      private SharedJedis jedis;

    //如果是环绕通知,则参数必须写ProceedingJoinPoint,必须位于第一位
    @Around("@annotation(cacheFind)")
............

redis持久化方式

Redis会根据配置文件的规则,定期将内存中的数据持久化到磁盘中.当redis重新启动时,会根据配置文件.实现内存数据的恢复

一、RDB模式

RDB模式是redis默认的持久化策略.

1.特点:

1).RDB模式定期实现数据的持久化 (可能会丢失数据)

2).RDB模式记录的是内存数据的快照.持久化文件较小.

3).RDB模式在进行持久化操作时是阻塞的.(数据安全性考虑)

4).一般使用持久化的策略RDB的效率是最高的.建议使用.

2.save指令(save、bgsave)

可以通过客户端执行save指令.实现内存数据的持久化操作

bgsave表示后台运行,异步操作.

save表示现在立即执行.表示同步操作.会造成线程阻塞.

3.持久化配置名称

4.RBD持久化策略

save 900 1   如果用户在900秒内,执行1次更新操作时,则持久化一次

save 300 10   在300秒内,执行10次更新操作时,则持久化

save 60 10000在60秒内,执行10000次更新操作时,则持久化

save 1 1     效率极低.

 二、  AOF模式

AOF模式默认是关闭的.如果使用需要开启.AOF模式最的是数据的追加.所以持久化文件较大.

1.特点:

1).AOF模式默认是关闭的.

2).AOF模式持久化时记录用户的操作过程,之后追加到持久化文件中.

3).AOF模式可以实现实时备份.保证数据安全.

4).AOF模式效率低于RDB模式

5).AOF持久化文件需要定期维护.

6).AOF模式是异步的不会陷入阻塞

2.AOF持久化策略

appendfsync always      用户做一次操作,持久化一次

appendfsync everysec   每秒持久化一次(默认)

appendfsync no         由操作系统决定何时持久化. 一般不用

Redis内存策略

Redis中自己有内存优化策略.能够保证在内存数据即将达到上限时,能够实现自动的优化. 但是该策略默认是关闭的.

1.LRU算法

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面内置算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面

自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。

2.LFU算法

LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用

次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。

3.内存优化算法

1).volatile-lru    设定超时时间的数据采用lru算法进行删除

2).allkeys-lru     所有数据采用LRU算法进行删除.

LFU                redis5.0版本以后的算法.

3).volatile-lfu    设定超时时间的数据,采用lfu算法 

4).allkeys-lfu     所有数据采用lfu算法.

5).volatile-random 设定超时时间的随机算法

6).allkeys-random  所有数据的随机算法

7).volatile-ttl    设定超时时间的数据按照可存活时间排序删除

8).noeviction 默认设定    如果内存满了不会删除数据,而是报错返回,有使用这自行决定.

4.修改内存

Redis哨兵机制

 redis分片实现了内存数据的扩容.但是redis分片没有实现高可用的效果.当redis分片的节点node如果宕机.导致整个分片不能正常执行.能否实现redis节点的高可用.

1.redis主从复制

1.1复制目录

将redis根目录中的shards目录复制为sentinel      cp -r shards sentinel

1.2检查节点状态

默认状态下,redis节点都是主机

 1.3主从配置

 注意:一旦实现主从结构之后,从机将不能set操作

1.4主从结构测试

1)在主机客户端使用     info replication 命令

2)向redis主机中set数据,之后检查从机中是否实现数据同步

1.5.redis哨兵实现

 

实现步骤:

1)哨兵启动时首先监控主机的状态,并且记录主机的全部信息(包括从机的host:port);

2)当主机发生宕机现象时.首先会根据PING-PONG心跳检测机制,查看主机的状态,如果连续3次主机无法响应,则断定主机宕机.

3)由哨兵利用自己的推选的算法.选举出新的主机.并且将其他的节点改为当前主机的从机.

 1.6 编辑哨兵配制文件

1)将哨兵的配置文件复制到sentinel目录中.

2)关闭哨兵保护模式

 3)开启后台启动

 4)修改哨兵监控信息

mymaster:变量名称  标识主机信息

1:   哨兵选举的票数.  一般数量> 哨兵 1/2

 5)修改宕机的超时时间

 6)启动哨兵    redis-sentinel sentinel.conf

 注意:配置哨兵前必须配置主从结构

Spring整合哨兵

1.编辑properties文件

#redis哨兵配置
redis.sentinels=192.168.175.129:26379

2.编辑配置类

@Configuration //标识配置类
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
    
    @Value("${redis.sentinels}")
    private String sentinels;
    
    /*实现哨兵的配置*/
    
    @Bean    //定义哨兵池对象
    public JedisSentinelPool pool() {
        Set<String> set = new HashSet<>();
        set.add(sentinels);
        return new JedisSentinelPool("mymaster",set);
    }
    
    
    //规则:可以为bean的方法自动的注入参数对象
    //方法2:指定ID进行注入
    //@Qualifier("jedisSentinelPool")JedisSentinelPool pool
     @Bean 
     @Scope("prototype")
    public Jedis jedis(JedisSentinelPool pool) {
         
        return pool.getResource();
    }
}

3.编辑切面

@Component    //将类交给容器管理
@Aspect        //标识切面
public class CacheAspect {
    
    @Autowired
    private Jedis jedis;
    //private SharedJedis jedis;

    //如果是环绕通知,则参数必须写ProceedingJoinPoint,必须位于第一位
    @Around("@annotation(cacheFind)")
............
原文地址:https://www.cnblogs.com/ming-long/p/11837845.html