資料結構和演算法之美 22 雜湊演算法

2021-10-10 21:13:22 字數 2076 閱讀 6204

實現乙個會話粘滯(session sticky)的負載均衡的演算法即在同乙個客戶端上一次會話的所有請求都能路由到同乙個伺服器上。

最簡單的辦法就是維護一張對映表,對映表中記錄會話id或者客戶端ip與伺服器編號的對映關係。客戶端每次發出的請求都先到對映表中查詢伺服器對應的編號,再請求編號對應的伺服器。這種方法雖然簡單直觀,但是存在幾個弊端:

1、如果客戶端很多,則對映表過大,比較浪費記憶體空間

2、客戶端上線、下線,服務端擴容、縮容都會導致對映表失效,這樣增加了維護的成本;

我們可以通過雜湊演算法,對客戶端 ip 位址或者會話 id 計算雜湊值,將取得的雜湊值與伺服器列表的大小進行取模運算,最終得到的值就是應該被路由到的伺服器編號。 這樣,我們就可以把同乙個 ip 過來的所有請求,都路由到同乙個後端伺服器上。

應用場景2: 如何快速判斷是否在相簿中?如何快速判斷是否在相簿中?上一節我們講過這個例子,不知道你還記得嗎?當時我介紹了一種方法,即給每個取唯一標識(或者資訊摘要),然後構建雜湊表。假設現在我們的相簿中有 1 億張,很顯然,在單台機器上構建雜湊表是行不通的。因為單台機器的記憶體有限,而 1 億張構建雜湊表顯然遠遠超過了單台機器的記憶體上限。我們同樣可以對資料進行分片,然後採用多機處理。我們準備 n 臺機器,讓每台機器只維護某一部分對應的雜湊表。我們每次從相簿中讀取乙個,計算唯一標識,然後與機器個數 n 求餘取模,得到的值就對應要分配的機器編號,然後將這個的唯一標識和路徑發往對應的機器構建雜湊表。當我們要判斷乙個是否在相簿中的時候,我們通過同樣的雜湊演算法,計算這個的唯一標識,然後與機器個數 n 求餘取模。假設得到的值是 k,那就去編號 k 的機器構建的雜湊表中查詢。現在,我們來估算一下,給這 1 億張構建雜湊表大約需要多少臺機器。雜湊表中每個資料單元包含兩個資訊,雜湊值和檔案的路徑。假設我們通過 md5 來計算雜湊值,那長度就是 128 位元,也就是 16 位元組。檔案路徑長度的上限是 256 位元組,我們可以假設平均長度是 128 位元組。如果我們用煉表法來解決衝突,那還需要儲存指標,指標只占用 8 位元組。所以,雜湊表中每個資料單元就占用 152 位元組(這裡只是估算,並不準確)。假設一台機器的記憶體大小為 2gb,雜湊表的裝載因子為 0.75,那一台機器可以給大約 1000 萬(2gb*0.75/152)張構建雜湊表。所以,如果要對 1 億張構建索引,需要大約十幾台機器。在工程中,這種估算還是很重要的,能讓我們事先對需要投入的資源、資金有個大概的了解,能更好地評估解決方案的可行性。實際上,針對這種海量資料的處理問題,我們都可以採用多機分布式處理。借助這種分片的思路,可以突破單機記憶體、cpu 等資源的限制。

現在網際網路面對的都是海量的資料、海量的使用者。我們為了提高資料的讀取、寫入能力,一般都採用分布式的方式來儲存資料,比如分布式快取。我們有海量的資料需要快取,所以乙個快取機器肯定是不夠的。於是,我們就需要將資料分布在多台機器上。該如何決定將哪個資料放到哪個機器上呢?我們可以借用前面資料分片的思想,即通過雜湊演算法對資料取雜湊值,然後對機器個數取模,這個最終值就是應該儲存的快取機器編號。

但是,如果資料增多,原來的 10 個機器已經無法承受了,我們就需要擴容了,比如擴到 11 個機器,這時候麻煩就來了。因為,這裡並不是簡單地加個機器就可以了。原來的資料是通過與 10 來取模的。比如 13 這個資料,儲存在編號為 3 這台機器上。但是新加了一台機器中,我們對資料按照 11 取模,原來 13 這個資料就被分配到 2 號這台機器上了。因此,所有的資料都要重新計算雜湊值,然後重新搬移到正確的機器上。這樣就相當於,快取中的資料一下子就都失效了。所有的資料請求都會穿透快取,直接去請求資料庫。這樣就可能發生雪崩效應,壓垮資料庫。

所以,我們需要一種方法,使得在新加入乙個機器後,並不需要做大量的資料搬移。這時候,***一致性雜湊演算法***就要登場了。假設我們有 k 個機器,資料的雜湊值的範圍是[0, max]。我們將整個範圍劃分成 m 個小區間(m 遠大於 k),每個機器負責 m/k 個小區間。當有新機器加入的時候,我們就將某幾個小區間的資料,從原來的機器中搬移到新的機器中。這樣,既不用全部重新雜湊、搬移資料,也保持了各個機器上資料數量的均衡。一致性雜湊演算法的基本思想就是這麼簡單。

除此之外,它還會借助乙個虛擬的環和虛擬結點,更加優美地實現出來。這裡我就不展開講了,如果感興趣,你可以看下這個介紹。除了我們上面講到的分布式快取,實際上,一致性雜湊演算法的應用非常廣泛,在很多分布式儲存系統中,都可以見到**一致性雜湊演算法**的影子。

資料結構與演算法之美(筆記9)雜湊演算法

我們前面講到雜湊表,雜湊函式,這裡又是雜湊演算法,實際上,雜湊函式就是雜湊演算法的乙個特例。只不過在雜湊表中,我們通常希望雜湊函式簡單,才不會影響查詢等的效能。雜湊演算法的定義和原理很簡單,就是把任意二進位制串值對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始的資料對映之後得到...

資料結構和演算法 雜湊演算法

前面我們學習了雜湊表,雜湊函式,和雜湊演算法啥關係?其實不管雜湊還是雜湊,都是翻譯的差別,對於英文都是hash,所以雜湊 雜湊 hash 雜湊演算法的定義 將任意長度的二進位制串對映為固定長度的二進位制串,這種對映規則就是雜湊演算法。通過原始資料對映成的規定固定長度的二級制串就是雜湊值乙個優秀的雜湊...

資料結構和演算法 雜湊演算法

一 定義 1 將任意長度的二進位制值串對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法。通過原始資料對映之後得到的二進位制值串就是雜湊值。二 hash演算法編寫要求 從雜湊值不能反向推導出原始資料 對輸入資料非常敏感,哪怕原始資料只修改了乙個bit,最後得到的hash值也會變化 雜湊衝突的...