當前位置:首頁 » 算力簡介 » gossip協議去中心化平均數

gossip協議去中心化平均數

發布時間: 2022-01-20 06:15:55

1. elasticsearch的自動發現節點機制是怎麼實現的,原理是怎樣

著作權歸作者所有。
商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
作者:ben well
鏈接:http://www.hu.com/question/29360024/answer/55368070
來源:知乎

早期 es 版本有 split brain 問題,俗稱腦裂。ES 採用的是一種 P2P 的 gossip 選舉方式,Gossip 演算法因為 Cassandra 而名聲大噪。
背景:
Gossip 演算法, 靈感來自辦公室八卦, 只要一個人八卦一下, 在有限的時間內所有人都會知道該八卦的信息,
這種方式也與病毒傳播類似, 因為 Gossip 有眾多的別名"閑話演算法"、"疫情傳播演算法"、"病毒感染演算法"、"謠言傳播(Rumor-Mongering)演算法".
但 Gossip 並不是一個新東西, 之前的泛洪查找、路由演算法都歸屬於這個范疇, 不同的是 Gossip 給這類演算法提供了明確的語義、具體實施方法及收斂性證明.

特點:
Gossip 演算法又被稱為反熵(Anti-Entropy), 熵是物理學上的一個概念, 代表雜亂無章, 而反熵就是在雜亂無章中尋求一致,
這充分說明了 Gossip 的特點:在一個有界網路中, 每個節點都隨機地與其他節點通信, 經過一番雜亂無章的通信,
最終所有節點的狀態都會達成一致. 每個節點可能知道所有其他節點, 也可能僅知道幾個鄰居節點,
只要這些節可以通過網路連通, 最終他們的狀態都是一致的, 當然這也是疫情傳播的特點.
要注意到的一點是, 即使有的節點因宕機而重啟, 有新節點加入, 但經過一段時間後,
這些節點的狀態也會與其他節點達成一致, 也就是說, Gossip 天然具有分布式容錯的優點.

本質:
Gossip 是一個帶冗餘的容錯演算法, 更進一步, Gossip 是一個最終一致性演算法。
雖然無法保證在某個時刻所有節點狀態一致, 但可以保證在」最終「所有節點一致, 」最終「是一個現實中存在, 但理論上無法證明的時間點。
因為 Gossip 不要求節點知道所有其他節點, 因此又具有去中心化的特點, 節點之間完全對等, 不需要任何的中心節點。
實際上 Gossip 可以用於眾多能接受「最終一致性」的領域:失敗檢測、路由同步、Pub/Sub、動態負載均衡。
但 Gossip 的缺點也很明顯, 冗餘通信會對網路帶寬、CPU 資源造成很大的負載, 而這些負載又受限於通信頻率, 該頻率又影響著演算法收斂的速度。

總結:
Gossip 是一種去中心化、容錯而又最終一致性的絕妙演算法, 其收斂性不但得到證明還具有指數級的收斂速度。
使用 Gossip 的系統可以很容易的把 Server 擴展到更多的節點, 滿足彈性擴展輕而易舉。
唯一的缺點是收斂是最終一致性, 不適應那些強一致性的場景, 比如 2PC。

2. php面試題 memcache和redis的區別

Redis與Memcached的區別

傳統MySQL+ Memcached架構遇到的問題

實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:

1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。

2.Memcached與MySQL資料庫數據一致性問題。

3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。

4.跨機房cache同步問題。

眾多NoSQL百花齊放,如何選擇

最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的
問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解
決以下幾種問題

1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。

2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。

3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。

4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。

面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。

Redis適用場景,如何正確的使用

前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-
backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用
Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

2 Redis支持數據的備份,即master-slave模式的數據備份。

3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。


Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的
key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability =
age*log(size_in_memory)」計
算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以

保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存

中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個
操作,直到子線程完成swap操作後才可以進行修改。

使用Redis特有內存模型前後的情況對比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used



從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。

這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行

批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程
池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。

補充的知識點:

memcached和redis的比較

1 網路IO模型

Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述
字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache
coherency和鎖的問題,比如,Memcached最常用的stats
命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。

(Memcached網路IO模型)

Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,
對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實
際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。

2.內存管理方面

Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內
存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可
能會被剔除,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

Redis使用現場申請內存的方式來存儲數據,並且很少使用free-list等方式來優化內存分配,會在一定程度上存在內存碎片,Redis
跟據存儲命令參數,會把帶過期時間的數據單獨存放在一起,並把它們稱為臨時數據,非臨時數據是永遠不會被剔除的,即便物理內存不夠,導致swap也不會剔
除任何非臨時數據(但會嘗試剔除部分臨時數據),這點上Redis更適合作為存儲而不是cache。

3.數據一致性問題

Memcached提供了cas命令,可以保證多個並發訪問操作同一份數據的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。

4.存儲方式及其它方面

Memcached基本只支持簡單的key-value存儲,不支持枚舉,不支持持久化和復制等功能

Redis除key/value之外,還支持list,set,sorted set,hash等眾多數據結構,提供了KEYS

進行枚舉操作,但不能在線上使用,如果需要枚舉線上數據,Redis提供了工具可以直接掃描其mp文件,枚舉出所有數據,Redis還同時提供了持久化和復制等功能。

5.關於不同語言的客戶端支持

在不同語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過因為Memcached發展的時間更久一些,目
前看在客戶端支持方面,Memcached的很多客戶端更加成熟穩定,而Redis由於其協議本身就比Memcached復雜,加上作者不斷增加新的功能
等,對應第三方客戶端跟進速度可能會趕不上,有時可能需要自己在第三方客戶端基礎上做些修改才能更好的使用。

根據以上比較不難看出,當我們不希望數據被踢出,或者需要除key/value之外的更多數據類型時,或者需要落地功能時,使用Redis比使用Memcached更合適。

關於Redis的一些周邊功能

Redis除了作為存儲之外還提供了一些其它方面的功能,比如聚合計算、pubsub、scripting等,對於此類功能需要了解其實現原
理,清楚地了解到它的局限性後,才能正確的使用,比如pubsub功能,這個實際是沒有任何持久化支持的,消費方連接閃斷或重連之間過來的消息是會全部丟
失的,又比如聚合計算和scripting等功能受Redis單線程模型所限,是不可能達到很高的吞吐量的,需要謹慎使用。

總的來說Redis作者是一位非常勤奮的開發者,可以經常看到作者在嘗試著各種不同的新鮮想法和思路,針對這些方面的功能就要求我們需要深入了解後再使用。

總結:

1.Redis使用最佳方式是全部數據in-memory。

2.Redis更多場景是作為Memcached的替代者來使用。

3.當需要除key/value之外的更多數據類型支持時,使用Redis更合適。

4.當存儲的數據不能被剔除時,使用Redis更合適。

談談Memcached與Redis(一)

1. Memcached簡介

Memcached是以LiveJurnal旗下Danga Interactive公司的Bard
Fitzpatric為首開發的高性能分布式內存緩存伺服器。其本質上就是一個內存key-value資料庫,但是不支持數據的持久化,伺服器關閉之後數
據全部丟失。Memcached使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上,只要安裝了libevent即可使
用。在Windows下,它也有一個可用的非官方版本(http://code.jellycan.com/memcached/)。Memcached
的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang,
Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和
WordPress等。

在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d
install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make
install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可
以為其配置不同的啟動參數。

1.1 Memcache配置

Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。

1)-p <num> Memcached的TCP監聽埠,預設配置為11211;

2)-U <num> Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;

3)-s <file> Memcached監聽的UNIX套接字路徑;

4)-a <mask> 訪問UNIX套接字的八進制掩碼,預設配置為0700;

5)-l <addr> 監聽的伺服器IP地址,默認為所有網卡;

6)-d 為Memcached伺服器啟動守護進程;

7)-r 最大core文件大小;

8)-u <username> 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;

9)-m <num> 分配給Memcached使用的內存數量,單位是MB;

10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;

11)-c <num> 最大並發連數,預設配置為1024;

12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;

13)-f <factor> 用於設置chunk大小的遞增因子;

14)-n <bytes> 最小的chunk大小,預設配置為48個位元組;

15)-t <num> Memcached伺服器使用的線程數,預設配置為4個;

16)-L 嘗試使用大內存頁;

17)-R 每個事件的最大請求數,預設配置為20個;

18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;

2. Redis簡介

Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字
符串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等
POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、
Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘
寶,國外像Flickr、Github等均在使用Redis的緩存服務。

Redis的安裝非常方便,只需從http://redis.io/download獲取源碼,然後make && make

install即可。默認情況下,Redis的伺服器啟動程序和客戶端程序會安裝到/usr/local/bin目錄下。在啟動Redis伺服器時,我們
需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。

3. elasticsearch的自動發現節點機制是怎麼實現的,原理是怎樣

著作權歸作者所有。 商業轉載請聯系作者獲得授權,非商業轉載請註明出處。 作者:ben well 鏈接:http://www.hu.com/question/29360024/answer/55368070 來源:知乎 早期 es 版本有 split brain 問題,俗稱腦裂。ES 採用的是一種 P2P 的 gossip 選舉方式,Gossip 演算法因為 Cassandra 而名聲大噪。 背景: Gossip 演算法, 靈感來自辦公室八卦, 只要一個人八卦一下, 在有限的時間內所有人都會知道該八卦的信息, 這種方式也與病毒傳播類似, 因為 Gossip 有眾多的別名"閑話演算法"、"疫情傳播演算法"、"病毒感染演算法"、"謠言傳播(Rumor-Mongering)演算法". 但 Gossip 並不是一個新東西, 之前的泛洪查找、路由演算法都歸屬於這個范疇, 不同的是 Gossip 給這類演算法提供了明確的語義、具體實施方法及收斂性證明. 特點: Gossip 演算法又被稱為反熵(Anti-Entropy), 熵是物理學上的一個概念, 代表雜亂無章, 而反熵就是在雜亂無章中尋求一致, 這充分說明了 Gossip 的特點:在一個有界網路中, 每個節點都隨機地與其他節點通信, 經過一番雜亂無章的通信, 最終所有節點的狀態都會達成一致. 每個節點可能知道所有其他節點, 也可能僅知道幾個鄰居節點, 只要這些節可以通過網路連通, 最終他們的狀態都是一致的, 當然這也是疫情傳播的特點. 要注意到的一點是, 即使有的節點因宕機而重啟, 有新節點加入, 但經過一段時間後, 這些節點的狀態也會與其他節點達成一致, 也就是說, Gossip 天然具有分布式容錯的優點. 本質: Gossip 是一個帶冗餘的容錯演算法, 更進一步, Gossip 是一個最終一致性演算法。 雖然無法保證在某個時刻所有節點狀態一致, 但可以保證在」最終「所有節點一致, 」最終「是一個現實中存在, 但理論上無法證明的時間點。 因為 Gossip 不要求節點知道所有其他節點, 因此又具有去中心化的特點, 節點之間完全對等, 不需要任何的中心節點。 實際上 Gossip 可以用於眾多能接受「最終一致性」的領域:失敗檢測、路由同步、Pub/Sub、動態負載均衡。 但 Gossip 的缺點也很明顯, 冗餘通信會對網路帶寬、CPU 資源造成很大的負載, 而這些負載又受限於通信頻率, 該頻率又影響著演算法收斂的速度。 總結: Gossip 是一種去中心化、容錯而又最終一致性的絕妙演算法, 其收斂性不但得到證明還具有指數級的收斂速度。 使用 Gossip 的系統可以很容易的把 Server 擴展到更多的節點, 滿足彈性擴展輕而易舉。 唯一的缺點是收斂是最終一致性, 不適應那些強一致性的場景, 比如 2PC。

4. memcached和redis的區別

前者是大型機器

5. redis和memcached的區別

Redis的作者Salvatore Sanfilippo曾經對這兩種基於內存的數據存儲系統進行過比較:

1、Redis支持伺服器端的數據操作:Redis相比Memcached來說,擁有更多的數據結構和並支持更豐富的數據操作,通常在Memcached里,你需要將數據拿到客戶端來進行類似的修改再set回去。這大大增加了網路IO的次數和數據體積。在Redis中,這些復雜的操作通常和一般的GET/SET一樣高效。所以,如果需要緩存能夠支持更復雜的結構和操作,那麼Redis會是不錯的選擇。

2、內存使用效率對比:使用簡單的key-value存儲的話,Memcached的內存利用率更高,而如果Redis採用hash結構來做key-value存儲,由於其組合式的壓縮,其內存利用率會高於Memcached。

3、性能對比:由於Redis只使用單核,而Memcached可以使用多核,所以平均每一個核上Redis在存儲小數據時比Memcached性能更高。而在100k以上的數據中,Memcached性能要高於Redis,雖然Redis最近也在存儲大數據的性能上進行優化,但是比起Memcached,還是稍有遜色。


具體為什麼會出現上面的結論,以下為收集到的資料:

1、數據類型支持不同

與Memcached僅支持簡單的key-value結構的數據記錄不同,Redis支持的數據類型要豐富得多。最為常用的數據類型主要由五種:String、Hash、List、Set和Sorted Set。Redis內部使用一個redisObject對象來表示所有的key和value。redisObject最主要的信息如圖所示:

type代表一個value對象具體是何種數據類型,encoding是不同數據類型在redis內部的存儲方式,比如:type=string代表value存儲的是一個普通字元串,那麼對應的encoding可以是raw或者是int,如果是int則代表實際redis內部是按數值型類存儲和表示這個字元串的,當然前提是這個字元串本身可以用數值表示,比如:」123″ 「456」這樣的字元串。只有打開了Redis的虛擬內存功能,vm欄位欄位才會真正的分配內存,該功能默認是關閉狀態的。

1)String

  • 常用命令:set/get/decr/incr/mget等;

  • 應用場景:String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類;

  • 實現方式:String在redis內部存儲默認就是一個字元串,被redisObject所引用,當遇到incr、decr等操作時會轉成數值型進行計算,此時redisObject的encoding欄位為int。

  • 2)Hash

  • 常用命令:hget/hset/hgetall等

  • 應用場景:我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;

  • 實現方式:Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的介面。如圖所示,Key是用戶ID, value是一個Map。這個Map的key是成員的屬性名,value是屬性值。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。當前HashMap的實現有兩種方式:當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding為ht。

  • 3)List

  • 常用命令:lpush/rpush/lpop/rpop/lrange等;

  • 應用場景:Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;

  • 實現方式:Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構。

  • 4)Set

  • 常用命令:sadd/spop/smembers/sunion等;

  • 應用場景:Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動排重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的重要介面,這個也是list所不能提供的;

  • 實現方式:set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。

  • 5)Sorted Set

  • 常用命令:zadd/zrange/zrem/zcard等;

  • 應用場景:Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。當你需要一個有序的並且不重復的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。

  • 實現方式:Redis sorted set的內部使用HashMap和跳躍表(SkipList)來保證數據的存儲和有序,HashMap里放的是成員到score的映射,而跳躍表裡存放的是所有的成員,排序依據是HashMap里存的score,使用跳躍表的結構可以獲得比較高的查找效率,並且在實現上比較簡單。

  • 2、內存管理機制不同

    在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。當物理內存用完時,Redis可以將一些很久沒用到的value交換到磁碟。Redis只會緩存所有的key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個操作,直到子線程完成swap操作後才可以進行修改。當從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

    對於像Redis和Memcached這種基於內存的資料庫系統來說,內存管理的效率高低是影響系統性能的關鍵因素。傳統C語言中的malloc/free函數是最常用的分配和釋放內存的方法,但是這種方法存在著很大的缺陷:首先,對於開發人員來說不匹配的malloc和free容易造成內存泄露;其次頻繁調用會造成大量內存碎片無法回收重新利用,降低內存利用率;最後作為系統調用,其系統開銷遠遠大於一般函數調用。所以,為了提高內存的管理效率,高效的內存管理方案都不會直接使用malloc/free調用。Redis和Memcached均使用了自身設計的內存管理機制,但是實現方法存在很大的差異,下面將會對兩者的內存管理機制分別進行介紹。

    Memcached默認使用Slab Allocation機制管理內存,其主要思想是按照預先規定的大小,將分配的內存分割成特定長度的塊以存儲相應長度的key-value數據記錄,以完全解決內存碎片問題。Slab Allocation機制只為存儲外部數據而設計,也就是說所有的key-value數據都存儲在Slab Allocation系統里,而Memcached的其它內存請求則通過普通的malloc/free來申請,因為這些請求的數量和頻率決定了它們不會對整個系統的性能造成影響Slab Allocation的原理相當簡單。 如圖所示,它首先從操作系統申請一大塊內存,並將其分割成各種尺寸的塊Chunk,並把尺寸相同的塊分成組Slab Class。其中,Chunk就是用來存儲key-value數據的最小單位。每個Slab Class的大小,可以在Memcached啟動的時候通過制定Growth Factor來控制。假定圖中Growth Factor的取值為1.25,如果第一組Chunk的大小為88個位元組,第二組Chunk的大小就為112個位元組,依此類推。

    當Memcached接收到客戶端發送過來的數據時首先會根據收到數據的大小選擇一個最合適的Slab Class,然後通過查詢Memcached保存著的該Slab Class內空閑Chunk的列表就可以找到一個可用於存儲數據的Chunk。當一條資料庫過期或者丟棄時,該記錄所佔用的Chunk就可以回收,重新添加到空閑列表中。從以上過程我們可以看出Memcached的內存管理制效率高,而且不會造成內存碎片,但是它最大的缺點就是會導致空間浪費。因為每個Chunk都分配了特定長度的內存空間,所以變長數據無法充分利用這些空間。如圖 所示,將100個位元組的數據緩存到128個位元組的Chunk中,剩餘的28個位元組就浪費掉了。

    Redis的內存管理主要通過源碼中zmalloc.h和zmalloc.c兩個文件來實現的。Redis為了方便內存的管理,在分配一塊內存之後,會將這塊內存的大小存入內存塊的頭部。如圖所示,real_ptr是redis調用malloc後返回的指針。redis將內存塊的大小size存入頭部,size所佔據的內存大小是已知的,為size_t類型的長度,然後返回ret_ptr。當需要釋放內存的時候,ret_ptr被傳給內存管理程序。通過ret_ptr,程序可以很容易的算出real_ptr的值,然後將real_ptr傳給free釋放內存。

    Redis通過定義一個數組來記錄所有的內存分配情況,這個數組的長度為ZMALLOC_MAX_ALLOC_STAT。數組的每一個元素代表當前程序所分配的內存塊的個數,且內存塊的大小為該元素的下標。在源碼中,這個數組為zmalloc_allocations。zmalloc_allocations[16]代表已經分配的長度為16bytes的內存塊的個數。zmalloc.c中有一個靜態變數used_memory用來記錄當前分配的內存總大小。所以,總的來看,Redis採用的是包裝的mallc/free,相較於Memcached的內存管理方法來說,要簡單很多。

    3、數據持久化支持

    Redis雖然是基於內存的存儲系統,但是它本身是支持內存數據的持久化的,而且提供兩種主要的持久化策略:RDB快照和AOF日誌。而memcached是不支持數據持久化操作的。

    1)RDB快照

    Redis支持將當前數據的快照存成一個數據文件的持久化機制,即RDB快照。但是一個持續寫入的資料庫如何生成快照呢?Redis藉助了fork命令的 on write機制。在生成快照時,將當前進程fork出一個子進程,然後在子進程中循環所有的數據,將數據寫成為RDB文件。我們可以通過Redis的save指令來配置RDB快照生成的時機,比如配置10分鍾就生成快照,也可以配置有1000次寫入就生成快照,也可以多個規則一起實施。這些規則的定義就在Redis的配置文件中,你也可以通過Redis的CONFIG SET命令在Redis運行時設置規則,不需要重啟Redis。

    Redis的RDB文件不會壞掉,因為其寫操作是在一個新進程中進行的,當生成一個新的RDB文件時,Redis生成的子進程會先將數據寫到一個臨時文件中,然後通過原子性rename系統調用將臨時文件重命名為RDB文件,這樣在任何時候出現故障,Redis的RDB文件都總是可用的。同時,Redis的RDB文件也是Redis主從同步內部實現中的一環。RDB有他的不足,就是一旦資料庫出現問題,那麼我們的RDB文件中保存的數據並不是全新的,從上次RDB文件生成到Redis停機這段時間的數據全部丟掉了。在某些業務下,這是可以忍受的。

    2)AOF日誌

    AOF日誌的全稱是append only file,它是一個追加寫入的日誌文件。與一般資料庫的binlog不同的是,AOF文件是可識別的純文本,它的內容就是一個個的Redis標准命令。只有那些會導致數據發生修改的命令才會追加到AOF文件。每一條修改數據的命令都生成一條日誌,AOF文件會越來越大,所以Redis又提供了一個功能,叫做AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一條記錄的操作只會有一次,而不像一份老文件那樣,可能記錄了對同一個值的多次操作。其生成過程和RDB類似,也是fork一個進程,直接遍歷數據,寫入新的AOF臨時文件。在寫入新文件的過程中,所有的寫操作日誌還是會寫到原來老的AOF文件中,同時還會記錄在內存緩沖區中。當重完操作完成後,會將所有緩沖區中的日誌一次性寫入到臨時文件中。然後調用原子性的rename命令用新的AOF文件取代老的AOF文件。

    AOF是一個寫文件操作,其目的是將操作日誌寫到磁碟上,所以它也同樣會遇到我們上面說的寫操作的流程。在Redis中對AOF調用write寫入後,通過appendfsync選項來控制調用fsync將其寫到磁碟上的時間,下面appendfsync的三個設置項,安全強度逐漸變強。

  • appendfsync no 當設置appendfsync為no的時候,Redis不會主動調用fsync去將AOF日誌內容同步到磁碟,所以這一切就完全依賴於操作系統的調試了。對大多數Linux操作系統,是每30秒進行一次fsync,將緩沖區中的數據寫到磁碟上。

  • appendfsync everysec 當設置appendfsync為everysec的時候,Redis會默認每隔一秒進行一次fsync調用,將緩沖區中的數據寫到磁碟。但是當這一次的fsync調用時長超過1秒時。Redis會採取延遲fsync的策略,再等一秒鍾。也就是在兩秒後再進行fsync,這一次的fsync就不管會執行多長時間都會進行。這時候由於在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞。所以結論就是,在絕大多數情況下,Redis會每隔一秒進行一次fsync。在最壞的情況下,兩秒鍾會進行一次fsync操作。這一操作在大多數資料庫系統中被稱為group commit,就是組合多次寫操作的數據,一次性將日誌寫到磁碟。

  • appednfsync always 當設置appendfsync為always時,每一次寫操作都會調用一次fsync,這時數據是最安全的,當然,由於每次都會執行fsync,所以其性能也會受到影響。

  • 對於一般性的業務需求,建議使用RDB的方式進行持久化,原因是RDB的開銷並相比AOF日誌要低很多,對於那些無法忍數據丟失的應用,建議使用AOF日誌。

    4、集群管理的不同

    Memcached是全內存的數據緩沖系統,Redis雖然支持數據的持久化,但是全內存畢竟才是其高性能的本質。作為基於內存的存儲系統來說,機器物理內存的大小就是系統能夠容納的最大數據量。如果需要處理的數據量超過了單台機器的物理內存大小,就需要構建分布式集群來擴展存儲能力。

    Memcached本身並不支持分布式,因此只能在客戶端通過像一致性哈希這樣的分布式演算法來實現Memcached的分布式存儲。下圖給出了Memcached的分布式存儲實現架構。當客戶端向Memcached集群發送數據之前,首先會通過內置的分布式演算法計算出該條數據的目標節點,然後數據會直接發送到該節點上存儲。但客戶端查詢數據時,同樣要計算出查詢數據所在的節點,然後直接向該節點發送查詢請求以獲取數據。

    相較於Memcached只能採用客戶端實現分布式存儲,Redis更偏向於在伺服器端構建分布式存儲。最新版本的Redis已經支持了分布式存儲功能。Redis Cluster是一個實現了分布式且允許單點故障的Redis高級版本,它沒有中心節點,具有線性可伸縮的功能。下圖給出Redis Cluster的分布式存儲架構,其中節點與節點之間通過二進制協議進行通信,節點與客戶端之間通過ascii協議進行通信。在數據的放置策略上,Redis Cluster將整個key的數值域分成4096個哈希槽,每個節點上可以存儲一個或多個哈希槽,也就是說當前Redis Cluster支持的最大節點數就是4096。Redis Cluster使用的分布式演算法也很簡單:crc16( key ) % HASH_SLOTS_NUMBER。

    為了保證單點故障下的數據可用性,Redis Cluster引入了Master節點和Slave節點。在Redis Cluster中,每個Master節點都會有對應的兩個用於冗餘的Slave節點。這樣在整個集群中,任意兩個節點的宕機都不會導致數據的不可用。當Master節點退出後,集群會自動選擇一個Slave節點成為新的Master節點。

6. elasticsearch的自動發現節點機制是怎麼實現的,原理是怎樣

1、Gossip 是一種去中心化、容錯而又最終一致性的絕妙演算法, 其收斂性不但得到證明還具有指數級的收斂速度。
2、使用 Gossip 的系統可以很容易的把 Server 擴展到更多的節點, 滿足彈性擴展輕而易舉。
3、唯一的缺點是收斂是最終一致性, 不適應那些強一致性的場景, 比如 2PC。

7. Dynamo的高級分析

有了上面一章里的兩個基礎介紹之後,我們開始進入Dynamo的世界。
Dynamo的數據分區與作用
在Dynamo的實現中提到一個關鍵的東西,就是數據分區。 假設我們的數據的key的范圍是0到2的64次方(不用懷疑你的數據量會超過它,正常甚至變態情況下你都是超不過的,甚至像伏地魔等其他類Dynamo系統是使用的 2的32次方),然後設置一個常數,比如說1000,將我們的key的范圍分成1000份。然後再將這1000份key的范圍均勻分配到所有的節點(s個節點),這樣每個節點負責的分區數就是1000/s份分區。
如圖二,假設我們有A、B、C三台機器,然後將我們的分區定義了12個。
圖二:三個節點分12個區的數據的情況
因為數據是均勻離散到這個環上的(有人開始會認為數據的key是從1、2、3、4……這樣子一直下去的,其實不是的,哈希計算出來的值,都是一個離散的結果),所以我們每個分區的數據量是大致相等的。從圖上我們可以得出,每台機器都分到了三個分區里的數據,並且因為分區是均勻的,在分區數量是相當大的時候,數據的分布會更加的均勻,與此同時,負載也被均勻地分開了(當然了,如果硬要說你的負載還是只集中在一個分區里,那就不是在這里要討論的問題了,有可能是你的哈希函數是不是有什麼樣的問題了)。
為什麼要進行這樣的分布呢,分布的好處在於,在有新機器加入的時候,只需要替換原有分區即可,如圖三所示:
圖三:加入一個新的節點D的情況
同樣是圖二里的情況,12個分區分到ABC三個節點,圖三中就是再進入了一個新的節點D,從圖上的重新分布情況可以得出,所有節點里只需要轉移四分之一的數據到新來的節點即可,同時,新節點的負載也伴隨分區的轉移而轉移了(這里的12個分區太少了,如果是1200個分區甚至是12000個分區的話,這個結論就是正確的了,12個分區只為演示用)。
從Dynamo的NRW看CAP法則
在Dynamo系統中,第一次提出來了NRW的方法。
N:復制的次數;
R:讀數據的最小節點數;
W:寫成功的最小分區數。
這三個數的具體作用是用來靈活地調整Dynamo系統的可用性與一致性。
舉個例子來說,如果R=1的話,表示最少只需要去一個節點讀數據即可,讀到即返回,這時是可用性是很高的,但並不能保證數據的一致性,如果說W同時為1的 話,那可用性更新是最高的一種情況,但這時完全不能保障數據的一致性,因為在可供復制的N個節點里,只需要寫成功一次就返回了,也就意味著,有可能在讀的這一次並沒有真正讀到需要的數據(一致性相當的不好)。如果W=R=N=3的話,也就是說,每次寫的時候,都保證所有要復制的點都寫成功,讀的時候也是都讀到,這樣子讀出來的數據一定是正確的,但是其性能大打折扣,也就是說,數據的一致性非常的高,但系統的可用性卻非常低了。如果R + W > N能夠保證我們「讀我們所寫」,Dynamo推薦使用322的組合。
Dynamo系統的數據分區讓整個網路的可擴展性其實是一個固定值(你分了多少區,實際上網路里擴展節點的上限就是這個數),通過NRW來達到另外兩個方 向上的調整。
Dynamo的一些增加可用性的補救
針對一些經常可能出現的問題,Dynamo還提供了一些解決的方法。
第一個是hinted handoff數據的加入:在一個節點出現臨時性故障時,數據會自動進入列表中的下一個節點進行寫操作,並標記為handoff數據,在收到通知需要原節點恢復時重新把數據推回去。這能使系統的寫入成功大大提升。
第二個是向量時鍾來做版本控制:用一個向量(比如說[a,1]表示這個數據在a節點第一次寫入)來標記數據的版本,這樣在有版本沖突的時候,可以追溯到出現問題的地方。這可以使數據的最終一致成為可能。(Cassandra未用vector clock,而只用client timestamps也達到了同樣效果。)
第三個是Merkle tree來提速數據變動時的查找:使用Merkle tree為數據建立索引,只要任意數據有變動,都將快速反饋出來。
第四個是Gossip協議:一種通訊協議,目標是讓節點與節點之間通信,省略中心節點的存在,使網路達到去中心化。提高系統的可用性。

8. 為什麼 elasticsearch 獲取節點信息失敗

為什麼 elasticsearch 獲取節點信息失敗
早期 es 版本有 split brain 問題,俗稱腦裂。ES 採用的是一種 P2P 的 gossip 選舉方式,Gossip 演算法因為 Cassandra 而名聲大噪。
背景:
Gossip 演算法, 靈感來自辦公室八卦, 只要一個人八卦一下, 在有限的時間內所有人都會知道該八卦的信息,
這種方式也與病毒傳播類似, 因為 Gossip 有眾多的別名"閑話演算法"、"疫情傳播演算法"、"病毒感染演算法"、"謠言傳播(Rumor-Mongering)演算法".
但 Gossip 並不是一個新東西, 之前的泛洪查找、路由演算法都歸屬於這個范疇, 不同的是 Gossip 給這類演算法提供了明確的語義、具體實施方法及收斂性證明.

特點:
Gossip 演算法又被稱為反熵(Anti-Entropy), 熵是物理學上的一個概念, 代表雜亂無章, 而反熵就是在雜亂無章中尋求一致,
這充分說明了 Gossip 的特點:在一個有界網路中, 每個節點都隨機地與其他節點通信, 經過一番雜亂無章的通信,
最終所有節點的狀態都會達成一致. 每個節點可能知道所有其他節點, 也可能僅知道幾個鄰居節點,
只要這些節可以通過網路連通, 最終他們的狀態都是一致的, 當然這也是疫情傳播的特點.
要注意到的一點是, 即使有的節點因宕機而重啟, 有新節點加入, 但經過一段時間後,
這些節點的狀態也會與其他節點達成一致, 也就是說, Gossip 天然具有分布式容錯的優點.

本質:
Gossip 是一個帶冗餘的容錯演算法, 更進一步, Gossip 是一個最終一致性演算法。
雖然無法保證在某個時刻所有節點狀態一致, 但可以保證在」最終「所有節點一致, 」最終「是一個現實中存在, 但理論上無法證明的時間點。
因為 Gossip 不要求節點知道所有其他節點, 因此又具有去中心化的特點, 節點之間完全對等, 不需要任何的中心節點。
實際上 Gossip 可以用於眾多能接受「最終一致性」的領域:失敗檢測、路由同步、Pub/Sub、動態負載均衡。
但 Gossip 的缺點也很明顯, 冗餘通信會對網路帶寬、CPU 資源造成很大的負載, 而這些負載又受限於通信頻率, 該頻率又影響著演算法收斂的速度。

9. 比特幣的價值是由什麼決定的

分為價格和價值兩個部分吧。
1:價值是基於早期去中心化(實際上還是資本擁有中心化的算力,資本擁有中心化的幣數量,可能這里的去中心化不會很理想)的區塊鏈技術誕生的所謂貨幣。當時人們有一定的預期預想和信仰,去中心化的低信任成本的世界大通,是一個很好的未來暢想,這讓大多數人認可他的價值(當然同時也造成了負面的使用價值,不可被控制和政府監管,提供很多額外便利)
當然數字貨幣的一些屬性是可借鑒的,現在各國也是法定數字貨幣的趨勢,btc可能由於一定的技術原因,個人覺得最終會趨於消失,或者是很難無法達到信仰者世界大通的願景的。如果沒有更好的技術底層更迭,技術的限制也會隨著科學技術的目前發展被逐步淘汰掉。
2:價格當然基本是由於市場交易決定的。BTC被很多資本更多的價值可能是作為金融價值使用。(還有價格的另一個普遍認知是數量有限,且產出越來越慢,隨著使用面增多,稀缺性提高價格,減半的故事也是資本家的良好助力)
因為是小眾,無監管,所以資本的力量影響是對價格很大的。美好的致富效應,可以吸引不斷的人進場,各種資本機構大戶交易所解決了業務產業問題,有了一些額外操作收入,同時誕生行業(例如基礎的金融衍生品及其他更多)。
包括今年的灰度牛,隨著疫情和美國局勢背景下,聯合機構製造新的金融衍生品在二級市場,一個新的循環致富故事誕生了,這個模式目前還比較堅實,價格穩定,且上漲。當然最終的消化者還是普通群眾。
同時BTC的特性也造成了一部人配置的避險資產。
等等原因博弈下產生了BTC的價格。
個人最終的結論(僅供參考):比特幣更多是一種金融價值,使用價值目前還是有限的,未來的難度推進也很高,技術如果不進化,會依舊小眾化的,當然世界政府的博弈也是一定的阻力。
目前的價格有機構的金融游戲基礎,還是有一定的穩定性的,前提是如果沒有新的大量人參與這個游戲,目前的上漲趨勢會減慢,灰度和機構也在擴展其他數字貨幣的玩法(畢竟GBTC對標的BTC數量佔比總BTC的已經比較多了-實物出資加少部分現金出資),但是可能還有上漲,不過什麼時候是頂,就看各種博弈的結果了(我覺得幾個點:1.一級市場的BTC或者其他幣交易頻度和持有量與灰度之間的博弈能有多久,人們的購買和消耗什麼時候對標灰度到一個界限。不可能一直買一直賣,有一個界限什麼時候到 2.灰度和機構自己的BTC對應的GBTC的二級市場消化度,什麼時候會消化不良也是一個博弈……等等)
BTC是有泡沫的,資本的金融游戲都是有很多泡沫的,當然這是很容易致富的機會,泡沫就是致富很快的渠道。
但是風險很高,不適用於大眾。只能說看運勢和契機吧。
BTC隨著每一次金融大趨勢游戲都會有大動作。
投資要謹慎。

熱點內容
比特幣還是未來老大嗎 發布:2025-05-06 21:09:03 瀏覽:310
5g融合合約機怎麼取消 發布:2025-05-06 21:00:57 瀏覽:423
s19礦機一天產多少幣 發布:2025-05-06 20:55:36 瀏覽:616
usdt充幣記錄 發布:2025-05-06 20:53:15 瀏覽:662
自己如何挖eth 發布:2025-05-06 20:41:03 瀏覽:849
洛倫茲力算內力嘛 發布:2025-05-06 20:38:06 瀏覽:260
深圳市民中心去中英街 發布:2025-05-06 20:33:47 瀏覽:146
央行主導的法定數字貨幣 發布:2025-05-06 20:14:15 瀏覽:430
期權合約結算價格怎麼計算 發布:2025-05-06 20:08:17 瀏覽:403
分布式賬本技術超越區塊鏈英文 發布:2025-05-06 20:06:02 瀏覽:566