nameserver(ns)是tfs的總控節,ns的主要職責包括為寫分配block、為讀查詢block、管理block與dataserver對應關係、管理dataserver、備ns狀態,執行後台複製、均衡、壓縮任務,以保證整個集群良好的工作。
block分配
ns接收到客戶端的寫請求,會分配乙個可寫的block,如果沒有可寫block,則會建立乙個新的block,每個block由乙個id標識(uint32_t,後續會將該值提公升至uint64_t),blockid不能重複,且不復用,新建立的block,在當前id的基礎上遞增,產生新的blockid。
為了保證產生不重複的blockid,必須將blockid當前的值進行持久化,ns在啟動時載入這個值,才能知道下乙個block id如何分配;唯一能保證完全不重複的方式是,每次blockid增加的時候,都進行持久化操作,但由於ns上的併發請求較多,並且ns上的其他元資料都是全記憶體化的,在每次建立block時都持久化blockid,對正常服務的影響較大。
目前採取的解決方法是,記錄blockid遞增的次數,當次數達到某個閾值(比如100)時,對blockid進行持久化。這樣做的問題時,下次再啟動,如果上次結束時最新的blockid還未持久化,則會出現重複的blockid,解決的方法是在啟動載入blockid後,直接往後跳100,這樣就能保證每次生成的blockid不重複,同時不會對ns的服務效能產生大的影響。
block與dataserver關係的管理
每個dataserver(ds)上可以擁有很多個block,每個block可以存在於多個ds(決定於配置的副本數),當新建立乙個block時,ns會選擇多個位置安全的ds,並在這些ds上建立block, block建立成功後,建立block到這多個ds的對應關係。
每個ds包含三個block列表
每個block包含乙個server列表
每次寫請求到達時,ns會從hold master列表中選擇乙個目標block,返回給客戶端用於寫,hold master列表中block個數會維持在乙個數值內,這樣做的好處是,每次先把一批block寫滿,再寫下一批,而不是把資料分配到所有的block上,減少了維護block的元資料。當hold master中的block個數不足時,會從writable中提公升一批到hold master,如果writable裡沒有可用的,則需新建立一批,以保證能隨時滿足寫請求服務。
ds及備ns管理
ns需要管理所有ds的狀態,同時ns為了主備容災,還需要維護備ns的狀態。
ds啟動後,會週期性的給主備ns(在配置檔案中指定)傳送心跳資訊,ns超過閾值時間(沒有收到ds的心跳就認為ds掛掉,將ds新增到dead server列表,當有新的ds心跳時,ns會先檢查新的ds在不在dead server列表中,如果在則從該列表中移除。dead server中的ds存在超過一段時間如240s,則認為這個server已經徹底死掉,這個server上的block的副本數需要增加,將這些block加入到複製任務中。google的研究表明,90%以上的機器故障在15min鐘內能恢復,故在故障時不必立即對block進行複製,可以等一段時間,具體等多久可根據系統的副本數確定。
ns在啟動時,會根據自己是否擁有vip來判斷自己的身份,備ns在啟動時,會主動向主ns傳送login資訊,ns為其分配乙個租約,隨後備ns會一直續約,只要備ns的租約有效,主ns會將一些操作同步個備ns,這些操作主要包括建立block、刪除block、block複製及遷移等。
主備ns間同步主要是考慮到,當主ns掛掉時,ns服務會通過ha切換到備ns,備ns只包含各個ds剛啟動時的block資訊,而隨著系統的執行,各個ds都相應發生了block建立、刪除、複製、遷移等操作,也就是說,備ns上的block資訊是過期的、不完整的。一種處理方式是在服務切到備ns時,讓所有的ds重新匯報一次block,但匯報block是個漫長的過程,在block匯報完前,備ns服務是不可用的。通過將主ns的block建立等操作同步到備ns,備ns的block資訊就基本接近主ns(可能有些操作未來得及同步),備ns接管後,能立即正常服務。
任務管理
nameserver還負責協調整個集群的工作,執行一些後台任務,以保證整個集群良好的工作,主要包括以下幾種型別。
複製任務:當有ds掛掉時,該ds上的block都會丟失,導致這些block的副本數下降,如果不及時增加副本,則再出現其他ds故障時,可能導致某些block永久丟失;複製任務及時發現這些副本數少於配置值的block,將其複製到合適的ds,保證資料的可靠性。當有ds宕機時,會觸發複製任務,複製任務在4個任務中優先順序最高,另外2個副本的block比丟失乙個副本的block優先順序更高,ds收到ns的任務請求時,應盡快處理優先順序高的任務。
均衡任務:當某些ds負載較高時,如磁碟空間使用率太高,或整體工作負載較高等,這時就需要將該ds上的部分block轉移到負載較輕的ds上。均衡任務將ds按照所有ds負載的平均值分成兩堆,對超過平均值一定範圍(可配置)的ds中選擇遷移源,從低於平均值一定範圍的的ds中選擇遷移目標。當建立均衡時,沒有限制每個ds上均衡任務數,這樣可能導致在一次建立過程中,很多ds的均衡任務並沒有被建立。另外在ds上選擇block時,應該盡量選擇儲存資料較多的block(最近出現空block被遷移的情況)。
壓縮任務:當某些block上檔案刪除很多時,block上就會出現很多空洞,但這些空間在沒有**前是不能被使用的,壓縮任務用於**這些block上已刪除檔案占用的空間。壓縮任務目前由ns發起,後期考慮把壓縮任務都移到ds上。
刪除任務:當某些block的副本數超出配置值時,需要刪除掉多餘的副本,以節省儲存空間。
nameserver在啟動時,會啟動任務建立執行緒和任務執行執行緒。前者週期性的檢查server、block的狀態,並依次建立上述4種任務,並將建立的任務新增到任務佇列中;後者則從任務佇列中取去任務,並將任務傳送到相應的ds並執行。
快速排序演算法實現(遞迴實現 棧實現)
基本思想 選擇乙個基準元素,比如選擇最後乙個元素,通過一趟掃瞄,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,又稱為軸位置,此位置的元素確定後不再參與排序,然後再用同樣的方法遞迴地排序劃分的兩部分。分析 快速排序是不穩定的排序。快速排序的時間複...
介面實現與配置實現
在實現系統功能的時候,通常會首先定義好功能的介面,在系統功能不斷被實現的過程中,慢慢的發現有些介面的實現很類似,這個時候通常會開始做一次抽象,形 成乙個共同的部分,慢慢的系統形成了乙個抽象的層次,而為了通用,通常是通過定義介面,形成乙個抽象類,抽象類中暴露出一些抽象方法供外部擴充套件實 現,逐步的積...
js分頁實現,前端實現。
主要是借鑑了網上乙個例子,自己重新加了樣式,新增了跳轉,修改了一些小地方,用於和大家一起分享,前端分頁的技巧,的資料是我已經寫好了,其實大家也可以前端渲染 然後再分頁,都是可以的。其實分頁最關鍵是這兩句 var startrow currentpage 1 pagesize 1 currentpag...