tcp out of order解决_分布式集群解决方案 学习笔记
回到目錄:
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:分布式集群中各個服務器節點都可以連接互聯?
- 場景2:分布式集群中某?個服務器節點可以訪問互聯?或者所有節點都不能夠訪問互聯?
選取集群中的?個服務器節點A(172.17.0.17)作為時間服務器(整個集群時間從這臺服務器同步,如果這臺服務器能夠訪問互聯?,可以讓這臺服務器和?絡時間保持同步,如果不能就?動設置?個時間)
?先設置好A的時間
把A配置為時間服務器(修改/etc/ntp.conf?件)
集群中其他節點就可以從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解决_分布式集群解决方案 学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取视频流做人脸识别_基于O
- 下一篇: python exe运行报 编码错误_p