第三阶段 Day14 Redis分片机制 Redis哨兵机制

半颠 2020-11-09 12:09:59
第三 阶段 第三阶段 三阶 day14


  1. Redis分片机制

=============

1.1 为什么需要分片机制

如果需要存储海量的内存数据,如果只使用一台redis,无法保证redis工作的效率. 大量的时间都浪费到了寻址当中.所以需要一种机制能够满足该要求.
采用分片机制实现:
在这里插入图片描述

1.2 Redis分片搭建

1.2.1 搭建注意事项

Redis服务的启动需要依赖于redis.conf的配置文件. 如果需要准备3台redis.则需要准备3个redis.conf的配置.

准备端口号:
1.6379
2.6380
3.6381

1.2.2 分片实现

在这里插入图片描述
修改端口号: 将各自的端口号进行修改.
在这里插入图片描述

启动3台redis服务器
在这里插入图片描述
校验服务器是否正常运行
在这里插入图片描述

1.2.3 关于分片的注意事项

1.问题描述:
当启动多台redis服务器之后,多台redis暂时没有必然的联系,各自都是独立的实体.可以数据数据的存储.如图所示.
2.如果将分片通过程序的方式进行操作,要把3台redis当做一个整体,所以与上述的操作完全不同.不会出现一个key同时保存到多个redis的现象.
在这里插入图片描述

1.3 分片入门案例

 `/**
* 测试Redis分片机制
* 思考: shards 如何确定应该存储到哪台redis中呢???
*/
@Test
public void testShards(){
List<JedisShardInfo> shards = new ArrayList<>();
shards.add(new JedisShardInfo("192.168.126.129",6379));
shards.add(new JedisShardInfo("192.168.126.129",6380));
shards.add(new JedisShardInfo("192.168.126.129",6381));
//准备分片对象
ShardedJedis shardedJedis = new ShardedJedis(shards);
shardedJedis.set("shards","redis分片测试");
System.out.println(shardedJedis.get("shards"));
}`

1.4 一致性hash算法

1.4.0 常识说明

常识1: 一般的hash是8位16进制数. 0-9 A-F (24)8 = 2^32
常识2: 如果对相同的数据进行hash运算 结果必然相同的.
常识3: 一个数据1M 与数据1G的hash运算的速度一致.

1.4.1 一致性hash算法介绍

一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。
在这里插入图片描述

1.4.2 特性1-平衡性

概念:平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题 [4] 。(大致平均)
问题描述: 由于节点都是通过hash方式进行算计.所以可能出现如图中的现象.,导致负载严重不平衡
在这里插入图片描述
解决方法: 引入虚拟节点
在这里插入图片描述

1.4.3 特性2-单调性

特点: 单调性是指在新增或者删减节点时,不影响系统正常运行 [4] 。
在这里插入图片描述

1.4.4 特性3-分散性

谚语: 鸡蛋不要放到一个篮子里.
③分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 [4]

1.5 SpringBoot整合Redis分片

1.5.1 编辑配置文件

`# 配置redis单台服务器
redis.host=192.168.126.129
redis.port=6379
# 配置redis分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381`

1.5.2 编辑配置类

`@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {
@Value("${redis.nodes}")
private String nodes; //node,node,node.....
//配置redis分片机制
@Bean
public ShardedJedis shardedJedis(){
nodes = nodes.trim(); //去除两边多余的空格
List<JedisShardInfo> shards = new ArrayList<>();
String[] nodeArray = nodes.split(",");
for (String strNode : nodeArray){ //strNode = host:port
String host = strNode.split(":")[0];
int port = Integer.parseInt(strNode.split(":")[1]);
JedisShardInfo info = new JedisShardInfo(host, port);
shards.add(info);
}
return new ShardedJedis(shards);
}
}`

1.5.3 修改AOP注入项

在这里插入图片描述

2 Redis哨兵机制

2.1 关于Redis分片说明

优点: 实现内存数据的扩容.
缺点: 如果redis分片中有一个节点出现了问题.,则整个redis分片机制用户访问必然有问题 直接影响用户的使用.
解决方案: 实现redis高可用.

2.2 配置redis主从的结构

策略划分: 1主2从 6379主 6380/6381从

1.将分片的目录复制 改名位sentinel
在这里插入图片描述

  1. 重启三台redis服务器
    在这里插入图片描述
    3.检查redis节点的主从的状态
    在这里插入图片描述
    4.实现主从挂载
    在这里插入图片描述
    5.检查主机的状态
    在这里插入图片描述

2.3 哨兵的工作原理

在这里插入图片描述
原理说明:
1.配置redis主从的结构.
2.哨兵服务启动时,会监控当前的主机. 同时获取主机的详情信息(主从的结构)
3.当哨兵利用心跳检测机制(PING-PONG) 连续3次都没有收到主机的反馈信息则断定主机宕机.
4.当哨兵发现主机宕机之后,则开启选举机制,在当前的从机中挑选一台Redis当做主机.
5.将其他的redis节点设置为新主机的从.

2.4 编辑哨兵配置文件

1).复制配置文件
cp sentinel.conf sentinel/

2).修改保护模式
在这里插入图片描述
3).开启后台运行
在这里插入图片描述
4).设定哨兵的监控
其中的1 表示投票生效的票数 当前只有一个哨兵所以写1
在这里插入图片描述
5).修改宕机的时间
在这里插入图片描述
6).选举失败的时间
说明:如果选举超过指定的时间没有结束,则重新选举.
在这里插入图片描述
7).启动哨兵服务
在这里插入图片描述

2.5 Redis哨兵高可用实现

测试步骤:
1.检查主机的状态
2.将redis主服务器宕机 等待10秒 之后检查从机是否当选新的主机
在这里插入图片描述
3.重启6379服务器., 检查是否成为了新主机的从.
在这里插入图片描述

2.6 哨兵入门案例

`/**
* 测试Redis哨兵
*/
@Test
public void testSentinel(){
Set<String> set = new HashSet<>();
//1.传递哨兵的配置信息
set.add("192.168.126.129:26379");
JedisSentinelPool sentinelPool =
new JedisSentinelPool("mymaster",set);
Jedis jedis = sentinelPool.getResource();
jedis.set("aa","哨兵测试");
System.out.println(jedis.get("aa"));
}`

2.7 SpringBoot整合Redis哨兵 (10分钟)

2.7.1 编辑pro配置文件

`# 配置redis单台服务器
redis.host=192.168.126.129
redis.port=6379
# 配置redis分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381
# 配置哨兵节点
redis.sentinel=192.168.126.129:26379`

2.7.2 编辑redis配置类

`@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {
@Value("${redis.sentinel}")
private String sentinel; //暂时只有单台
@Bean
public JedisSentinelPool jedisSentinelPool(){
Set<String> sentinels = new HashSet<>();
sentinels.add(sentinel);
return new JedisSentinelPool("mymaster",sentinels);
}
}`

2.7.3 修改CacheAOP中的注入项

`package com.jt.aop;
import com.jt.anno.CacheFind;
import com.jt.config.JedisConfig;
import com.jt.util.ObjectMapperUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.ShardedJedis;
import java.lang.reflect.Method;
import java.util.Arrays;
@Aspect //我是一个AOP切面类
@Component //将类交给spring容器管理
public class CacheAOP {
@Autowired
//private Jedis jedis; //单台redis
//private ShardedJedis jedis; //分片机制
private JedisSentinelPool jedisSentinelPool;
/**
* 切面 = 切入点 + 通知方法
* 注解相关 + 环绕通知 控制目标方法是否执行
*
* 难点:
* 1.如何获取注解对象
* 2.动态生成key prekey + 用户参数数组
* 3.如何获取方法的返回值类型
*/
@Around("@annotation(cacheFind)") //参数传递变量的传递
//@Around("@annotation(com.jt.anno.CacheFind)")
public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind){
//从池中获取jedis对象
Jedis jedis = jedisSentinelPool.getResource();
Object result = null;
try {
//1.拼接redis存储数据的key
Object[] args = joinPoint.getArgs();
String key = cacheFind.preKey() +"::" + Arrays.toString(args);
//2. 查询redis 之后判断是否有数据
if(jedis.exists(key)){
//redis中有记录,无需执行目标方法
String json = jedis.get(key);
//动态获取方法的返回值类型 向上造型 向下造型
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Class returnType = methodSignature.getReturnType();
result = ObjectMapperUtil.toObj(json,returnType);
System.out.println("AOP查询redis缓存");
}else{
//表示数据不存在,需要查询数据库
result = joinPoint.proceed(); //执行目标方法及通知
//将查询的结果保存到redis中去
String json = ObjectMapperUtil.toJSON(result);
//判断数据是否需要超时时间
if(cacheFind.seconds()>0){
jedis.setex(key,cacheFind.seconds(),json);
}else {
jedis.set(key, json);
}
System.out.println("aop执行目标方法查询数据库");
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
jedis.close(); //将使用完成的链接记得关闭.
return result;
}
}`

作业

1.预习 Redis集群搭建步骤
2.了解redis集群工作原理

版权声明
本文为[半颠]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000037770231

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云