回到目录:

OrangeZh:拉勾教育:JAVA高薪训练营 学习技术篇​zhuanlan.zhihu.com

介绍

文章内容输出来源:拉勾教育 Java高薪训练营

分布式集群解决方案相关

什么是分布式?什么是集群?

分布式:把一个系统拆分成多个子系统,每个子系统负责各自的功能,独立部署

集群啊:多个实例共同工作,将一个应用多份部署

一、一致性Hash算法

Hash算法应用:密码学的安全加密(MD5、SHA等),数据存储和查找(Hash表,查询效率高)

Hash表:Hash表的查询效率与Hash算法关系密切,Hash算法能够让数据平均分布,既能节省空间又能提高查询效率

Hash算法在分布式集群架构中的应用场景

分布式集群架构Redis、Hadoop、ElasticSearch,Mysql分库分表,Ngnix负载均衡等

主要应用场景:

  • 请求的负载均衡(ngnix的ip_hash策略)
  • IP_Hash策略:可以在客户端ip不变的情况下,将请求始终路由到同一服务器,实现会话粘滞,避免处理Session共享问题
  • 分布式存储

普通Hash算法存在的问题

服务器宕机或者新加服务器会出现重新求模问题,会导致大量客户端会话丢失

一致性Hash算法

负载均衡算法中的一种,相同的请求到固定的服务器上,当服务器宕机或者新增机器时只影响少部分请求到不同的服务器上;

原理:Hash环,根据服务器IP或者其它取hash值,置于hash环中,每个请求取hash,置于hash环中,按照顺时针方向取,遇到的第一个服务器hash就是处理此请求的服务器;

当服务器宕机或者新增服务器时只会影响宕机或者新增服务器顺时针相关的服务器,不会影响其它;

为了避免数据倾斜,加入了虚拟节点,让每个服务器计算多个虚拟hash值,让每个节点在环中分布得更加均匀

Hash算法:

/*** Hash算法,性能高,碰撞率低** @param key String* @return Long*/public Long hash(String key) {ByteBuffer buf = ByteBuffer.wrap(key.getBytes());int seed = 0x1234ABCD;ByteOrder byteOrder = buf.order();buf.order(ByteOrder.LITTLE_ENDIAN);long m = 0xc6a4a7935bd1e995L;int r = 47;long h = seed ^ (buf.remaining() * m);long k;while (buf.remaining() >= 8) {k = buf.getLong();k *= m;k ^= k >>> r;k *= m;h ^= k;h *= m;}if (buf.remaining() > 0) {ByteBuffer finish = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);finish.put(buf).rewind();h ^= finish.getLong();h *= m;}h ^= h >>> r;h *= m;h ^= h >>> r;buf.order(byteOrder);return h;}

实现一致性Hash算法

// 定义服务器ip
private static String[] tomcatServers = new String[]{"123.111.0.0", "123.101.3.1", "111.20.35.2", "123.98.26.3"};// 定义客户端IP
private static String[] clients = new String[]{"10.78.12.3", "113.25.63.1", "126.12.3.8"};/*** 一致性Hash算法 含虚拟节点*/
private static void consistentHashWithVirtual() {//step1 初始化:把服务器节点IP的哈希值对应到哈希环上SortedMap<Integer, String> hashServerMap = new TreeMap<>();// 定义针对每个真实服务器虚拟出来几个节点int virtualCount = 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 < virtualCount; i++) {int virtualHash = Math.abs((tomcatServer + "#" + i).hashCode());hashServerMap.put(virtualHash, "----由虚拟节点" + i + "映射过来的请求:" + tomcatServer);}}//step2 针对客户端IP求出hash值System.out.println("==========>>>> ConsistentHashWithVirtual <<<<==========");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));}}
}

算法实现:一致性Hash算法

Ngnix配置一致性Hash负载均衡策略

ngx_http_upstream_consistent_hash 模块是⼀个负载均衡器,使⽤⼀个内部⼀致性hash算法来选择合适的后端节点。

该模块可以根据配置参数采取不同的⽅式将请求均匀映射到后端机器

  • consistent_hash $remote_addr:可以根据客户端ip映射
  • consistent_hash $request_uri:根据客户端请求的uri映射
  • consistent_hash $args:根据客户端携带的参数进⾏映

二、集群时钟同步问题

问题:在集群机器中可能存在不同服务器之间服务器时间不一致

解决方法:

  • 场景1:分布式集群中各个服务器节点都可以连接互联⽹
#使⽤ ntpdate ⽹络时间同步命令
ntpdate -u ntp.api.bz #从⼀个时间服务器同步时间#windows有计划任务
#Linux也有定时任务,crond,可以使⽤linux的定时任务,每隔10分钟执⾏⼀次ntpdate命令

  • 场景2:分布式集群中某⼀个服务器节点可以访问互联⽹或者所有节点都不能够访问互联⽹
    选取集群中的⼀个服务器节点A(172.17.0.17)作为时间服务器(整个集群时间从这台服务器同步,如果这台服务器能够访问互联⽹,可以让这台服务器和⽹络时间保持同步,如果不能就⼿动设置⼀个时间)
    ⾸先设置好A的时间
    把A配置为时间服务器(修改/etc/ntp.conf⽂件)
1、如果有 restrict default ignore,注释掉它
2、添加如下⼏⾏内容
restrict 172.17.0.0 mask 255.255.255.0 nomodify notrap # 放开局
域⽹同步功能,172.17.0.0是你的局域⽹⽹段
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
3、重启⽣效并配置ntpd服务开机⾃启动
service ntpd restart
chkconfig ntpd on

集群中其他节点就可以从A服务器同步时间了

ntpdate 172.17.0.17

三、分布式ID解决方案

因为分库分布后不能使用自动递增主键,所以数据库分库分表时需要一种能够产生全局唯一ID的方案

使用UUID

UUID 是指Universally Unique Identifier,翻译为中⽂是通⽤唯⼀识别码

产⽣重复 UUID 并造成错误的情况⾮常低,是故⼤可不必考虑此问题。

Java中得到⼀个UUID,可以使⽤java.util包提供的⽅法:

java.util.UUID.randomUUID()

独⽴数据库的⾃增ID(性能低,不可靠,部署成集群比较麻烦)

单独维护一个ID自增表,但性能低,如果库挂了就无法获取了,可靠性不够高

SnowFlake 雪花算法(可以⽤,推荐)

雪花算法是Twitter推出的⼀个⽤于⽣成分布式ID的策略。

雪花算法是⼀个算法,基于这个算法可以⽣成ID,⽣成的ID是⼀个long型,那么在Java中⼀个long型是8个字节,算下来是64bit,如下是使⽤雪花算法⽣成的⼀个ID的⼆进制形式示意:

SnowFlake雪花算法

一些互联⽹公司也基于上述的⽅案封装了⼀些分布式ID⽣成器,⽐如滴滴的tinyid(基于数据库实现)、百度的uidgenerator(基于SnowFlake)和美团的leaf(基于数据库和SnowFlake)等

算法实现:SnowFlake 雪花算法

使用Redis的Incr命令获取全局唯⼀ID(推荐)

存一个全局的自增数到一个redisKey中

四、分布式调度问题(定时任务的分布式执行)

定时任务场景

定时任务形式:每隔⼀定时间/特定某⼀时刻执⾏

例如:

订单审核、出库
订单超时⾃动取消、⽀付退款
礼券同步、⽣成、发放作业
物流信息推送、抓取作业、退换货处理作业
数据积压监控、⽇志监控、服务可⽤性探测作业
定时备份数据
⾦融系统每天的定时结算
数据归档、清理作业
报表、离线数据分析作业

什么是分布式调度

1)运⾏在分布式集群环境下的调度任务(同⼀个定时任务程序部署多份,只应该有⼀个定时任务在执⾏)

2)分布式调度—>定时任务的分布式—>定时任务的拆分(即为把⼀个⼤的作业任务拆分为多个⼩的作业任务,同时执⾏)

分布式任务调度

定时任务与消息队列的区别

共同点:

  • 异步处理 ⽐如注册、下单事件
  • 应⽤解耦 不管定时任务作业还是MQ都可以作为两个应⽤之间的⻮轮实现应⽤解耦,这个⻮轮可以中转数据,当然单体服务不需要考虑这些,服务拆分的时候往往都会考虑
  • 流量削峰 双⼗⼀的时候,任务作业和MQ都可以⽤来扛流量,后端系统根据服务能⼒定时处理订单或者从MQ抓取订单抓取到⼀个订单到来事件的话触发处理,对于前端⽤户来说看到的结果是已经下单成功了,下单是不受任何影响的

本质不同:

  • 定时任务作业是时间驱动,⽽MQ是事件驱动
  • 时间驱动是不可代替的,⽐如⾦融系统每⽇的利息结算,不是说利息来⼀条(利息到来事件)就算⼀下,⽽往往是通过定时任务批量计算;
  • 定时任务作业更倾向于批处理,MQ倾向于逐条处理;

定时任务的实现方式(任务调度框架Quartz)

定时任务的实现⽅式有多种。早期没有定时任务框架的时候,我们会使⽤JDK中的Timer机制和多线程机制(Runnable+线程休眠)来实现定时或者间隔⼀段时间执⾏某⼀段程序;后来有了定时任务框架,⽐如⼤名鼎鼎的Quartz任务调度框架,使⽤时间表达式(包括:秒、分、时、⽇、周、年)配置某⼀个任务什么时间去执⾏

<!--任务调度框架quartz-->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version>
</dependency>

示例实现:示例

分布式调度框架Elastic-Job

Elastic-Job是当当⽹开源的⼀个分布式调度解决⽅案,基于Quartz⼆次开发的,由两个相互独⽴的⼦项⽬Elastic-Job-Lite和Elastic-Job-Cloud组成

Elastic-Job的github地址:https://github.com/elasticjob

五、Session共享(一致性)问题

Session问题原因分析

路由后到了不同的服务器,导致了Session丢失,会出现重复登录问题

Session问题

解决Session⼀致性的⽅案

  • Nginx的 IP_Hash 策略(可以使⽤)
    同⼀个客户端IP的请求都会被路由到同⼀个⽬标服务器,也叫做会话粘滞
    优点:配置简单,不⼊侵应⽤,不需要额外修改代码
    缺点:服务器重启Session丢失、存在单点负载⾼的⻛险、单点故障问题
  • Session复制(不推荐)
    多个tomcat之间通过修改配置⽂件,达到Session之间的复制,通过TCP进行同步
    优点:不⼊侵应⽤、便于服务器⽔平扩展、能适应各种负载均衡策略、服务器重启或者宕机不会造成Session丢失
    缺点:性能低、内存消耗、不能存储太多数据,否则数据越多越影响性能、延迟性
  • Session共享,Session集中存储(推荐)
    Session的本质就是缓存,那Session数据可以存入缓存中间件Redis中
    优点:能适应各种负载均衡策略、服务器重启或者宕机不会造成Session丢失、扩展能⼒强、适合⼤集群数量使⽤
    缺点:对应⽤有⼊侵,引⼊了和Redis的交互代码
    Spring Session使得基于Redis的Session共享应⽤起来⾮常之简单

回到目录:

OrangeZh:拉勾教育:JAVA高薪训练营 学习技术篇​zhuanlan.zhihu.com

tcp out of order解决_分布式集群解决方案 学习笔记相关推荐

  1. Hadoop安装教程_分布式集群

    安装前的准备 伪分布式的设置 集群的规划 集群的初始设置 网络配置 SSH无密码登陆 java及apache环境设置 安装流程 主机的安装 集群的安装 效果与验证 安装注意 模式切换 参考资料 安装前 ...

  2. Hadoop集群安装部署_分布式集群安装_02

    文章目录 一.上传与 解压 1. 上传安装包 2. 解压hadoop安装包 二.修改hadoop相关配置文件 2.1. hadoop-env.sh 2.2. core-site.xml 2.3. hd ...

  3. Hadoop集群安装部署_分布式集群安装_01

    文章目录 1. 分布式集群规划 2. 数据清理 3. 基础环境准备 4. 配置ip映射 5. 时间同步 6. SSH免密码登录完善 7. 免密登录验证 1. 分布式集群规划 伪分布集群搞定了以后我们来 ...

  4. 龙果学院mysql分布式集群代码_龙果学院-MySQL大型分布式集群解决方案

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1 课程概述 2 课程背景 3 纵观大型网站架构发展,总结持久化部分需要应对的问题 4 操作系统安装以及配置 5 在CentOS上通过yum安装mysql ...

  5. NetApp DataONTAP 集群模式 学习笔记1

    一.NetApp存储操作系统 Data ONTAP是NetApp最流行的存储操作系统,它运行在NetApp FAS(Fabric Attached Storage)系统上.FAS系统是被设计为共享的存 ...

  6. 【redis集群】学习笔记

    主从 (1)redis-6379 的配置文件,6380和6381相似 1 include /etc/redis/redis.conf2 pidfile /var/run/redis-pid/maste ...

  7. java集群session共享_分布式/集群下session共享方案汇总

    1.F5 BIG-IP 硬件实现session粘性复制 F5 硬件,可以作为HTTP负载均衡器使用,可以将用户IP与Session通过F5进行的绑定,使其Session保持一致性.是直接通过智能交换机 ...

  8. websocket 单机服务 和 分布式集群解决方案

    1.为什么有了http还需要websocket 为 HTTP 协议有一个缺陷:通信只能由客户端发起,如果服务器有连续的状态变化,只能使用"轮询" WebSocket 服务器可以主动 ...

  9. 分布式 集群 系统组件架构_分布式跟踪系统的四个组件如何一起工作

    分布式 集群 系统组件架构 十年前,基本上只有认真思考分布式跟踪的人是学者和少数大型互联网公司. 如今,对于任何采用微服务的组织来说,它已经变成了赌注. 基本原理是公认的:微服务以令人惊讶且通常是惊人 ...

最新文章

  1. MySQL的元数据锁MDL发生场景和解决方法总结
  2. PHP5 $this self parent static的区别
  3. 山东财经大学python实验六答案_实验六(带答案)
  4. Java项目开发全程实录pdf
  5. SAD立体匹配算法在opencv中的实现
  6. 利用python进行统计分析学习笔记 第7章
  7. python 还原九宫格图片_用Python做一个好玩的朋友圈九宫格抽奖
  8. 计算机及相关设备制造业2020,在现实生活中,接近完全垄断市场类型的行业包括()。A.计算机及相关设备制造业B.稀有...
  9. P3203 [HNOI2010]弹飞绵羊
  10. Java LocalDate类| parse()方法与示例
  11. 华为P30真机屏幕盖板曝光:超窄边框水滴屏
  12. shell脚本执行时报bad interpreter: Text file busy的解决方法
  13. HTML5.1 推荐中 1.5.3. Extensibility 段落翻译
  14. EPS电动转向系统分析
  15. Windows显示文件名后缀的方法
  16. idea_设置项目编码
  17. 如何在window电脑和Ipad之间互传文件之优雅的解放Ipad生产力
  18. lm做自相关做几阶_lm检验(lm检验怎么判断是几阶自相关)
  19. MapReduce经典案例总结
  20. E-PUCK机器人-FAQ

热门文章

  1. 微信接口调用 ---ACCESS_TOKEN
  2. CSS之 :before :after的用法,伪类和伪元素的区别
  3. 如何理解IIS 7的两种应用程序池的管道模式(Managed Pipeline Mode)
  4. 北斗词卡(三):带你了解北斗相关的国际组织缩写
  5. 华为机器狗 VS 波士顿狗,谁更胜一筹?
  6. Python3编程语言之zip() 函数使用示例
  7. 陈中华:李彦宏候选工程院院士,是全中国人民的大耻辱
  8. 计算机AL教程笔记,计算机系统基础学习笔记(2)-数据的位运算操作
  9. java 二维数组的定义
  10. 037_Dropdown下拉菜单