分布式集群架构场景化解决方案

在这里插入图片描述

一、分布式和集群分布式的每一个节点都可以做集群,而集群并不一定就是分布式的。(个人觉得这个表述有点问题,需要一点理解的技巧,不可以钻牛角尖)分布式:把一个系统拆分为多个子系统,集群:多个实例共同工作。二、一致性Hash算法2.1 Hash算法问题:提供⼀组数据 1,5,7,6,3,4,8,对这组数据进⾏存储,然后随便给定⼀个数n,请你判断n是否存在于刚才的数据集中?解题思路:顺序查找法 --> 二分查找 --> 直接寻址法 (各有优劣)Hash算法: 除留余数法(求模) --> 开放寻址法(前后一个地址) --> 拉链法2.2 Hash算法的应用场景Hash算法在很多分布式集群产品中都有应⽤,分布式集群架构Redis、Hadoop、ElasticSearch,Mysql分库分表,Nginx负载均衡等。主要的应用场景归纳起来两个:1. 请求的负载均衡(比如nginx的ip_hash策略)对ip地址或者sessionid进⾏计算哈希值,哈希值与服务器数量进⾏取模运算,得到的值就是当前请求应该被路由到的服务器编号。C语言Nginx源码在设计ip_hash模块中,取ip地址前三段计算哈希值,来判断ip是否来源于同一网段,以此为基础锁定路由的服务器,实现会话粘滞。2. 分布式存储以分布式内存数据库Redis为例,集群中有redis1,redis2,redis3 三台Redis服务器,在进⾏数据<key1,value1>存储时,针对key进⾏hash处理:hash(key1)%3=index,使用余数index锁定存储的具体服务器节点。2.3 一致性Hash算法普通Hash算法存在的问题:服务器扩容缩容时,算法结果会改变,导致请求迁移一致性Hash算法原理:哈希环对232取模,232个点组成的圆环称为Hash环1. 服务节点的IP或者机器名称进行哈希,就能确定每台机器在哈希环上的位置;2. 将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置;从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。添加、删除节点的时候,只影响相邻一个节点的数据,其他节点的数据不影响为了防止数据分布不均匀,可以应用虚拟节点来映射物理节点。2.4 手写一致性Hash算法public class ConsistentHashWithVirtual {

public static void main(String[] args) {
    //step1 初始化:把服务器节点IP的哈希值对应到哈希环上
    // 定义服务器ip
    String[] tomcatServers = new String[]{"123.111.0.0","123.101.3.1","111.20.35.2","123.98.26.3"};

    SortedMap<Integer,String> hashServerMap = new TreeMap<>();

    // 定义针对每个真实服务器虚拟出来几个节点
    int virtaulCount = 3;

    for(String tomcatServer: tomcatServers) {
        // 求出每一个ip的hash值,对应到hash环上,存储hash值与ip的对应关系
        int serverHash = Math.abs(tomcatServer.hashCode());
        // 存储hash值与ip的对应关系
        hashServerMap.put(serverHash,tomcatServer);

        // 处理虚拟节点
        for(int i = 0; i < virtaulCount; i++) {
            int virtualHash = Math.abs((tomcatServer + "#" + i).hashCode());
            hashServerMap.put(virtualHash,"----由虚拟节点"+ i  + "映射过来的请求:"+ tomcatServer);
        }

    }

    //step2 针对客户端IP求出hash值
    // 定义客户端IP
    String[] clients = new String[]{"10.78.12.3","113.25.63.1","126.12.3.8"};
    for(String client : clients) {
        int clientHash = Math.abs(client.hashCode());
        //step3 针对客户端,找到能够处理当前客户端请求的服务器(哈希环上顺时针最近)
        // 根据客户端ip的哈希值去找出哪一个服务器节点能够处理()
        SortedMap<Integer, String> integerStringSortedMap = hashServerMap.tailMap(clientHash);
        if(integerStringSortedMap.isEmpty()) {
            // 取哈希环上的顺时针第一台服务器
            Integer firstKey = hashServerMap.firstKey();
            System.out.println("==========>>>>客户端:" + client + " 被路由到服务器:" + hashServerMap.get(firstKey));
        }else{
            Integer firstKey = integerStringSortedMap.firstKey();
            System.out.println("==========>>>>客户端:" + client + " 被路由到服务器:" + hashServerMap.get(firstKey));
        }
    }
}

}三、集群时钟同步问题时钟此处指服务器的时间,集群节点时间不一致会导致问题如何解决?场景1:分布式集群中各个服务器节点都可以连接互联⽹#使⽤ ntpdate ⽹络时间同步命令ntpdate -u ntp.api.bz #从⼀个时间服务器同步时间场景2:分布式集群中有服务器节点不可以连接互联⽹使用可以联网的节点作为局域网内的时间服务器,或选定一台固定的服务器,其它节点从该时间服务器同步时间。四、分布式ID解决方案分布式集群环境下的全局唯⼀ID4.1 UUID Universally Unique Identifier可以用,但长、没有规律、作为主键索引效率低.4.2 独立数据库的自增ID单独的创建⼀个Mysql数据库,模拟插入自增,然后获取最新的IDinsert into DISTRIBUTE_ID(createtime) values(NOW());select LAST_INSERT_ID();不推荐,性能和可靠性都不好。4.3 雪花算法 SnowFlake4.4 借助Redis的Incr命令获取全局唯⼀ID(推荐)五、分布式调度问题(定时任务的分布式)什么是分布式任务调度?分2种情况1. 运⾏在分布式集群环境下的调度任务即同⼀个定时任务程序部署多份,只应该有⼀个定时任务在执⾏。2. 分布式调度 --> 定时任务的分布式 --> 定时任务的拆分即把⼀个⼤的作业任务拆分为多个⼩的作业任务,同时执⾏。5.1 定时任务和消息队列的区别共同点1. 异步处理2. 应用解耦3. 流量削峰(后端系统根据服务能⼒定时处理订单或者从MQ抓取订单抓取到⼀个订单到来事件的话触发处理)本质区别定时任务是时间驱动,而MQ是事件驱动定时任务作业更倾向于批处理,MQ倾向于逐条处理5.2 任务调度框架Quartz时间表达式(包括:秒、分、时、⽇、月、周、年)配置
*示例:

  • 0 0 11 * * ? 每天的11点触发执⾏⼀次
  • 0 30 10 1 * ? 每⽉1号上午10点半触发执⾏⼀次5.3 分布式调度框架Elastic-JobElastic-Job是当当⽹开源的⼀个分布式调度解决方案,基于Quartz⼆次开发的,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。主要功能:1. 分布式调度协调2. 丰富的调度策略3. 弹性扩容缩容4. 失效转移5. 错过执行作业重触发6. ⽀持并行调度7. 作业分片⼀致性5.4 Elastic-Job-Lite + zookeeper轻量级:All in Jar,仅依赖zookeeper,非独立部署的中间件去中心化:1. 执行节点对等2. 定时调度自触发3. 服务自发现4. 主节点非固定5.5 分片及扩容缩容ElasticJob可以把作业分为多个的task(每⼀个task就是⼀个任务分⽚),每⼀个task交给具体的⼀个机器实例去处理(⼀个机器实例是可以处理多个task的),但是具体每个task执⾏什么逻辑由我们⾃⼰来指定。六、Session共享(一致性)问题因为Http协议是⽆状态的协议,所以第⼆次请求服务端⽆法认识到我们曾经来过为了保持Http状态的技术,于是有了Cookie和Session。而当服务端集群部署,nginx采用默认轮询策略时,便会产生session不一致的问题。解决Session⼀致性的⽅案1. Nginx的 IP_Hash 策略(可用)优点:配置简单,不侵入应用缺点:服务器重启session丢失、存在单点负载高的风险、单点故障2. Session复制(不推荐)通过网络通信的组播机制实现Session同步(TCP)优点:不侵入应用、便于水平扩展、重复不会造成丢失缺点:性能低、有延时、消耗内存3. Session共享,Session集中存储(推荐)优点:使用各种负载均衡策略、不丢失、扩展强、适合大集群数量使用缺点:对应用有入侵,引入了和Redis的交互代码SpringSession原理示意图
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值