不懂Redis Cluster原理,我被同事diss了!

2021-01-16 51CTO

Redis 緩存作為使用最多的緩存工具被各大廠商爭相使用。通常我們會使用單體的 Redis 應用作為緩存服務,為了保證其高可用還會使用主從模式(Master-Slave),又或者是讀寫分離的設計。

圖片來自 Pexels

但是當緩存數據量增加以後,無法用單體伺服器承載緩存服務時,就需要對緩存服務進行擴展。

將需要緩存的數據切分成不同的分區,將數據分區放到不同的伺服器中,用分布式的緩存來承載高並發的緩存訪問。恰好 Redis Cluster 方案剛好支持這部分功能。

今天就來一起看看 Redis Cluster 的核心原理和實踐:

Redis Cluster 實現數據分區分布式緩存節點之間的通訊請求分布式緩存的路由緩存節點的擴展和收縮故障發現和恢復

Redis Cluster 實現數據分區

正如開篇中提到的,分布式資料庫要解決的就是將整塊數據,按照規則分配到多個緩存節點,解決的是單個緩存節點處理數量大的問題。

如果要將這些數據進行拆分,並且存放必須有一個算法。例如:哈希算法和哈希一致性算法,這些比較經典的算法。

Redis Cluster 則採用的是虛擬槽分區算法。其中提到了槽(Slot)的概念。這個槽是用來存放緩存信息的單位,在 Redis 中將存儲空間分成了 16384 個槽,也就是說 Redis Cluster 槽的範圍是 0 -16383(2^4 * 2^10)。

緩存信息通常是用 Key-Value 的方式來存放的,在存儲信息的時候,集群會對 Key 進行 CRC16 校驗並對 16384 取模(slot = CRC16(key)%16383)。

得到的結果就是 Key-Value 所放入的槽,從而實現自動分割數據到不同的節點上。然後再將這些槽分配到不同的緩存節點中保存。

圖1:Redis 集群中的數據分片

如圖 1 所示,假設有三個緩存節點分別是 1、2、3。Redis Cluster 將存放緩存數據的槽(Slot)分別放入這三個節點中:

緩存節點 1 存放的是(0-5000)Slot 的數據。緩存節點 2 存放的是(5001-10000)Slot 的數據。緩存節點 3 存放的是(10000-16383)Slot 的數據。

此時 Redis Client 需要根據一個 Key 獲取對應的 Value 的數據,首先通過 CRC16(key)%16383 計算出 Slot 的值,假設計算的結果是 5002。

將這個數據傳送給 Redis Cluster,集群接受到以後會到一個對照表中查找這個 Slot=5002 屬於那個緩存節點。

發現屬於「緩存節點 2」,於是順著紅線的方向調用緩存節點 2 中存放的 Key-Value 的內容並且返回給 Redis Client。

分布式緩存節點之間的通訊

如果說 Redis Cluster 的虛擬槽算法解決的是數據拆分和存放的問題,那麼存放緩存數據的節點之間是如何通訊的,就是接下來我們要討論的。

緩存節點中存放著緩存的數據,在 Redis Cluster 的分布式部署下,緩存節點會被分配到一臺或者多臺伺服器上。

圖 2:新上線的緩存節點 2 和緩存節點 1 進行通訊

緩存節點的數目也有可能根據緩存數據量和支持的並發進行擴展。如圖 2 所示,假設 Redis Cluster 中存在「緩存節點 1」,此時由於業務擴展新增了「緩存節點 2」。

新加入的節點會通過 Gossip 協議向老節點,發出一個「Meet 消息」。收到消息以後「緩存節點 1」,會禮貌地回復一個「Pong 消息」。

此後「緩存節點 2」會定期發送給「緩存節點 1」 一個「Ping 消息」,同樣的「緩存節點 1」每次都會回復「Pong 消息」。

上面這個例子說明了,在 Redis Cluster 中緩存節點之間是通過 Gossip 協議進行通訊的。

其實節點之間通訊的目的是為了維護節點之間的元數據信息。這個元數據就是每個節點包含哪些數據,是否出現故障。

節點之間通過 Gossip 協議不斷相互交互這些信息,就好像一群人在一起八卦一樣,沒有多久每個節點就知道其他所有節點的情況了,這個情況就是節點的元數據。

整個傳輸過程大致分為以下幾點:

Redis Cluster 的每個緩存節點都會開通一個獨立的 TCP 通道,用於和其他節點通訊。有一個節點定時任務,每隔一段時間會從系統中選出「發送節點」。這個「發送節點」按照一定頻率,例如:每秒 5 次,隨機向最久沒有通訊的節點發起 Ping 消息。接受到 Ping 消息的節點會使用 Pong 消息向「發送節點」進行回復。

不斷重複上面行為,讓所有節點保持通訊。他們之間通訊是通過 Gossip 協議實現的。

從類型上來說其分為了四種,分別是:

Meet 消息,用於通知新節點加入。就好像上面例子中提到的新節點上線會給老節點發送 Meet 消息,表示有「新成員」加入。Ping 消息,這個消息使用得最為頻繁,該消息中封裝了自身節點和其他節點的狀態數據,有規律地發給其他節點。Pong 消息,在接受到 Meet 和 Ping 消息以後,也將自己的數據狀態發給對方。同時也可以對集群中所有的節點發起廣播,告知大家的自身狀態。Fail 消息,如果一個節點下線或者掛掉了,會向集群中廣播這個消息。

圖 3:Gossip 協議結構

Gossip 協議的結構如圖 3 所示,有其中 type 定義了消息的類型,例如:Meet、Ping、Pong、Fail 等消息。

另外有一個 myslots 的數組定義了節點負責的槽信息。每個節點發送 Gossip 協議給其他節點最重要的就是將該信息告訴其他節點。另外,消息體通過 clusterMsgData 對象傳遞消息徵文。

請求分布式緩存的路由

對內,分布式緩存的節點通過 Gossip 協議互相發送消息,為了保證節點之間了解對方的情況。

那麼對外來說,一個 Redis 客戶端如何通過分布式節點獲取緩存數據,就是分布式緩存路由要解決的問題了。

上文提到了 Gossip 協議會將每個節點管理的槽信息發送給其他節點,其中用到了 unsigned char myslots[CLUSTER_SLOTS/8] 這樣一個數組存放每個節點的槽信息。

myslots 屬性是一個二進位位數組(bit array),其中 CLUSTER_SLOTS 為 16384。

這個數組的長度為 16384/8=2048 個字節,由於每個字節包含 8 個 bit 位(二進位位),所以共包含 16384 個 bit,也就是 16384 個二進位位。

每個節點用 bit 來標識自己是否擁有某個槽的數據。如圖 4 所示,假設這個圖表示節點 A 所管理槽的情況。

圖 4:通過二進位數組存放槽信息

0、1、2 三個數組下標就表示 0、1、2 三個槽,如果對應的二進位值是 1,表示該節點負責存放 0、1、2 三個槽的數據。同理,後面的數組下標位 0 就表示該節點不負責存放對應槽的數據。

用二進位存放的優點是,判斷的效率高,例如對於編號為 1 的槽,節點只要判斷序列的第二位,時間複雜度為 O(1)。

圖 5:接受節點把節點槽的對應信息保存在本地

如圖 5 所示,當收到發送節點的節點槽信息以後,接受節點會將這些信息保存到本地的 clusterState 的結構中,其中 Slots 的數組就是存放每個槽對應哪些節點信息。

圖 6:ClusterStatus 結構以及槽與節點的對應

如圖 6 所示,ClusterState 中保存的 Slots 數組中每個下標對應一個槽,每個槽信息中對應一個 clusterNode 也就是緩存的節點。

這些節點會對應一個實際存在的 Redis 緩存服務,包括 IP 和 Port 的信息。

Redis Cluster 的通訊機制實際上保證了每個節點都有其他節點和槽數據的對應關係。

Redis 的客戶端無論訪問集群中的哪個節點都可以路由到對應的節點上,因為每個節點都有一份 ClusterState,它記錄了所有槽和節點的對應關係。

下面來看看 Redis 客戶端是如何通過路由來調用緩存節點的:

圖 7:MOVED 重定向請求

如圖 7 所示,Redis 客戶端通過 CRC16(key)%16383 計算出 Slot 的值,發現需要找「緩存節點 1」讀/寫數據,但是由於緩存數據遷移或者其他原因導致這個對應的 Slot 的數據被遷移到了「緩存節點 2」上面。

那麼這個時候 Redis 客戶端就無法從「緩存節點 1」中獲取數據了。

但是由於「緩存節點 1」中保存了所有集群中緩存節點的信息,因此它知道這個 Slot 的數據在「緩存節點 2」中保存,因此向 Redis 客戶端發送了一個 MOVED 的重定向請求。

這個請求告訴其應該訪問的「緩存節點 2」的地址。Redis 客戶端拿到這個地址,繼續訪問「緩存節點 2」並且拿到數據。

上面的例子說明了,數據 Slot 從「緩存節點 1」已經遷移到「緩存節點 2」了,那麼客戶端可以直接找「緩存節點 2」要數據。

那麼如果兩個緩存節點正在做節點的數據遷移,此時客戶端請求會如何處理呢?

圖 8:ASK 重定向請求

如圖 8 所示,Redis 客戶端向「緩存節點 1」發出請求,此時「緩存節點 1」正向「緩存節點 2」遷移數據,如果沒有命中對應的 Slot,它會返回客戶端一個 ASK 重定向請求並且告訴「緩存節點 2」的地址。

客戶端向「緩存節點 2」發送 Asking 命令,詢問需要的數據是否在「緩存節點 2」上,「緩存節點 2」接到消息以後返回數據是否存在的結果。

緩存節點的擴展和收縮

作為分布式部署的緩存節點總會遇到緩存擴容和緩存故障的問題。這就會導致緩存節點的上線和下線的問題。

由於每個節點中保存著槽數據,因此當緩存節點數出現變動時,這些槽數據會根據對應的虛擬槽算法被遷移到其他的緩存節點上。

圖 9:分布式緩存擴容

如圖 9 所示,集群中本來存在「緩存節點 1」和「緩存節點 2」,此時「緩存節點 3」上線了並且加入到集群中。

此時根據虛擬槽的算法,「緩存節點 1」和「緩存節點 2」中對應槽的數據會應該新節點的加入被遷移到「緩存節點 3」上面。

針對節點擴容,新建立的節點需要運行在集群模式下,因此新建節點的配置最好與集群內其他節點配置保持一致。

新節點加入到集群的時候,作為孤兒節點是沒有和其他節點進行通訊的。因此,其會採用 cluster meet 命令加入到集群中。

在集群中任意節點執行 cluster meet 命令讓新節點加入進來。假設新節點是 192.168.1.1 5002,老節點是 192.168.1.1 5003,那麼運行以下命令將新節點加入到集群中。

192.168.1.1 5003> cluster meet 192.168.1.1 5002

這個是由老節點發起的,有點老成員歡迎新成員加入的意思。新節點剛剛建立沒有建立槽對應的數據,也就是說沒有緩存任何數據。

如果這個節點是主節點,需要對其進行槽數據的擴容;如果這個節點是從節點,就需要同步主節點上的數據。總之就是要同步數據。

圖 10:節點遷移槽數據的過程

如圖 10 所示,由客戶端發起節點之間的槽數據遷移,數據從源節點往目標節點遷移:

客戶端對目標節點發起準備導入槽數據的命令,讓目標節點準備好導入槽數據。這裡使用 cluster setslot {slot} importing {sourceNodeId} 命令。之後對源節點發起送命令,讓源節點準備遷出對應的槽數據。使用命令 cluster setslot {slot} importing {sourceNodeId}。此時源節點準備遷移數據了,在遷移之前把要遷移的數據獲取出來。通過命令 cluster getkeysinslot {slot} {count}。Count 表示遷移的 Slot 的個數。然後在源節點上執行,migrate {targetIP} {targetPort} 「」 0 {timeout} keys{keys} 命令,把獲取的鍵通過流水線批量遷移到目標節點。重複 3 和 4 兩步不斷將數據遷移到目標節點。目標節點獲取遷移的數據。完成數據遷移以後目標節點,通過 cluster setslot {slot} node {targetNodeId} 命令通知對應的槽被分配到目標節點,並且廣播這個信息給全網的其他主節點,更新自身的槽節點對應表。

既然有緩存伺服器的上線操作,那麼也有下線的操作。下線操作正好和上線操作相反,將要下線緩存節點的槽數據分配到其他的緩存主節點中。

遷移的過程也與上線操作類似,不同的是下線的時候需要通知全網的其他節點忘記自己,此時通過命令 cluster forget{downNodeId} 通知其他的節點。

當節點收到 forget 命令以後會將這個下線節點放到僅用列表中,那麼之後就不用再向這個節點發送 Gossip 的 Ping 消息了。

不過這個僅用表的超時時間是 60 秒,超過了這個時間,依舊還會對這個節點發起 Ping 消息。

不過可以使用 redis-trib.rb del-node{host:port} {donwNodeId} 命令幫助我們完成下線操作。

尤其是下線的節點是主節點的情況下,會安排對應的從節點接替主節點的位置。

故障發現和恢復

前面在談到緩存節點擴展和收縮是提到,緩存節點收縮時會有一個下線的動作。

有些時候是為了節約資源,或者是計劃性的下線,但更多時候是節點出現了故障導致下線。

針對下線故障來說有兩種下線的確定方式:

主觀下線:當節點 1 向節點 2 例行發送 Ping 消息的時候,如果節點 2 正常工作就會返回 Pong 消息,同時會記錄節點 1 的相關信息。

同時接受到 Pong 消息以後節點 1 也會更新最近一次與節點 2 通訊的時間。

如果此時兩個節點由於某種原因斷開連接,過一段時間以後節點 1 還會主動連接節點 2,如果一直通訊失敗,節點 1 中就無法更新與節點 2 最後通訊時間了。

此時節點 1 的定時任務檢測到與節點 2 最好通訊的時間超過了 cluster-node-timeout 的時候,就會更新本地節點狀態,把節點 2 更新為主觀下線。

這裡的 cluster-node-timeout 是節點掛掉被發現的超時時間,如果超過這個時間還沒有獲得節點返回的 Pong 消息就認為該節點掛掉了。

這裡的主觀下線指的是,節點 1 主觀的認為節點 2 沒有返回 Pong 消息,因此認為節點 2 下線。

只是節點 1 的主觀認為,有可能是節點 1 與節點 2 之間的網絡斷開了,但是其他的節點依舊可以和節點 2 進行通訊,因此主觀下線並不能代表某個節點真的下線了。

客觀下線:由於 Redis Cluster 的節點不斷地與集群內的節點進行通訊,下線信息也會通過 Gossip 消息傳遍所有節點。

因此集群內的節點會不斷收到下線報告,當半數以上持有槽的主節點標記了某個節點是主觀下線時,便會觸發客觀下線的流程。

也就是說當集群內的半數以上的主節點,認為某個節點主觀下線了,才會啟動這個流程。

這個流程有一個前提,就是直針對主節點,如果是從節點就會忽略。也就是說集群中的節點每次接受到其他節點的主觀下線是都會做以下的事情。

將主觀下線的報告保存到本地的 ClusterNode 的結構中,並且針對主觀下線報告的時效性進行檢查,如果超過 cluster-node-timeout*2 的時間,就忽略這個報告。

否則就記錄報告內容,並且比較被標記下線的主觀節點的報告數量大於等於持有槽的主節點數量的時候,將其標記為客觀下線。

同時向集群中廣播一條 Fail 消息,通知所有的節點將故障節點標記為客觀下線,這個消息指包含故障節點的 ID。

此後,群內所有的節點都會標記這個節點為客觀下線,通知故障節點的從節點出發故障轉移的流程,也就是故障的恢復。

說白了,客觀下線就是整個集群中有一半的節點都認為某節點主觀下線了,那麼這個節點就被標記為客觀下線了。

如果某個主節點被認為客觀下線了,那麼需要從它的從節點中選出一個節點替代主節點的位置。

此時下線主節點的所有從節點都擔負著恢復義務,這些從節點會定時監測主節點是否下線。

一旦發現下線會走如下的恢復流程:

①資格檢查,每個節點都會檢查與主節點斷開的時間。如果這個時間超過了 cluster-node-timeout*cluster-slave-validity-factor(從節點有效因子,默認為 10),那麼就沒有故障轉移的資格。

也就是說這個從節點和主節點斷開的太久了,很久沒有同步主節點的數據了,不適合成為新的主節點,因為成為主節點以後其他的從節點回同步自己的數據。

②觸發選舉,通過了上面資格的從節點都可以觸發選舉。但是出發選舉是有先後順序的,這裡按照複製偏移量的大小來判斷。

這個偏移量記錄了執行命令的字節數。主伺服器每次向從伺服器傳播 N 個字節時就會將自己的複製偏移量+N,從服務在接收到主伺服器傳送來的 N 個字節的命令時,就將自己的複製偏移量+N。

複製偏移量越大說明從節點延遲越低,也就是該從節點和主節點溝通更加頻繁,該從節點上面的數據也會更新一些,因此複製偏移量大的從節點會率先發起選舉。

③發起選舉,首先每個主節點會去更新配置紀元(clusterNode.configEpoch),這個值是不斷增加的整數。

在節點進行 Ping/Pong 消息交互式也會更新這個值,它們都會將最大的值更新到自己的配置紀元中。

這個值記錄了每個節點的版本和整個集群的版本。每當發生重要事情的時候,例如:出現新節點,從節點精選。都會增加全局的配置紀元並且賦給相關的主節點,用來記錄這個事件。

說白了更新這個值目的是,保證所有主節點對這件「大事」保持一致。大家都統一成一個配置紀元(一個整數),表示大家都知道這個「大事」了。

更新完配置紀元以後,會想群內發起廣播選舉的消息(FAILOVER_AUTH_REQUEST)。並且保證每個從節點在一次配置紀元中只能發起一次選舉。

④投票選舉,參與投票的只有主節點,從節點沒有投票權,超過半數的主節點通過某一個節點成為新的主節點時投票完成。

如果在 cluster-node-timeout*2 的時間內從節點沒有獲得足夠數量的票數,本次選舉作廢,進行第二輪選舉。

這裡每個候選的從節點會收到其他主節點投的票。在第2步領先的從節點通常此時會獲得更多的票,因為它觸發選舉的時間更早一些。

獲得票的機會更大,也是由於它和原主節點延遲少,理論上數據會更加新一點。

⑤當滿足投票條件的從節點被選出來以後,會觸發替換主節點的操作。新的主節點別選出以後,刪除原主節點負責的槽數據,把這些槽數據添加到自己節點上。

並且廣播讓其他的節點都知道這件事情,新的主節點誕生了。

總結

本文通過 Redis Cluster 提供了分布式緩存的方案為出發點,針對此方案中緩存節點的分區方式進行了描述。

虛擬槽的分區算法,將整塊數據分配到了不同的緩存節點,通過 Slot 和 Node 的對應關係讓數據找到節點的位置。

對於分布式部署的節點,需要通過 Gossip 協議進行 Ping、Pong、Meet、Fail 的通訊,達到互通有無的目的。

當客戶端調用緩存節點數據的時候通過 MOVED 和 ASKED 重定向請求找到正確的緩存節點。

並且介紹了在緩存擴容和收縮時需要注意的處理流程,以及數據遷移的方式。

最後,講述如何發現故障(主觀下線和客觀下線)以及如何恢復故障(選舉節點)的處理流程。

相關焦點

  • redis cluster 集群管理工具
    前言在redis源碼編譯的時候,在src目錄下會有一個redis-trib.rb的腳本,這個腳本是ruby寫的,用於管理redis cluster。info命令也是先執行load_cluster_info_from_node獲取完整的集群信息。/opt/redis/bin/redis-trib.rb info 127.0.0.1:80013、check檢查集群:檢查集群狀態的命令,沒有其他參數,只需要選擇一個集群中的一個節點即可。
  • redis cluster 之master 選舉過程
    在redis 3.0版本後,官方推出了redis cluster 分布式解決方案,當一個redis節點掛了可以快速地切換到另一個節點。當遇到單機內存、並發等瓶頸時,可以採用分布式方案要解決問題.redis-cluster架構中,被設計成共有16384(2的14次方)個hash slot。每個master分得一部分slot,其算法為:hash_slot = crc16(key) mod 16384 ,這就找到對應slot。群集至少需要3主3從,且每個實例使用不同的配置文件。
  • redis cluster-cluster 命令手動管理redis集群
    使用cluster命令管理redis cluster集群1、列印集群的信息 CLUSTER INFO cluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail
  • Redis 3.0.0 RC4 發布,無 Redis Cluster 修復
    此版本包括關於 redis-cli 方面的新特性,一個使用 xterm 256 顏色的延遲光譜可視化工具。Reids 團隊計劃兩周後發布一個 RC 版本或者是 3.0.0 穩定版本。Reids 3.0.0.RC4 常規改進:* [FIX] redis-cli CSV output NIL spurious newline removed.
  • 機率大的 Redis 面試題(含答案)|內存|key|原子性|哈希|redis_網易...
    單線程的redis為什麼這麼快redis的數據類型,以及每種數據類型的使用場景,Redis 內部結構redis的過期策略以及內存淘汰機制【~】Redis 為什麼是單線程的,優點如何解決redis的並發競爭key問題Redis 集群方案應該怎麼做?都有哪些方案?有沒有嘗試進行多機redis 的部署?如何保證數據一致的?對於大量的請求怎麼樣處理Redis 常見性能問題和解決方案?
  • Redis RDB與AOF模式下的持久化原理
    前言:在此之前,如果還不了解Redis的,或者不知道怎麼使用Redis,可以參考官網網站:https://redis.io/documentation自行學習,本文主要針對Redis的核心點之一:RDB和AOF持久化模式進行展開。
  • Redis教程:Redis持久化方式
    何時執行快照出現下面的情況redis會快照內存裡的數據用戶發送bgsave命令(此時redis會fork一個子進程,子進程負責生成硬碟文件,父進程負責繼續接受命令)用戶發送save命令(和bgsave命令不同,發送save命令後,到系統創建快照完成之前系統不會再接收新的命令,換 句話說save命令會阻塞後面的命令,而bgsave不會)用戶在配置文件了配置了類似這樣的命令
  • 大數據必學:redis深入了解 Redis 的持久化機制(RDB、AOF)
    因為 redis是一個內存資料庫,所有數據都存儲在內存中,而且內存中的數據非常容易丟失,所以 redis的數據持久化就變得非常重要, redis提供了兩種數據持久化方法,分別用於 RDB和 AOF,而 redis默認用於 RDB的數據持久化方法。
  • 於正發博「我沒有diss誰的意思」 說話不走腦子躺槍的陳妍希實慘!
    於正發博「我沒有diss誰的意思」 說話不走腦子躺槍的陳妍希實慘!時間:2020-06-29 09:52   來源:中華網   責任編輯:沫朵 川北在線核心提示:原標題:於正發博我沒有diss誰的意思 說話不走腦子躺槍的陳妍希實慘! 於正曬baby小龍女扮相後秒刪回應:我沒有diss誰的意思。
  • Python使用redis存儲對象
    Python總的對象存儲到redis中默認為字符串,那麼如何存儲對象呢?下面就看看如何直接將Python中對象存儲到redis中先寫個測試redis是否正常連接上import rediscache = redis.StrictRedis('172.20.0.227',6379)
  • diss是什麼意思中文,diss網絡用語什麼意思,diss他什麼意思
    網絡上經常會看到diss這詞,例如某某diss誰,那麼這個diss是什麼意思那,為什麼會火起來,我們一起來看一下吧。diss英文的原版翻譯是對…不尊敬; 不公正地批評。現在網絡上經常說的diss是英文Disrespect (不尊重)或Disparage (輕視)的簡寫,現在說的diss某人,一般表示表示懟某人。diss最早出現在說唱; 嘻哈文化中,通過節目《中國有嘻哈》走紅,在嘻哈文化中diss表達不滿的一種歌曲形式。而當你diss一個人,對方有了回應,也會diss回來。
  • 微信附近的人,用redis也能實現?(GEO)
    相信微信附近的人的功能大家都應該用過我可以很隨意的通過我自己的定位能看到我附近的人,並且能看到那個人距離我的距離,大家有沒有思考過這個是怎麼實現的?作為一個程序猿任何問題應該都有一個思考的過程,而不是直接看結論,接下來大家一步一步的思考,直到問題解決。
  • redis - aof持久化介紹
    AOF簡介redis持久化存儲的方式有rdb序列化存儲和aof(append only file)。aof就是將操作和數據以格式化指令的方式追加到操作日誌的尾部,在append操作返回後,才進行實際的數據變更。
  • 《明日之子》曾育茗:我很作,我快樂;我diss,我道歉!
    13名選手晉級,但是在所有的選手裡面,這一位卻是被眾人diss最慘的,更被網友冠以「男版楊超越」的稱號。原本在一個靠人氣的節目裡面,也對於曾育茗來說也是十分不利的。在第一期中,曾育茗就說自己是一個很作的人,但是在他的《阿通》中,我們仿佛看到了另一個曾育茗,膽小、怯懦,但是在唱著自己的勇敢,「我想對我自己說說,你真的不錯,我的聰明不是我想要的,我一個人傷心難過。」
  • Redis如何存儲和計算一億用戶的活躍度
    2.如何滿足搜索,redis是一個鍵值對的內存結構,只能根據key來進行定位value值,無法做到像elastic search那樣對文檔進行倒排索引快速全文檢索。redis其實有這種數據結構的,可以以很少的空間來存儲大量的信息。
  • 「男版楊超越」曾育茗:我很作,我快樂;我diss,我道歉!
    13名選手晉級,但是在所有的選手裡面,這一位卻是被眾人diss最慘的,更被網友冠以「男版楊超越」的稱號。原本在一個靠人氣的節目裡面,也對於曾育茗來說也是十分不利的。在第一期中,曾育茗就說自己是一個很作的人,但是在他的《阿通》中,我們仿佛看到了另一個曾育茗,膽小、怯懦,但是在唱著自己的勇敢,「我想對我自己說說,你真的不錯,我的聰明不是我想要的,我一個人傷心難過。」
  • 詳解Redis中兩種持久化機制RDB和AOF(面試常問,工作常用)
    redis是一個內存資料庫,數據保存在內存中,但是我們都知道內存的數據變化是很快的,也容易發生丟失。幸好Redis還為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)。在這裡假設你已經了解了redis的基礎語法,某字母網站都有很好的教程,可以去看。基本使用的文章就不寫了,都是一些常用的命令。
  • Redis持久化和備份
    比如如下命令redis 127.0.0.1:6379> set key1 HelloOKredis 127.0.0.1:6379> append key1 " World!"(integer) 12redis 127.0.0.1:6379> del key1(integer) 1redis 127.0.0.1:6379> del non_existing_key(integer) 0在AOF中存儲如下$ cat appendonly.aof*2$6SELECT$10*3$3set$4key1$5Hello*3$6append$4key1$7 World
  • 楊坤再次diss《驚雷》,帶偏大眾的審美,侵蝕孩子的思想?
    關於楊坤diss《驚雷》的事情,大家都不陌生了,隨後被原創者反懟,稱楊坤所有的歌都沒有這首歌的流量高,也沒有這首歌的名氣大,言外之意就是楊坤就是嫉妒他mc六道的名氣,還對外稱存在就是合理的,隨後楊坤沒有回應,不過在17日晚上,楊坤直播的時候再次diss了《驚雷》,到底是怎麼回事呢?
  • 面試必問的 Redis:RDB、AOF、混合持久化
    我估計後面的主從複製、哨兵、集群內容也是不少,所以說實話,我也不知道之前說的3篇會拆成幾篇了  引入)  RDB的實現原理、優缺點  描述:類似於快照。默認是 everysec,在這種配置下,redis 仍然可以保持良好的性能,並且就算發生故障停機,也最多只會丟失一秒鐘的數據。  2)AOF文件是一個純追加的日誌文件。即使日誌因為某些原因而包含了未寫入完整的命令(比如寫入時磁碟已滿,寫入中途停機等等), 我們也可以使用 redis-check-aof 工具也可以輕易地修復這種問題。