精灵商场项目(八)--Redis分片-哨兵-主从

本文详细介绍了Redis的分片机制,包括搭建步骤和Spring整合,并探讨了Hash一致性算法,强调了数据均衡性、单调性和分散性。此外,讨论了Redis的RDB和AOF持久化方式,以及内存策略。还深入讲解了Redis的哨兵机制,用于实现高可用性,包括哨兵的选举原理和配置方法。最后,提到了在实际应用中遇到的高可用问题及其解决方案。
摘要由CSDN通过智能技术生成

本篇主要是讲解原理

Redis官方网站

命令

文档

一、Redis 分片机制

1.1 原理说明

需求分析 : 单台redis节点,保存的数据是有限的.如果一味的增大单个节点的内存空间,不能从根本上解决内存不足的问题.如何实现有效的内存扩容呢?

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

1.2 redis分片搭建步骤(了解)

1.2.1 创建目录

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

1.2.2 复制配置文件

将redis.conf文件复制3份到shards中

cp redis.conf shards/redis-6379.conf

cp redis.conf shards/redis-6380.conf

cp redis.conf shards/redis-6381.conf

1.2.3 修改端口号

将port修改为对应的端口地址

vim redis-6379.conf

vim redis-6380.conf

vim redis-6381.conf

1.2.4 启动3台redis

1.启动3台redis:

redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf

2.查看rides服务,检查是否正常启动

ps -ef |grep redis

1.2.5 分片入门案例

测试redis分片

public class TestShards {
	@Test
	public void test01() {
		String host = "192.168.56.129";
		List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
		shards.add(new JedisShardInfo(host, 6379));
		shards.add(new JedisShardInfo(host, 6380));
		shards.add(new JedisShardInfo(host, 6381));
		ShardedJedis jedis = new ShardedJedis(shards);
		jedis.set("1111", "学习redis分片机制");
		System.out.println(jedis.get("1111"));
	}
}

1.3 Spring整合redis分片

1.3.1 编辑pro配置文件

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

1.3.2 编辑配置类

实现spring容器管理redis配置类

@Configuration //标识配置类
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
	@Value("${redis.nodes}")
	private String nodes;
    
	/**
	 * redis分片
	 */
	@Bean
	@Scope("prototype")
	public ShardedJedis shardedJedis() {
		List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
		String[] redisNodes = nodes.split(",");
		for (String redisNode : redisNodes) {
			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);
	}
}

1.3.3 编辑切面类信息

@Autowired
private shardedJedis jedis;


二、Hash一致性规则

2.1 Hash一致性算法介绍

  1. 确定节点node的位置
  2. 对key进行hash运算.获取唯一的位置
  3. 之后顺时针找到最近的节点
  4. 之后链接节点进行set/get操作

在这里插入图片描述

2.2 均衡性

说明 : 为了解决数据分配不均,采用虚拟节点的方式实现数据的均衡(均衡性算法)
问题说明 : 如果没有虚拟节点平衡数据,则会造成数据负载不均

2.3 单调性

说明 : 当节点新增时,数据可以实现自动的迁移
重点 : 一旦节点宕机,则内存缺失,整个分片不能正常使用
原则 : 如果节点新增,则尽可能保证原有的数据不发生变化

2.4 分散性

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

2.5 负载

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

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

2.6 总结

1、搭建缓存集群缓解服务器的访问压力
2、通过hash算法将数据合理的分配到每一台缓存服务器中。
3、出现增减缓存服务器是hash算法存在问题
4、引入一致性哈希算法解决这个问题-增减服务器时有一小部分数据受到影响
5、通过虚拟节点方式解决哈希偏斜问题


三、Redis持久化方式

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

3.1 RDB模式

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

特点:

  1. RDB模式定期实现数据的持久化 (可能会丢失数据)
    . RDB模式记录的是内存数据的快照.持久化文件较小
    . RDB模式在进行持久化操作时是阻塞的.(数据安全性考虑)
    . 一般使用持久化的策略RDB的效率是最高的.建议使用

可以通过客户端执行save指令,实现内存数据的持久化操作
bgsave表示后台运行,异步操作.
save表示现在立即执行.表示同步操作.会造成线程阻塞

RDB的持久化策略:

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

修改持久化文件名称的配置 : redis.conf
在这里插入图片描述

3.3 AOF模式

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

特点:

  1. AOF模式默认是关闭的.
    . AOF模式持久化时记录用户的操作过程,之后追加到持久化文件中
    . AOF模式可以实现实时备份.保证数据安全
    . AOF模式效率低于RDB模式
    . AOF持久化文件需要定期维护
    . AOF模式是异步的不会陷入阻塞

开启AOF模式 : 修改配置文件 : redis.conf
在这里插入图片描述

AOF模式持久化策略:

appendfsync always 用户做一次操作,持久化一次
appendfsync everysec 每秒持久化一次
appendfsync no 由操作系统决定何时持久化. 一般不用


四、关于Redis内存策略

4.1 说明

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

4.2 LRU算法

LRU(Least Recently Used) ,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。

4.3 LFU算法

LFU(least frequently used),即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。

4.4 内存优化算法

内存优化策略说明
volatile-lru设定超时时间的数据采用LRU算法进行删除
allkeys-lru所有数据采用LRU算法进行删除
volatile-lfu设定超时时间的数据,采用LFU算法
allkeys-lfu所有数据采用LFU算法
volatile-random设定超时时间的随机算法
allkeys-random所有数据的随机算法
volatile-ttl设定超时时间的数据按照可存活时间排序删除
noeviction 默认设定如果内存满了不会删除数据,而是报错返回,有使用这自行决定

4.5 修改内存策略

修改redis.conf文件 : maxmemory-policy

在这里插入图片描述

五、Redis 哨兵机制(了解)

5.1 业务需求

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

5.2 Redis 主从复制

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

  2. 将redis配置文件复制好之后,将redis服务启动

  3. 检查节点状态 info replication

  4. 主从配置 : 让6370当主机,6380当从机 : SLAVEOF 192.168.56.129:6379

    (一旦实现主从结构之后,从机将不能set操作)

  5. 主从结构测试 : 检查是否可以通信info replication ; 检查主从结构是否正常: 向redis主机中set数据,之后检查从机中是否实现数据同步

5.3 Redis哨兵实现

5.3.1 哨兵原理说明

实现步骤:

  1. 哨兵启动时首先监控主机的状态,并且记录主机的全部信息(包括从机的host:port)
    . 当主机发生宕机现象时.首先会根据PING-PONG心跳检测机制,查看主机的状态,如果连续3次主机无法响应,则断定主机宕机
    . 由哨兵利用自己的推选的算法.选举出新的主机.并且将其他的节点改为当前主机的从机.

5.3.2 编辑哨兵配制文件

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

  2. 关闭哨兵保护模式 : 配置文件中找到 pritected-mode改为 no

  3. 开启后台启动 : 配置文件中找到 daemonize改为 yes

  4. 修改哨兵监控信息 :
    在这里插入图片描述
    mymaster:变量名称 ;标识主机信息

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

  5. 修改宕机的超时时间
    在这里插入图片描述

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

5.3.3 关于redis高可用问题

  1. 前提:必须配置主从结构
  2. 如果出现了哨兵不能正确选举.则需要重新配置主从
  3. 解决方案:编辑redis.conf的配置文件,之后删除最后一行信息.删除之后重新挂载.

5.4 Spring整合Redis哨兵

5.4.1 入门案例

端口说明:
默认端口: 6379
通信端口:16379 PING-PONG
哨兵端口:26379

public class TestSentinel {
	/**
	 * 程序链接哨兵入门案例
	 * masterName:mymaster
	 * sentinels: 哨兵的Set集合信息.
	 */
	@Test
	public void test01() {
		Set<String> sentinels = new HashSet<>();
		sentinels.add("192.168.56.129:26379");
		JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
		Jedis jedis = pool.getResource();
		jedis.set("1907", "redis哨兵测试成功!!!!");
		System.out.println(jedis.get("1907"));	
	}
}

5.4.2 编辑pro文件

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

5.4.2 编辑配置类

实现spring容器管理redis配置类

@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的方法自动的注入参数对象
 	@Bean 
 	@Scope("prototype")
	public Jedis jedis(JedisSentinelPool pool) {
		return pool.getResource();
	}
}


随手笔记

1.关于redis高可用问题

  1. 前提:必须配置主从结构.
  2. 如果出现了哨兵不能正确选举.则需要重新配置主从
  3. 解决方案 : 编辑redis.conf的配置文件,之后删除最后一行信息.删除之后重新挂载
    在这里插入图片描述

2.关于RDB和AOF的说明

1.是否允许数据丢失 ? RDB(yes) ; AOF(no)
2.是否允许2种模式同时存在?
允许,一般在主从结构中使用.主节点选用dB模式,从节点选用AOF模式.如果出现特殊现象,则可直接拷贝AOF文件/RDB文件实现数据恢复
3.效率问题RDB高于AOF
4.RDB做内存数据的快照,AOF记录用户的操作过程.
5.RDB同步操作AOF模式异步操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值