一致 先验分布 后验分布_浅谈Loki分布式架构中的一致性哈希
云原生小白
看到上面藍色字了么?關注下吧!
Loki在分布式部署的模式下,保存Ingester服務的狀態主要有3個渠道,分別是etcd、consul和基于gossip協議的memberlist。不管Loki用的是什么方式,它們最終都是將哈希環以KV的方式保存。再聊Loki之前,先來了解下一致性哈希的基本概念。一致性哈希[1]是在1997年由麻省理工學院提出的一種分布式哈希(DHT)實現算法。相較于普通的哈希算法,一致性哈希除了繼承數據的離散性、擴展性和容錯性之外,還引入了虛擬節點的概念,極大的優化了數據在存儲過程的中出現的傾斜問題。另外,遇到需要在不中斷業務的情況下擴容節點或處理故障節點時造成的數據哈希變動場景,通常還需要引入數據副本和請求中繼的方式來支持服務的熱變動。
Loki的分布式架構與Cortex一脈相承,其中對于各組件服務狀態和數據的哈希路由均采用了相同的設計。在ring.go中可以看到在Cortex中定義4種類型的哈希環IngesterRing、RulerRing、DestributorRing和CompactorRing。其中最重要的一個環便是IngesterRing。
先來看看Loki官方的架構說明里面是怎么描述的吧。
從這里面我們可以了解到幾個關鍵信息:
- 對日志流進行hash是根據
tenant ID和Labels這兩個字段計算的 - 每個Ingester服務都會擁有一組32位數字組成的Token注冊到哈希環中
- Ingester狀態只有JOINING和ACTIVE狀態時,才可以接收日志寫請求
- Ingester狀態只有ACTIVE和LEAVING狀態時,才可以接收日志讀請求
- 查詢hash環上尋址會符合
token > 日志流hash key中最小的一個token,并找到預期對應的ingester實例 - 如果復制因子大于1,則在已有哈希環上token的位置再順時針尋找下一個不屬于當前ingster的實例
根據上述描述,我們大致得到一個類似下面的示意圖:
可以看到,當復制因子等于2時,Distributor就會將日志流發給兩個ingester服務處理。其中一個ingester故障或者下線時,查詢日志時仍然可以從有副本下一個Ingester實例中獲取到數據
在真實環境里,我們來看看Loki中關于IngesterRing的核心配置如下:
ingester_config:
??lifecycler:
????num_tokens:??|?default?=?128]
????ring:
??????kvstore:???|?default?=?"consul"]
??????replication_factor:??|?default?=?3]這里最重要的便是虛擬節點(num_tokens)和復制因子(replication_factor),這兩個配置將直接影響日志流經過一致性哈希后的路由。虛擬節點的數量直接影響了一致性哈希的數據離散性??梢院唵蔚母爬閚um_tokens越多,日志流經過一致性哈希后會分散得更均衡到ingester處理,不過這是建立在犧牲內存消耗和查找時間前提下的結論。
關于一致性哈希均衡性的結論可參考 https://medium.com/@dgryski/consistent-hashing-algorithmic-tradeoffs-ef6b8e2fcae8#890d
此外,復制因子的數量決定了Loki分布式集群對于節點故障的容忍性,以replication_factor=2為例,當日志流經過一致性哈希后會映射至兩個ingester實例,那么當集群出現故障時,在掛掉一個ingester實例時,Loki日志流的寫入和讀取可以從相鄰的下一個ingester實例中獲取到。如果恰好兩個相鄰的ingester實例掛掉的話那此時日志流的讀寫映射到此區域的皆會受到影響。我們知道,ingester在將chunks刷新到存儲前,這部分數據都是存在內存的,所以復制因子配置過大,會造成內容冗余,配置過小則又會造成故障時丟失數據的風險。在生產環境中使用時,需根據loki的集群規模找到最佳值。
我們可以在瀏覽器中訪問http:///ring來查看和管理一致性哈希環。
可以看到里面主要存了Ingester的ID、狀態、地址、注冊時間、更新時間、Token數(虛擬節點)、數據分布情況和每個Ingester的詳細Tokens。對所有的tokens做個排序便形成了一致性哈希環。當有新的ingester加入進來的時候,帶來的新tokens會填入一致性哈希環,期間涉及到實例間數據遷移的部分僅會影響新token相鄰節點之間展開。
另外,我們還可以發現ingester注冊進環中的服務名取的是hostname,也就是說如果你的Loki集群主機名有變化的話,ingester會以新的實例名稱注冊進哈希環。老的失效的ingester仍然會保留在環中影響數據分布。這時我們需要在管理界面中將失效的Ingester實例刪除掉,也就是圖中的Forget按鈕。
如果你的Loki集群是裸金屬部署,那你需要保證服務器的HostName?
如果你的Loki集群是通過kubernetes部署,那Ingester一定要用StatesfulSet類型
最后,除一致性哈希外,Loki中關于仲裁一致性也會影響集群的可用性。當Distributor的一次請求要經過集群內超過半數的ingester成功相應后才會將本次請求返回給客戶端。關于這部分,Loki采用的Dynamo-style[2]方法,這個曾經在Amazon的Dynamo系統中采用過,目前Riak, Cassandra, 和Voldemort這些無主節點備份模型也有參考。這里算是另一個話題了,留作以后再寫吧。
參考資料
[1]一致性哈希: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.147.1879&rep=rep1&type=pdf
[2]Dynamo-style: https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
你可能還喜歡
點擊下方圖片即可閱讀Loki告警日志內容的騷方法
如何用Loki來繪制Ingress Nginx監控大屏
關注公眾號【云原生小白】,回復「入群」加入Loki學習群
總結
以上是生活随笔為你收集整理的一致 先验分布 后验分布_浅谈Loki分布式架构中的一致性哈希的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求KTV中的高能无节操歌曲!《倾尽天下》
- 下一篇: 电影美人鱼中张轩是不是太监