分類
發燒車訊

給女朋友講解什麼是Git

前言

在周六發現了Linus去Google演講的一個視頻,當時還發了一條朋友圈:

有興趣的同學也可以去看看,一點兒也不無聊,在線看Linus大佬懟人

https://www.bilibili.com/video/BV1xb411A7ac?from=search&seid=4239535088233137638

朋友圈的評論有幾個人問我女朋友

我又恰好給我女朋友科普過什麼是Git,所以這篇文章就有了。

Git介紹

Git是幹啥用的?它是一個版本控制軟件。

Git這個玩意三歪曾經還給女朋友給科普過(三歪會經常給女朋友說點技術的東西,我也不知道她到底聽懂了沒有,反正她每次都說好像有點懂了)。

當時情況是這樣的,某一天她跟三歪說:我做的Excel還沒保存,電腦藍屏死機了,東西全丟了。

於是三歪說:這…我也沒怎麼用過Excel這類的軟件,要不看看你用的WPS或者Office?有沒有相關的備份功能或者說是自動保存?

三歪順手找了一下WPS是有備份(自動保存)功能的,時間什麼的要自己定義一下。

三歪還補了一句:這種情況要是在程序員的手上感覺發生的概率會低一點,程序員習慣會按ctrl+s。甚至有的時候,看着看着網頁還會按ctrl+s。不過像我們寫代碼的工具(IDEA)都不用自己手動保存了….

過了一會,她說藍屏之前做的東西找不回來了,沒設置自動保存。

三歪又感嘆一句:我們寫代碼還有版本控制的軟件,在這個過程中會記錄每次修改的內容,誰改了什麼東西。誰改錯了,誰要背鍋,一個都不能跑

女朋友聽着三歪一頓亂吹,貌似也有點感興趣:“版本控制是什麼東西?這麼厲害的嗎?會計就經常要背鍋”

三歪:“其實也沒啥,就是我們一般寫代碼往往都是多人協作的。你們會計可能是每個人負責一張表(Excel),然後把已完成好的表傳給下一個人。而寫代碼的不一樣,我們都是在同一個項目裡邊編寫的,不會單獨等着某個人做完了,其他的人再開始動手”

女朋友:“嗯?然後呢”

三歪:“你可以理解成,我們多個人會在同一個目錄下編寫代碼,裡邊可能會做更改或者添加文件的操作。項目組裡的所有人都可以對這個目錄修改,改完了我們會提交,然後發布上線系統。”

女朋友:“啥?你是不是偏題了?這跟發布上線系統有啥關係?”

三歪:“哦,我還是舉個例子吧。就比如我們寫論文的時候可能要對論文不斷修改,我們的修改是基於原有的基礎上改的”

三歪繼續補充:”因為我們怕在原來的基礎改錯了東西,沒法恢復,所以,我們可能會有多個「畢業論文」的文件。而我們寫代碼的時候本身就是「多人協作」的,修改是無法避免的,我們不希望有多個文件的產生,又希望能夠記錄每次更改的內容。“

三歪:”更改的內容指的就是:基於原有的基礎上更改了什麼,以及提交者是誰。這樣子,我們就沒法甩鍋了。說白了就是,我們能知道的文件被改了什麼,以及誰改了“。

三歪:“到這裏,有問題嗎?”

女朋友:“嗯,沒問題,你繼續”

三歪:“「每一次的修改」我們稱為一個版本,它能夠實現版本與版本之間的來回穿梭。打個比方,我有篇文章寫了一周,這期間有10個版本,我能隨意回到我想要的版本。所以它叫做版本控制軟件”

女朋友:“我大致聽懂了,大概就是每一次修改都會被記錄下來,然後你們就可以知道每一次版本修改了什麼,是誰改的,如果做錯了,可以通過這個軟件回到想要的版本”

三歪:“嗯,就是這個意思”

女朋友:“那我想問個問題,你一直提到的「多人協作」是在同一個目錄下對文件修改的,然後可以看到彼此改了什麼。那你是在你的電腦上改,你的同事是在他的電腦上改的,你們是怎麼看到彼此改了什麼?這現在有這麼厲害的東西了嗎?“

三歪:”哦~你的意思大概就是:我們又不聯網,怎麼知道對方改了什麼,是這個意思吧?“

女朋友:“嗯,是的”

三歪:“你的理解是沒錯的,我們之間不聯網,是沒辦法知道對方改了什麼的。我漏了一點沒說,我們在改到一定程度下(比如說這個功能我們做完了、也可能做得差不多了),我們會把當前版本提交到遠程倉庫上”

三歪繼續補充:“可以發現的是,提交到遠程倉庫后,即便我們電腦壞了,我們可以從遠程倉庫再把這份數據拉取下來。”

女朋友:“所以呢?遠程倉庫到我這聽起來就是一個備份的功能吧?你們怎麼知道對方改了什麼?”

三歪:“是這樣的,我們從遠程倉庫拉取代碼的時候除了會把有變動的代碼同步到自己的電腦上,還會把所有修改的記錄也同步到自己的電腦上。所以說,我們會知道彼此修改的內容。”

女朋友:”聽着很有用啊,我平時用的word和excel可以用這個軟件嗎?即便我電腦壞了,我還可以去『遠程倉庫』拿到上一次我提交的數據,並且還有你所說的『版本控制』功能。又能備份,又能知道每次修改了什麼,很好用啊!“

三歪:”很可惜,像你們那種工作場景,可能用不上,也可以說不太適合用“

女朋友:”為什麼?“

三歪:”之前我也想要用定時任務+GitHub的方式去保存我在本地寫的文章,發出來之後,被一頓噴。GitHub你可以簡單理解為就是那個遠程倉庫,定時任務我就是讓它隔一段時間就保存一次“

女朋友:”我聽明白了,你想要的是備份功能,對吧?為什麼被噴的呢?“

三歪:”他們說我瞎整,這每隔一段時間就提交到GitHub,網絡開銷可多大啊。然後給我列出一系列的產品,比如說:「堅果雲」「Dropbox」「OneDrive」等等“

女朋友:”那你怎麼不用?“

三歪:”我哪知道啊,有信息差的呢。反正當時覺得自己寫個定時任務實現了,就沒多想了。“

女朋友:”那你是真的菜“

三歪:”哦“

三歪:”除了上面說的自動同步,你們的word、excel在用我們的工具也沒法查到歷史的版本記錄“

女朋友:”為啥?你不是說你們寫代碼都可以的嗎?為什麼word和excel就沒法查?“

三歪:”我們寫代碼的文件類型都是屬於文本文件,而你的word、excel本質上屬於二進制文件,很難去比對每次修改的差異,所以不支持“

女朋友:”那聽你這樣說,在我的場景里這個「版本控制軟件」沒啥用啊,它不能記錄像Word、Excel這種文件每次版本的差異,要想用它做備份,還不如現有的雲產品。“

三歪:”嗯,是的。其實現在雲產品也能提供版本控制的功能了,你用它們就足夠了。還有一點很重要的是,它有學習成本,可不是每個人都會用的。“

女朋友:”聽你說了這麼多,好像雲產品就很行啊,為啥你們還要「偏執」去用你說的那東西?“

三歪:“主要是我們寫代碼時遇到的問題會更多,我們用的「版本控制軟件」會更加靈活,它支持的功能會更多。”

女朋友:“對了,你都說了這麼久了,你們用的那個軟件叫啥啊?”

三歪:“Git

三歪瞎扯

其實本來想着直接講一下在工作中常用到的Git命令,但發現不太好寫(琢磨了很久

看三歪文章的人可能很多都是大學生,對Git本身了解可能就不太清楚,直接上Git的命令可能看不太懂,所以就分開了兩篇。

下一篇講一下三歪在工作中使用Git的糗事以及工作中是怎麼用Git的。

涵蓋Java後端所有知識點的開源項目(已有8K+ star):

  • GitHub
  • Gitee訪問更快

我是三歪,一個想要變強的男人,感謝大家的點贊收藏和轉發,下期見。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

LeetCode 76,一題教會你面試算法時的思考套路

本文始發於個人公眾號:TechFlow,原創不易,求個關注

今天是LeetCode專題的第45篇文章,我們一起來看看LeetCode的76題,最小窗口子串Minimum Window Substring。

這題的官方難度是Hard,通過了也是34.2%,4202人點贊,299人反對。從通過率以及點贊比來看,這題的質量很高,稍稍有些偏難,所以小夥伴們請做好準備,這是一道有點挑戰的問題。

題意和樣例

我們一起來看下題意,這題的題意很短,給定兩個字符串S和T。要求設計一個複雜度為的算法,在S串當中找到一個子串,能夠包含T串當中的所有字符。要求返回合法且長度最小的窗口的內容。

注意:

  • 如果不存在這樣的窗口,返回“”。
  • 如果窗口存在,題目保證有且只有一個。

樣例:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

分析

我們來分析一下這個問題,從題意當中大家應該都能感受到它的難度。因為上來題目當中就限定了我們使用的算法的複雜度必須是,然而我們遍歷字符串的複雜度就已經是了,也就是說我們不能引入額外的計算開銷,否則一定不滿足題目的要求。

可能有些同學會想到傳說中在時間內判斷字符串匹配的KMP算法,如果你不知道這個算法也沒有關係,因為這個算法並不適用。因為我們要找的不是完全相等的子串的位置,而是找的是字符構成一樣的子串,所以並不能通過引入字符串匹配算法來解決。沒有學過KMP算法的同學可以松一口氣了,這題當中並不會引入新的算法。

解題的套路

一般來說當我們面臨一個算法問題的時候,我們常常的思考過程主要有兩種。一種是適配,說白了就是把可能可以用上的算法往問題上套。根據題意先感覺一下,大概會用到什麼樣的算法,然後詳細地推導適配的過程,看看是不是真的適用或者是有什麼坑,或者是會出現什麼新的問題。如果一切OK,能夠推理得通,那麼這個算法就是解。第二種方法是建模,也就是說從題意入手,對題意進行深入的分析,對問題進行建模和抽象,找到問題的核心,從而推導出用什麼樣的算法可以解決。

舉個很簡單的例子,一般來說我們的動態規劃算法都是適配。都是我們先感覺或者是猜測出可以使用動態規劃,然後再去找狀態和轉移,最後建立狀態轉移方程。而一些搜索問題一般是建模,我們先對問題進行分析,然後找出需要搜索的解的存在空間,然後設計算法去搜索和剪枝,最後找到答案。

據說一些頂級高手這兩種方法是一起使用的,所以才可以那麼快速地找到解。當然我不是頂級高手,所以這個也只是我的猜測。這個思考過程非常有用,特別是當我們面試的時候,遇到一個從未見過的問題,如果你什麼套路也沒有,頭腦一片空白或者是苦思冥想不得要領是很常見的事情。當你有了套路之後,你就可以試着慢慢找到答案了。

回到這道題本身,我們剛才已經試過了,拿字符串匹配的算法網上套是不行的。在視野里似乎也沒有其他的算法可以套用,所以我們換一種思路,試試看建模。

首先我們可以肯定一點,我們需要在遍歷的時候找到答案,這樣才可以保證算法的複雜度是。我們的目標是尋找子串,也就是說我們遍歷的過程應該對應一個子串,並且我們有方法可以快速判斷這個子串是否合法。這樣我們才可以做到遍歷的同時判斷答案的可行性。進而可以想到這是一個區間維護的問題,區間維護我們經常使用的方法就是two pointers。所以我們可以試試two pointers能否適用。

實際上這道題的正解就是two pointers。

題解

我們維護了一個區間,我們需要判斷區間里的字符構成,這個很容易想到可以使用dict,維護每一個字符出現的次數。在這個題目當中,我們只需要考慮覆蓋的情況,也就是說字符多了並不會構成非法。所以我們可以維護一個dict,每次讀入一個字符更新它,當dict當中的字符滿足要求的時候,為了使得區間長度盡量短,我們可以試着移動區間的左側,盡量縮短區間的長度。

從區間維護的角度來說,我們每次移動區間右側一個單位,只有當區間內已經滿足題意的時候才會移動左側。通過移動左側彈出元素來獲取能夠滿足題意的最佳區間。

我們來看下主要的流程代碼:

# 存儲區間內的字符
segement = {}
for i in range(n):
    segement[s[i]] += 1
    # 當滿足條件的時候移動區間左側
    while l <= i and satisified(segment):
        # 更新最佳答案
        if i - l + 1 < ans_len:
            ans_len = i - l + 1
            beg, end = l, i + 1
        # 彈出元素
  segement[s[l]] -= 1
        l += 1

到這裏還有一個小問題,就是怎麼樣判斷這個segment是否合法呢?我們可以用一個数字matched來記錄目前已經匹配上的字符的數量。當某個字符在segment當中出現的次數和T中的次數相等的時候,matched加一。當matched的數量和T中字符種類的數量相等的時候,就可以認為已經合法了。

我們把所有的邏輯串起來,就可以通過這題了。

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        from collections import Counter, defaultdict
        # 通過Counter直接獲取T當中的字符構成
        counter = Counter(t)
        n, m = len(s), len(counter)
        l, beg, end = 0, 0, 0
        cur = defaultdict(int)
        matched = 0
        flag = False
        # 記錄合法的字符串的長度
        ans_len = 0x3f3f3f3f
        
        for i in range(n):
            if s[i] not in counter:
                continue
                
            cur[s[i]] += 1
            # 當數量匹配上的時候,matched+1
            if cur[s[i]] == counter[s[i]]:
                matched += 1
                
            # 如果已經找到了合法的區間,嘗試縮短區間的長度
            while l <= i and matched == m:
                if i - l + 1 < ans_len:
                    flag = True
                    beg, end = l, i+1
                    ans_len = i - l + 1
                    
                # 彈出左側元素
                c = s[l]
                if c in counter:
                    cur[c] -= 1
                    if cur[c] < counter[c]:
                        matched -= 1
                        
                l += 1

        
        return "" if not flag else s[beg: end]

總結

到這裏,這道題就算是解決了。很多同學可能會覺得疑惑,為什麼我們用到了兩重循環,但是它依然還是的算法呢?

這個是two pointers算法的常見問題,也是老生常談的話題了。我們在分析複雜度的時候,不能只簡單地看用到了幾層循環,而是要抓住計算的核心。比如在這個問題當中,我們內部的while循環針對的變量是l,l這個變量對於i整體是遞增的。也就是說無論外面這個循環執行多少次,裏面的這個while循環一共最多累加只能執行n次。那麼,當然這是一個的算法。

這題總體來說有些難度,特別是一開始的時候可能會覺得沒有頭緒無從下手。這個時候有一個清晰的頭腦以及靠譜的思考鏈非常重要,希望大家都能學到這個其中思維的過程,這樣以後才可以應付更多的算法問題。

如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

本文使用 mdnice 排版

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

真慘!連各大編程語言都擺起地攤了!

困難年年有,今年特別多。

公司要做一個新的網站,可預算有限,聽說為了生計,各大編程語言們都擺起了地攤兒,我決定去瞧瞧,看看能不能淘點做網站需要的東西。

選擇靜態web服務器

一進集市,這煙火氣就撲面而來,平時一個個端着架子的C++、Java、Python居然能放下身段,招呼叫賣,我還是頭一回見。

“老哥,需要來點什麼?”,C語言給我打起了招呼。

“我想要建個網站”,我回答到。

“那你可算來對地方了”,C語言攤主起身說到,“建網站總得需要一個Web服務器吧,你看這裏,apacheweb服務器,賣的可好了”

我搖了搖頭,“這個apache,之前有用過,是用的多進程模型,連接多了有些吃力啊?”

“老哥是行家啊,來看這一款我們最新推出的nginx服務器,採用epoll多路復用+事件驅動,性能強勁!上萬連接不在話下”,C語言攤主自豪的說到。

隨後攤主給我展示了這個nginx服務器的能力,果然不錯,我加入了購物車,繼續往前逛。

挑選web應用開發框架

沒走幾步來到 C# 的攤前。

“喲,老哥,你這是要做網站啊?”,C#攤主主動給我打起了招呼。

“你怎麼知道的?”,我好奇的問到。

“你這購物車裡不是裝了一個nginx嘛!既然做網站,可得試試我們家的.NET Framework哦,各種裝備,應有盡有。”,C#熱情的拉着我過去。

不過我還是拒絕了他:“實在不好意思,聽說你們家產品只能在Windows系統上面運行,不支持Linux,還是算了,我再看看別家”

C#攤主不肯放棄,“別呀,我們已經支持Linux了,您再看看,現在搞活動,免費送IIS服務器哦,你把那nginx退了吧,喂,再考慮一下啊·····”

不等他說完,我就溜走了,來到了Python的攤前。

Python攤主也看出了我要做網站,也推銷起他家的產品來。

“大哥,你做網站,肯定不想只做一個靜態的吧,來試試咱們家的Web框架做一個動態網站?咱Python家的產品,簡單、輕量又實惠。”,攤主熱情的說到。

“有哪些推薦的呢?”,我問到。

Python攤主指着攤位上的幾個產品說道:“有DjangoFlaskTornado這三款是現在主打拳頭產品,用了的都說好”

我正想蹲下仔細看看,背後傳來一個聲音:“這位大哥,擱這選Web開發框架吶?快來我這邊看看”

一邊說,一邊硬把我往後面拽。

來到他的攤位上,我一看原來是PHP攤主。

“咱PHP產品琳琅滿目,就是專門為做網站而生的,現在做活動,跳樓價只要9.9,錯過不再有!”

這PHP攤主好生能說,一頓猛誇把我說的暈頭轉向,不知怎的竟然就加入了購物車。

繼續向前,來到了Java的攤位,一個好大的攤位,擺放的東西也是看的人眼花繚亂。

“你這個攤位不錯啊,又寬敞人流又多”

“可不是咋的,剛為了搶這個攤位,跟PHP那傢伙還幹了一架呢。”,Java攤主笑着說到。

看到我購物車裡的東西,Java攤主也開始推銷起來:“大哥,這年頭怎麼還用PHP那傢伙的東西,趕緊去退了吧,咱Java攤里的東西都是大品牌,質量有保障!”

“這,不太好吧,這PHP也是大品牌啊”

Java攤主搖了搖頭,“他一個腳本語言怎麼跟我們比啊?大哥你看,我們有Spring、SpringMVC、SpringBoot、SpringCloud等等明星產品,用戶眾多,售後工作也到位。而且現在搞活動可以送tomcat服務器,你要是用戶量不多都可以把nginx退掉,省一筆錢。”

“看起來很厲害的樣子呢,我考慮一下”,我打算再去別的地方看看比較一下。

Java攤主一把拉住了我,“大哥,不說了,咱今天碰到是緣分,你做網站有很多服務是吧,得用到RPC吧,你今天下單,我再送你一套netty框架,又能幫你省一筆了”

Java攤主盛情難卻,我一時興起,買下了好幾個,購物車都裝滿了一大半了。

挑選數據庫

剛付完錢準備離開,背後又傳來一個聲音:“大哥,做網站你得用數據庫吧,快來這看看”

我尋聲望去,原來是 C++ 攤主在叫我。

“來看看我的MySQL數據庫,做網站必備!”

我看了一下產品說明書,感覺還不錯,看了下錢包,剛才在Java攤主那裡花費不少,有些囊中羞澀了,問到:“能不能優惠一點”

C++攤主一聽,臉上的笑容少了一半,“如果你選個MongoDB組個套餐,可以給你8折優惠”

“MongoDB?我要這個幹嘛”

攤主一聽來了勁頭,開始滔滔不絕:“有些數據啊他不適合存在數據庫里,比如文檔啊,JSON啊,這些東西你要用數據庫存儲,增加字段和查詢,可麻煩了,你用MongoDB就方便都多了······”

被他說了一通,感覺是得要個這個玩意兒。

攤主見我有些心動,又繼續推銷:“大哥看來真是行家,您做網站是不是有圖片音頻視頻需要存儲,我這裏還有一個對象存儲(OSS)系統CEPH,你看看要不要也一併帶上,我還是給您八折,怎麼樣?”

“實在不好意思,我這預算有些吃緊了,這個就算了吧”,我婉拒到。

“哎哎大哥您往這瞧,咱家也有對象存儲minio,現在市場推廣期,免費送了!”,旁邊的Golang攤主招呼了起來。

居然有免費這好事,我倒是想去看看。

C++攤主見狀小聲說到:“免費的你敢用,出了問題都找不到人,還是看看我的吧,直接給你六折,怎麼樣?”

我一想也是,正想下單買下,背後傳來一聲“且慢”!

我回頭一看,原來是剛才的Java攤主,“大哥,咱Java家的ElasticSearch也考慮一下唄。”

我回到Java攤主這邊,問到:“這又是個什麼?我需要用到嗎?”

Java攤主也開始給我掰扯起來:“咱家的ElasticSearch那可是搜索行家,你網站內容多了是不是需要個搜索功能啊,咱家的這個ES,全文搜索不在話下,秒級響應,做網站必備啊。看你是回頭客,給你九折!”

我正想做一個搜索功能,看來這個也是必不可少,也一起拿下了。

緩存服務器

我推着購物車準備回家了,今天真是滿載而歸。

來到集市出口,又碰到了一開始的C語言攤主,攤主一瞧揮着手喊道:“大哥,你還差個內存緩存系統,過來看看,Redis搞活動呢!哎,別走啊,Memcached虧本處理了,過來看看啊”

我一摸錢包,完蛋,嚴重超支了!我加快了步伐,匆忙離開······

彩蛋

看着我採購回來的一堆東西,老闆是氣不打一處來。

“咱們就做一個內網論壇,全公司不過100號人,你給我搞這麼多,幾個意思?”

“老闆,您聽我解釋···”

“解釋個啥,明天不用來了”

哦豁,丟了飯碗,我也去擺地攤了···

往期熱門回顧

因為一個跨域請求,我差點丟了飯碗

一個神秘URL釀大禍,差點讓我背鍋!

就為了一個原子操作,其他CPU核心都罷工了

完了!CPU一味求快出事兒了!

可怕!CPU竟成了黑客的幫凶!

哈希表哪家強?幾大編程語言吵起來了!

震撼!全網第一張源碼分析全景圖揭秘Nginx

一網打盡!每個程序猿都該了解的黑客技術大匯總

DDoS攻擊:無限戰爭

一個Java對象的回憶錄:垃圾回收

誰動了你的HTTPS流量?

路由器里的廣告秘密

一個HTTP數據包的奇幻之旅

我是一個流氓軟件線程

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

網頁設計最專業,超強功能平台可客製化

分類
發燒車訊

PBFT共識算法

拜占庭將軍問題

我們已知的共識算法,Paxos、Raft解決的都是非拜占庭問題,也就是可以容忍節點故障,消息丟失、延時、亂序等,但節點不能有惡意節點。但如何在有惡意節點存在的情況下達成共識呢?BFT共識算法就是解決這一問題的。即不但能容忍節點故障,還能容忍一定的惡意節點或者說拜占庭節點的存在。我們下面就學習一下BFT算法中的PBFT(Practical Byzantine Fault Tolerance)。BFT算法有非常多的變種,這裏只學習PBFT,其他的可以舉一反三。

PBFT

PBFT核心由3個協議組成:一致性協議、檢查點協議、視圖更換協議。系統正常運行在一致性協議和檢查點協議下,只有當主節點出錯或者運行緩慢的情況下才會啟動視圖更換協議,以維持系統繼續響應客戶端的請求。下面詳解這3個子協議。在講一致性協議之前,我們屏蔽算法細節先看一下正常情況下大致是怎麼工作的,大致流程如下:

  1. 客戶端發送請求給主節點(如果請求發送給了從節點,從節點會將該請求轉發給主節點或者將主節點的信息告知客戶端,讓客戶端發送給主節點)。
  2. 主節點將請求廣播給從節點。
  3. 主從節點經過2輪投票后執行客戶端的請求並響應客戶端。(協議細節見下面的一致性協議)
  4. 客戶端收集到來着\(f+1\)個不同節點的相同的響應后,確認請求執行成功。(因為最多有\(f\)個惡意節點,\(f+1\)個相同即能保證正確性)。

一致性協議

一致性協議的目標是使來自客戶端的請求在每個服務器上都按照一個確定的順序執行。 在協議中,一般有一個服務器被稱作主節點,負責將客戶端的請求排序;其餘的服務器稱作從節點,按照主節點提供的順序執行請求。所有的服務器都在相同的配置信息下工作,這個配置信息稱作視圖view,每更換一次主節點,視圖view就會隨之變化。協議主要分pre-preparepreparecommit三階段,如下圖所示:

REQUEST:

首先是客戶端發起請求, 請求<REQUEST,o,t,c>中時間戳t主要用來保證exactly-once語義,也就是說對同一客戶端請求不能有執行2次的情況,具體實現時也不一定非是時間戳,也可以是邏輯時鐘或者其他,只要能唯一標識這個請求就可以了。

PRE-PREPARE:

【1】 收到客戶端的請求消息后,先判斷當前正在處理的消息數量是否超出限制,如果超出限制,則先緩存起來,後面再打包一起處理。否則的話(當然,沒超過也可以緩存處理),對請求分配序列號n,並附加視圖號v等信息生成PRE-PREPARE消息<<PRE-PREPARE,v,n,d>,m>,廣播給其他節點。簡而言之就是對請求分配序號並告知所有節點。

【2】 收到PRE-PREPARE的消息後進行如下處理:

  • 消息合法性檢查,消息簽名是否正確,消息摘要是否正確。
  • 視圖檢查,檢查是否是同一個視圖號v
  • 水線檢查,判斷n是否在hH之間。(h一般是系統穩定檢查點,H是上限,會隨着h的不斷提高而提高)

如果都通過的話,就廣播PREPARE消息<PREPARE,v,n,d,i>給其他節點,表示自己收到並認可[n,v]這個請求,進入prepare階段。如果沒有通過,則忽略該消息。

這裏想一個問題,從節點能不能收到PRE-PREPARE消息就執行請求呢?答案顯然是不能的,因為不能確認本節點與其他節點收到的是相同的請求消息,此時不能確定主節點是不是正常節點,如果主節點是惡意節點呢?比如,發送給從節點1的消息是m,而發送給從節點2的消息是m',如果直接執行就會出現從節點的不一致。因為不能確認本節點與其他節點收到的是相同的請求消息,所以要通過從節點與從節點交互的方式互相告知收到了請求消息,好讓後面階段對比一下,是否一致。

PREPARE:
收到PREPARE消息<PREPARE,v,n,d,i>后,進行如下處理:

  • 消息合法性檢查,消息簽名是否正確,消息摘要是否正確。
  • 視圖檢查,檢查是否是同一個視圖號v
  • 水線檢查,判斷n是否在hH之間。

如果上面都通過,就將PREPARE消息加入到日誌中,並繼續收集PREPARE消息,如果收到正確的\(2f\)張(包括自己)PREPARE消息,這裏如何驗證是否正確呢?主要是收到的PREPARE要與PRE-PREPARE中的vnd等信息要匹配,就進入COMMIT階段,廣播COMMIT消息<COMMIT,v,n,D(m),i>

這一階段一般也可以稱為第一輪投票,目的是什麼呢?論文中是這麼說的:The pre-prepare and prepare phases of the algorithm guarantee that non-faulty replicas agree on a total order for the requests within a view. 濃縮為兩個字就是定序,確定在同一視圖下足額的正常的節點都對來自客戶端的請求有相同的定序。再說的直白點,就是解決上面提到的,無法確認本節點與其他節點收到的消息是否一致的問題。通過檢查相同視圖號v及同一序號n下的消息摘要d是否一致來判斷同一視圖配置下的同一個序號請求的消息是否一致。同時也確保了有足夠數量的節點收到了一致的消息請求。

可以再想一個問題,此時可以直接執行請求嗎?答案是不可以,因為此時,你只能確認自己收到了\(2f\)個一致的PREPARE消息,你無法確認其他節點是否也收到了\(2f\)個一致的PREPARE消息。也就是說,當前,你只能確認自己準備好了去執行序號為n的請求,但是你不能確認其他節點有沒有準備好,所以,還要再進行一次節點間的消息交互,互相告訴大家,我準備好了。

COMMIT:

在上一階段,節點收到足額PREPARE投票後會廣播COMMIT投票,過程類似,當節點收到其他節點的COMMIT投票消息后,會進行如下檢查:

  • 消息合法性檢查,檢查消息簽名是否正確,消息摘要正不正確有沒有被篡改。
  • 視圖檢查,view是否匹配。
  • 水線檢查,判斷n是否在hH之間。

如果都通過則把收到的投票消息寫入日誌log中,如果收到的合法的COMMIT投票消息大於等於\(2f+1\)個(包括自己),意思就是,已經確認大多數節點都準備好了執行請求,就執行請求並回復REPLY消息給客戶端。這裏如同上面一樣,也是檢查視圖,序號及消息是否匹配。

REPLY:

客戶端收到REPLY后,會進行統計,如果收到\(f+1\)個相同時間戳t和響應值r,則認為請求響應成功。如果在規定的時間內沒有收到回應或者沒有收到足額回應怎麼辦?可以將該請求廣播給所有節點,節點收到請求后,如果該請求已經被狀態機執行了,則再次回復客戶端REPLY消息,如果沒有被狀態機執行,如果節點不是主節點,就將該請求轉發給主節點。如果主節點沒有正常的將該請求廣播給其他節點,則將會被懷疑是主節點故障或惡意節點,當有足夠的節點都懷疑時將會觸發視圖變更協議,更換視圖。

我們進行進一步的分析,可以看到,如果是客戶端沒有收到任何回應,很有可能是主節點故障或主節點是惡意節點(我就故意不執行你的請求),沒有將請求足額廣播給其他節點,(當然還有消息丟失等原因,這裏不在詳細分析),這時,客戶端因一直沒有響應,所以將請求廣播給了所有節點,所有節點收到請求后,轉發給主節點后發現主節點怎麼什麼都不幹呀,懷疑主節點有問題,然後觸發視圖更換協議,換掉主節點。當然,客戶端沒有收到足額回應的一個原因還可能是消息丟失,那麼如果是已經執行了該請求的節點再次收到該請求後會再次回應REPLY,前提是該請求是在水線範圍內的合法請求,否則被拒絕。

檢查點協議

在上面的一致性協議中可以看到,系統每執行一個請求,服務器都需要記錄日誌(包括,request、pre-prepare、prepare、commit等消息)。如果日誌得不到及時的清理,就會導致系統資源被大量的日誌所佔用,影響系統性能及可用性。另一方面,由於拜占庭節點的存在,一致性協議並不能保證每一台服務器都執行了相同的請求,所以,不同服務器狀態可能不一致。例如,某些服務器可能由於網絡延時導致從某個序號開始之後的請求都沒有執行。因此,設置周期性的檢查點協議,將系統中的服務器同步到某一個相同的狀態。簡言之,主要作用有2個:1、同步服務器的狀態;2、定期清理日誌。

同步服務器的狀態,比較容易理解與做到。比如在區塊鏈系統中,同步服務器的狀態,實際上就是追塊,即服務器節點會通過鏈定時廣播的鏈世界狀態或其他消息獲知到自己區塊落後了,然後啟動追塊流程。

定期清理日誌,怎麼做呢?首先要明確哪些日誌可以被清理,哪些日誌仍然需要保留。如果一個請求已經被\(f+1\)台非拜占庭節點執行,並且某一服務器節點i可以向其他服務器節點證明這一點,那麼該i節點就可以將關於這個請求的日誌刪除。協議一般採用的方式是服務器節點每執行一定數量的請求就將自己的狀態發送給所有服務器並且執行一個該協議,如果某台服務器節點收到\(2f+1\)台服務器節點的狀態,那麼其中一致的部分就是至少有\(f+1\)台非拜占庭服務器節點經歷過的狀態,因此,這部分的日誌就可以刪除,同時更新為較新狀態。

具體實現時可以聯想到上面的一致性協議總的水線檢查。上面的低水線h值等同於穩定檢查點,穩定檢查點之前的日誌都可被清理掉。高水線H=h+k,也就是接收請求序號上限值,因為穩定檢查點往往是間隔很多的序號才觸發一次,所以k一般要設置的足夠大。例如,每間隔100個請求就觸發一次檢查點協議,提升水線,k可以設置為200。

這裏解釋一下穩定檢查點的概念,可以理解為當\(2f+1\)個節點都達到了某個請求序號,該請求序號就是穩定檢查點。所有穩定檢查點之前的消息都可以被丟棄,減少資源佔用。 對比Raft,Raft是通過快照的方式壓縮日誌,都需要一個清理日誌的機制,不然日誌無限增長下去會造成系統不可用

視圖更換協議

在一致性協議里,已經知道主節點在整個系統中擁有序號分配,請求轉發等核心能力,支配着這個系統的運行行為。然而一旦主節點自身發生錯誤,就可能導致從節點接收到具有相同序號的不同請求,或者同一個請求被分配多個序號等問題,這將直接導致請求不能被正確執行。視圖更換協議的作用就是在主節點不能繼續履行職責時,將其用一個從節點替換掉,並且保證已經被非拜占庭服務器執行的請求不會被篡改。即,核心有2點:1,主節點故障時,可能造成系統不可用,要更換主節點;2,當主節點是惡意節點時,要更換為誠實節點,不能讓作惡節點作為主節點。

當檢測到主節點故障或為惡意節點觸發視圖更換時,下一任主節點應該選誰呢?PBFT的辦法是採用“輪流上崗”的方式,通過\((v+1) \ mod \ N\),其中\(v\)為當前視圖號,\(N\)為節點總數,通過這一方式確定下一個視圖的主節點。還有個更關鍵的問題,什麼時候觸發視圖更換協議呢?我們繼續往下討論。

如果是主節點故障的情況,這種情況一般較好處理。具體實現時,一般從節點都會維護一個定時器,如果長時間沒有收到來自主節點的消息,就會認為主節點發生故障。此時可觸發視圖更換協議,當然具體實現時,細節可能會不同,比如,也可以是這種情況,客戶端發送請求給故障主節點必然導致長時間收不到響應,所以,客戶端將請求發送給了系統中所有從節點,從節點將請求轉發給主節點並啟動定時器,如果主節點長時間沒有將該請求分配序號發送PRE-PREPARE消息,認為主節點故障,觸發視圖更換協議。這2種情況比較好理解,但就這2種情況嗎?其實還有以下幾種情況也會觸發視圖更換協議:

  • 從節點廣播PREPARE消息后,在約定的時間內未收到來自其他節點的\(2f\)個一致合法消息。
  • 從節點廣播COMMIT消息后,在約定的時間內未收到來自其他節點的\(2f\)個一致合法消息。
  • 從節點收到異常消息,比如視圖、序號一致,但消息不一致。
    這三點,都有可能是主節點作惡導致的,但也有可能是消息丟失等原因導致的。雖然不一定是因為主節點異常導致的,但從另一個角度看,解決了從節點不能無限等待其他節點投票消息的問題。

這裏補充一點,觸發視圖更換協議后,將不再接收除檢查點消息、VIEW-CHANGE消息、NEW-VIEW消息之外的消息。也就是視圖更換期間,不再接收客戶端請求,暫停服務。

解決了什麼時候觸發的問題后,下一個問題就是具體怎麼實現呢?當因上面的情況觸發視圖更換協議時,從節點i就會廣播一個VIEW-CHANGE消息<VIEW-CHANGE,v+1,n,C,P,i>,序號n是節點i的最新穩定檢查點sC\(2f+1\)個有效檢查點消息,是為了證明穩定檢查點s的正確性,P是位於序號n之後的一系列消息的結合,這裏要包含這些信息可以理解為是證據,也就是說,從節點不能隨便就發送一個VIEW-CHANGE,什麼證據都沒有,別人怎麼能認同你更換視圖呢?。上面我們提到過下一任主節點是誰的問題?通過\((v+1) \ mod \ N\)確定的一下任主節點p(在圖中就是節點1),在收到\(2f\)個有效的VIEW-CHANGE消息后,就廣播<NEW-VIEW,v+1,V,O>消息,這裏VO具體的生成方法參考原論文,主要是VIEW-CHANGEPRE-PREPARE等消息構成的集合,主要目的是為了讓從節點去驗證當前新的主節點的合法性以及解決下面這個問題,還有要處理未確認消息和投票消息。

視圖更換協議需要解決的問題是如何保證已經被非拜占庭服務器執行的請求不被更改。由於系統達成一致性之後至少有\(f+1\)台非拜占庭服務器節點執行了請求,所以目前採用的方法是:由新的主節點收集至少\(2f+1\)台服務器節點的狀態信息(也就是上面在構造消息時所需的各種消息集合),這些狀態信息中一定包含所有執行過的請求;然後,新主節點將這些狀態信息發送給所有的服務器,服務器按照相同的原則將在上一個主節點完成的請求同步一遍,同步之後,所有的節點都處於相同的狀態,這時就可以開始執行新的請求。

若干細節問題的思考

在3階段協議中,對收到的消息都要進行消息合法性檢查、視圖檢查、水線檢查這3項檢查,為什麼呢?

這3項檢查是十分有必要的,添加消息簽名是為了驗證投票是否合法,正確統計合法票數,不能是隨便一個不知道的節點都能投票,那我怎麼驗證到底是誰投的呀。也就是說,要通過消息簽名的方式確認消息來源,通過消息摘要的方式,確認消息沒有被篡改。當然,考慮到性能因素,也可以使用消息認證碼(MAC),以節省大量加解密的性能開銷。PBFT算法,可以容忍節點作惡,消息丟失、延時、亂序,但消息不能被篡改。

視圖檢查比較容易理解,所有節點必須在同一個配置下才能正常工作。如果節點的視圖配置不一致,比如主節點不一致、節點數量不一致,那統計合法票數的時候,真沒法幹了。

水線檢查,是檢查點協議的一部分,在工程實現時,不是所有的請求我都有處理,比如,你收到一個歷史投票信息,你還有必要處理嗎?當然,它的作用不止於此,還可以防止惡意節點選擇一個非常大的序列號而耗盡序列號空間,例如,當一個節點分配了超過H上限的序列號,這時,正常節點會拒絕這個請求從而阻止了惡意節點分配的遠超過H的序列號。

3階段協議中每一階段的意義是什麼?

論文中有如下錶述:

The three phases are pre-prepare, prepare, and commit.The pre-prepare and prepare phases are used to totally order requests sent in the same view even when the primary, which proposes the ordering of requests, is faulty. The prepare and commit phases are used to ensure that requests that commit are totally ordered across views.

即,pre-prepareprepare階段,主要的作用就是定序,個人理解就是要確認有足夠數量的節點收到同一請求,並且與自己所收到的請求相一致。prepare以及commit階段是確認大家執行的同一請求。

為什麼是\(3f+1\)

我們知道PBFT的容錯能力為不超過三分之一,即\(n=3f+1\)\(f\)為拜占庭節點數量。但這個公式是怎麼來的呢?論文中有這麼一段論述可以幫助我們去理解:

The resiliency of our algorithm is optimal: \(3f+1\) is the minimum number of replicas that allow an asynchronous system to provide the safety and liveness properties when up to \(f\) replicas are faulty. This many replicas are needed because it must be possible to proceed after communicating with \(n-f\) replicas, since \(f\) replicas might be faulty and not responding. However, it is possible that the \(f\) replicas that did not respond are not faulty and, therefore, \(f\) of those that responded might be faulty. Even so, there must still be enough responses that those from non-faulty replicas outnumber those from faulty ones, i.e., \(n-2f>f\). Therefore \(n>3f\).

意思就是,在一個容忍\(f\)個錯誤節點的系統中,系統至少要\(3f+1\)個節點才能保證系統安全可靠。為什麼呢?因為在所有\(n\)個節點中,有\(f\)個節點可能因故障而沒有回應(或者投票),而在回應的\(n-f\)中又有可能有\(f\)個是惡意節點的回應,即使如此,也要保證正常節點的投票要多於惡意節點的投票數量,即\(n-f-f>f\),推出\(n>3f\)

PBFT對比Raft

PBFT對比Raft,最大的不同在於解決的問題不一樣,雖然都是共識算法,但一個解決的拜占庭問題,另一個則解決的非拜占庭問題。從算法細節上來看,Raft中的領導者是強領導者,即,一切領導者說了算,但PBFT中對應的主節點卻不是,因為不能保證主節點不是拜占庭節點,萬一主節點作惡,從節點要有發現主節點是惡意節點的能力,並及時觸發視圖更換協議更換主節點。從算法消耗的資源來看,明顯PBFT要更複雜,投票數明顯多於Raft,不但要主從節點交互,還有從節點與從節點互相交互,所以,其性能也一定比Raft低,這是肯定的,因為PBFT解決的問題比Raft更複雜,一定程度上可以認為Raft是PBFT的子集,如果你把PBFT三階段協議中從節點與從節點交互的那部分去掉,只保留主節點與從節點交互的那部分,你會發現,好像還蠻像的。從另一個方面說,Raft算法,因為沒有拜占庭節點的存在,領導者節點一定是對的,從節點一切聽領導的就是。但是在PBFT中,從節點就不能光聽主節點的,萬一主節點也是壞人咋辦?怎麼解決這個問題呢?顯然,只聽主節點肯定是不行的,我還要看看其他節點的意見,如果有足額的節點認為是對的,就同意。怎麼確定足額節點數到底是多少呢?上面有講到過。所以,相比Raft,PBFT多了從節點與從節點的消息交互。

PBFT的時間複雜度分析

PBFT有比較明顯的兩輪投票,所以時間複雜度\(O(n^2)\),節點數量較大時,一次共識協商所需的消息太多,這也決定了PBFT只能適用於節點數量不大的系統中,比如區塊鏈中的許可鏈,公鏈節點數量太多,並不適用PBFT算法。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計最專業,超強功能平台可客製化

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※教你寫出一流的銷售文案?

分類
發燒車訊

伊朗火災與爆炸頻傳 伊斯法罕省電廠也傳事故

摘錄自2020年7月19日中央社報導

伊朗中部伊斯法罕省一座電廠今天(19日)發生爆炸。所幸沒有人員傷亡。電廠過了約兩小時恢復正常運作,伊斯法罕省供電不受影響。

伊朗各地的軍事與民用設施近幾週頻傳火災與爆炸事故,讓伊朗境內人士懷疑可能是宿敵以色列在搞破壞。以色列指控伊朗試圖發展核彈,伊朗則堅稱本身的核子計畫完全是為了和平目的。

首都德黑蘭(Tehran)6月下旬就發生兩起爆炸,其中一起發生在軍事用地附近,另一起衛生中心的火災則奪走19人性命。本月稍早,伊朗南部一座造船廠、德黑蘭南方一座工廠,以及伊朗中部的納坦茲(Natanz)核設施,也分別發生火災或爆炸事故。其中工廠事故奪走兩人性命。伊朗當局形容納坦茲核設施起火是意外,他們基於「安全理由」不公布事發原因及細節。

土地利用
能源轉型
國際新聞
伊朗
火力發電廠
火災
災害
核能

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

分類
發燒車訊

荷研發植物製塑膠瓶 一年內可生物分解

摘錄自2020年7月21日公視報導

荷蘭一間生化公司開發出以植物原料製造的塑膠瓶,使用完不僅可以回收,它還能在一年內自行分解。

荷蘭生化公司技術總監古魯特表示:「而且因為從隔離膜的角度來看,PEF(生質聚酯塑膠)性能確實很好,因為紙瓶的優勢來自於紙質製造,只需要一層薄薄的PEF即可實現阻隔(液體)的性能,能好好將內容物妥善保存一段時間。」

這種植物塑膠,是由玉米、小麥,和甜菜根作成,可以用來盛裝包括氣泡型的飲料,能大幅減少塑膠污染,跟市場對化石燃料的依賴。經過將瓶子放入淡水、鹽水、泥土跟沉澱物的實驗證明,這種塑膠經過堆肥處理後,一年內就可以完全分解,就算放在戶外,也只要幾年時間就能分解。

生化公司認為這些瓶子,可以回收再利用,因此爭取到了美國可口可樂公司,和丹麥啤酒製造商「嘉士伯」的支持,持續開發。由於植物塑膠的製作成本,生化公司了解一開始無法在價格上占有市場優勢,因此預計先每年生產5000公噸,預計將在2023年前,會與飲料公司合作,讓產品上架。

污染治理
國際新聞
荷蘭
可生物分解
廢棄物

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

研究:提高空調能源效率、改用氣候友善製冷劑 將可省下數千億噸碳排

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

分類
發燒車訊

簡單5步,輕鬆debug K8S服務!

作者:
Ram Rai,性能、可擴展性以及軟件架構的愛好者

原文鏈接:
https://medium.com/better-programming/debug-your-kubernetes-service-in-5-easy-steps-1457974f024c

在Kubernetes中,服務是一個核心概念。在本文中,將介紹如何調試K8S服務,這些服務是由多個Pod組成的工作負載的抽象接口(主機+端口)。

在我們深入探索debug方法之前,我們先簡單回顧一下網絡,這是Kubernetes服務的基礎。

  • 在一個pod中的容器共享相同的網絡空間和IP。

  • 所有的pod都能通過IP彼此通信。

  • 每個節點都能看到所有的Pod,反之亦然。

  • Pod可以看到所有的服務。

那麼,在實踐中這些意味着什麼呢?

在圖中:

  • 位於Pod1中的容器B可以直接作為localhost尋址容器A

  • 容器B可以通過其IP直接尋址Pod2(kubectl get pod -o wide)。我們知道當pod2出現故障時着不是一個可靠的通信渠道,並且一個新的pod可以出現在其位置中。但是我們無法追逐不斷變化的目標。

  • 接下來,容器B可以通過Service x訪問pod 2和pod 3,後者將它們的IP與負載均衡捆綁在一起;因此,在K8S上支持基於微服務的應用程序起着至關重要的作用

儘管對Kubernetes的內部網絡結構的檢查不在本文的討論範圍內,但我稍後會發布一些參考資料以供大家進一步研究。

對於當下,我還是鼓勵你花費一點時間在實踐中經歷和理解Kubernetes中的網絡。例如,你可以啟動一個Kubernetes測試pod並且嘗試從該pod中訪問其他pod、節點和服務。此處显示的命令將在Pod內彈出一個Linux shell。

kubectl run -it networktest --image=alpine bin/ash --restart=Never --rm

現在你在Kubernetes網絡空間內並且你可以隨意使用wegtpingnslookup之類的命令進行實驗。例如,測試你的Kubernetes集群中先前列出的網絡要求,nslookup <servicename>, ping <PodIP>

現在讓我們回到我們的話題,troubleshooting Kubernetes服務,這實際上是一種網絡結構。

Step1:檢查服務是否存在

kubectl get svc

如果服務不存在,應該是服務創建出現了故障,因此要去檢查你的服務定義。

Step2:測試你的服務

請記住,一個內部的Kubernetes ClusterIP服務是無法在集群外部訪問的。因此,有兩種方法可以對其進行測試。方法一,你可以啟動一個測試Pod,通過SSH進入該pod,然後嘗試像這樣訪問你的服務:

kubectl run -it testpod --image=alpine bin/ash --restart=Never --rm

在本文中我們啟動一個alpine Docker鏡像作為pod來從其內部測試服務:

#works for http services
wget <servicename>:<httpport>

#Confirm there is a DNS entry for the service!
nslookup <servicename>

或者,你可以轉發到本地計算機並在本地進行測試。

kubectl port-forward <service_name> 8000:8080

現在,你可以通過localhost:8000訪問服務。

Step3:檢查服務是否target相關Pod

Kubernetes服務會根據標籤selector將入站流量路由到其中一個pod,流量通過其IP路由到目標Pod。所以,請檢查服務是否綁定到那些pod。

kubectl describe service <service-name> | grep Endpoints

執行上述命令之後,你應該看到與列出的工作負載相關的所有Pod的IP。如果沒有看到,請執行Step4。

Step4:檢查Pod標籤

確保在Kubernetes服務中的selector與pod的標籤相匹配。

kubectl get pods --show-labels
kubectl describe svc <service_name>

從下面的截圖的中可以看到,pod的標籤在右邊。四個pod被標記為app=tinywebsitetier=frontend,這些標籤與下面“described”的服務selector相匹配。

在這四個匹配的Pod中,只有三個正在運行,其IP在突出显示的行中被列為服務的端點(endpoint)。你還可以在IP列中看到相同的IP。

Step5:確認服務端口與pod相匹配

最後,確保在你的pod中的代碼能夠監聽到你為服務指定的targetPort(例如,你在上方截圖中看到的port8001)!

這十分簡單,為了讓你更進一步深入了解和研究Kubernetes的網絡世界,歡迎你閱讀以下文章。

  • 在Kubernetes中部署一個應用程序

  • Debug服務

  • Kubernetes網絡

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

分類
發燒車訊

分佈式鎖的一些理解

 在多線程併發的情況下,單個節點內的線程安全可以通過synchronized關鍵字和Lock接口來保證。

synchronized和lock的區別

  1. Lock是一個接口,是基於在語言層面實現的鎖,而synchronized是Java中的關鍵字,是基於JVM實現的內置鎖,Java中的每一個對象都可以使用synchronized添加鎖。

  2. synchronized在發生異常時,會自動釋放線程佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;

  3. Lock可以讓等待鎖的線程響應中斷,而synchronized卻不行,使用synchronized時,等待的線程會一直等待下去,不能夠響應中斷;

  4. Lock可以提高多個線程進行讀操作的效率。(可以通過readwritelock實現讀寫分離,一個用來獲取讀鎖,一個用來獲取寫鎖。)

  當開發的應用程序處於一個分佈式的集群環境中,涉及到多節點,多進程共同完成時,如何保證線程的執行順序是正確的。比如在高併發的情況下,很多企業都會使用Nginx反向代理服務器實現負載均衡的目的,這個時候很多請求會被分配到不同的Server上,一旦這些請求涉及到對統一資源進行修改操作時,就會出現問題,這個時候在分佈式系統中就需要一個全局鎖實現多個線程(不同進程中的線程)之間的同步。

  常見的處理辦法有三種:數據庫、緩存、分佈式協調系統。數據庫和緩存是比較常用的,但是分佈式協調系統是不常用的。

  常用的分佈式鎖的實現包含:

      Redis分佈式鎖Zookeeper分佈式鎖Memcached

基於 Redis 做分佈式鎖

 Redis提供的三種方法:

(1)鎖 SETNX:只在鍵 key 不存在的情況下, 將鍵 key 的值設置為 value 。若鍵 key 已經存在, 則 SETNX 命令不做任何動作。SETNX 是『SET if Not eXists』(如果不存在,則 SET)的簡寫。命令在設置成功時返回 1 , 設置失敗時返回 0

redis> SETNX job "programmer"    # job 設置成功
(integer) 1

redis> SETNX job "code-farmer"   # 嘗試覆蓋 job ,失敗

(2)解鎖 DEL:刪除給定的一個或多個 key

(3)鎖超時 EXPIRE: 為給定 key 設置生存時間,當 key 過期時(生存時間為 0 ),它會被自動刪除。

  每次當一個節點想要去操作臨界資源的時候,我們可以通過redis來的鍵值對來標記一把鎖,每一進程首先通過Redis訪問同一個key,對於每一個進程來說,如果該key不存在,則該線程可以獲取鎖,將該鍵值對寫入redis,如果存在,則說明鎖已經被其他進程所佔用。具體邏輯的偽代碼如下:

try{
	if(SETNX(key, 1) == 1){
		//do something ......
	}finally{
	DEL(key);
}

  但是此時,又會出現問題,因為SETNX和DEL操作並不是原子操作,如果程序在執行完SETNX后,而並沒有執行EXPIRE就已經宕機了,這樣一來,原先的問題依然存在,整個系統都將被阻塞。

  幸虧Redis又提供了SET key value timeout NX方法,可以以原子操作的方式完成SETNX和EXPIRE的操作。此時只需如下操作即可。

try{
	if(SET(key, 1, 30, timeout, NX) == 1){
		//do something ......
	}
}finally{
	DEL(key);
}

  解決了原子操作,仍然還有一點需要注意,例如,A節點的進程獲取到鎖的時候,A進程可能執行的很慢,在do something未完成的情況下,30秒的時間片已經使用完,此時會將該key給深處掉,此時B進程發現這個key不存在,則去訪問,並成功的獲取到鎖,開始執行do something,此時A線程恰好執行到DEL(key),會將B的key刪除掉,此時相當於B線程在訪問沒有加鎖的臨界資源,而其餘進程都有機會同時去操作這個臨界資源,會造成一些錯誤的結果。對於該問題的解決辦法是進程在刪除key之前可以做一個判斷,驗證當前的鎖是不是本進程加的鎖。

String threadId = Thread.currentThread().getId()
try{
	if(SET(key, threadId, 30, timeout, NX) == 1){
		//do something ......
	}
}finally{
    if(threadId.equals(redisClient.get(key))){
        DEL(key);
    }
}

   上面的改進雖然解決鎖被不同的進程釋放的危險,但並沒有解決獲取到鎖的進程在指定的時間內未完成do something操作(上面的代碼還有一點小問題,就是判斷操作和釋放鎖是兩個獨立的操作,不具備原子性。假設線程A判斷完確實是自己加的鎖 , 這時還沒del ,這時有效的時間用完了 , 緊接着線程B又馬上搶到了鎖 , 然後線程A才執行del命令 , 就會把B搶到的鎖給誤刪了),使得卡住的進程有可能與後來的進程同時同問臨界資源,而出現問題,因此一旦某個進程無法在超時時間內完成對臨界資源的操作,就需要延長超時的時間。此時可以啟動一個守護進程,監視指定時間內獲取鎖的進程是否完成操作,如果沒有,則添加超時時間,讓程序繼續執行。

String threadId = Thread.currentThread().getId()
try{
	if(SET(key, threadId, 30, timeout, NX) == 1){
		new Thread(){
            @Override
            public void run() {
            	//start Daemon
            }
         }
		//do something ......
	}
}finally{
    if(threadId.equals(redisClient.get(key))){
        DEL(key);
    }
}

  基於以上的分析,基本上可以通過Redis實現一個分佈式鎖,如果我們想提升該分佈式的性能,我們可以對連接資源進行分段處理,將請求均勻的分佈到這些臨界資源段中,比如一個買票系統,我們可以將100張票分為10 部分,每部分包含10張票放在其他的服務節點上,這些請求可以通過Nginx被均勻的分散到這些處理節點上,可以加快對臨界資源的處理。

參考資料

  1. 併發編程的鎖機制:synchronized和lock

  2. B站視頻上一部分講解

  3. 什麼是分佈式鎖?

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

分類
發燒車訊

東南亞最大湖泊洞里薩湖延遲回流 柬埔寨歸咎上游中、寮大壩

摘錄自2020年7月22日ETtoday新聞雲報導

位於柬埔寨的洞里薩湖(Tonle Sap)是東南亞最大的湖泊,無論旱、雨季都出產大量魚蝦,周圍地帶有約300萬人以漁業相關產業維生。

洞里薩湖的水源—湄公河—通常會於雨季水位上漲,並回流至柬埔寨的洞里薩湖,提供豐富的魚類資源。但專家稱,近來連續2年湄公河都延遲回流,嚴重干擾了捕魚活動,影響上百萬人的糧食供應。

據《路透社》報導,湄公河委員會認為延遲回流現象歸因於2019年降雨減少,以及湄公河上游2座寮國和11座中國水壩的運行,破壞了湄公河的自然水流,回流預計延遲到下個月(8月)才可能發生,導致漁民生計大受影響。

生物多樣性
國際新聞
柬埔寨
洞里薩湖
水源供應
湄公河
大壩
截流
水文

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準