這篇文章帶大家了解Redis中的Codis,介紹一下Codis原理,希望對大家有幫助!
場景
在大數據高並發場景下,使用單一redis實例,即使redis的效能再高,也會變的非常吃力,
首先,資料量越大,redis佔用記憶體就越大,進一步導致rdb檔案過大,這種情況會使的主從全量同步時間過長,同時實例重啟時,載入過大的rdb也會讓啟動時間變長。 【相關推薦:Redis影片教學】
其次在CPU的使用上,單一實例的Redis只能使用一個CPU核心,一個核心應多過多的數據,也會顯得力不從心,
因此需要一個叢集方案,將巨大的資料量由一台實例分散到多台實例上,從Redis流行到官方支援自己的Cluster方案之間,第三方也在自己開發支持叢集的元件,Codis就是其中之一,
Codis使用Go語言開發,在Redis與客戶端中間充當代理的角色,使用Redis協議,所以客戶端直接連接Codis,向其發送指令即可,Codis負責轉送指令給Redis,最後接收回傳結果再回傳給客戶端,
Codis代理程式的Redis實例構成一個Redis集群,當叢集空間也不足以使用時,可以動態擴容,繼續增加Redis實例,同時,客戶端使用的sdk不需要做任何改動,只需由原來的連接redis改成連接codis即可,
Codis自身也可以採取一個集群,來確保自身的高可用,由於其本身就是無狀態的,只負責轉發內容,增加多個Codis沒有副作用還可以保證QPS的提高,當其中一個Codis掛掉時,還可以使用別的。
原理
Codis將特定的Key轉送到特定的Redis實例,叢集中每個實例都保存一部分Key,降低其他實例的壓力,同時所有實例的資料加起來,就是一份完整的資訊。
Codis預設劃分了1024個插槽(slot),叢集中的每個Redis實例對應一部分槽位,Codis會在記憶體中維護槽位與Redis實例的對應關係,
槽位的數量預設是1024,可以更改,如果叢集節點比較多,可以將數字調大。
當接收到客戶端發送過來的key時,Codis對該key進行crc32 運算得出一個hash 值,
再將hash 後的整數值對1024(槽位數) 進行取模得到一個餘數,該餘數就是Key將被保存到的槽位,有了槽位就可以找到這個key該發到哪個redis實例上了。
偽代碼:
hash = crc32(command.key) # 计算hash值 slot = hash % 1024 # 取模得到槽位 redisInstance = slots[slot].redis # 得到redis实例 redis.do(command) # 执行命令复制代码
群集插槽同步
Redis與槽位的對映關係存在Codis的記憶體當中,因此Codis叢集需要考慮確保每個節點中的槽位映射關係同步,所以Codis採用Zookeeper、Etcd 分散式配置儲存中間件來持久化槽位映射關係,確保Codis叢集之間的資料同步,
如下圖,Codis將插槽關係存在Zookeeper中,並提供了一個Dashboard 觀察與修改槽位關係,當發生改變時,Codis Proxy 監聽到變化並重新同步槽位關係。
拓容
#當現有叢集也不滿足業務需求時,就需要新增實例加入的叢集中,此時槽位映射關係需要重新分配,需要分配一部分的插槽給新節點。
Codis新增了一個SLOTSSCAN 指令,可以遍歷指定slot下的所有key,透過該指令掃描出待遷移槽位的所有key,然後挨個遍歷每個key遷移到新節點中,
遷移過程中,Codis繼續對外提供服務,此時來了一個請求打在了正在遷移的槽位上,由於該槽位現在對應新老兩個節點,此時Codis 無法判斷該key 有沒有從舊節點中遷移到新節點上,
因此這種情況Codis 會立即強制對當前的key 進行單一遷移,遷移完成後,將請求轉發給新的Redis實例上。
偽代碼:
slot_index = crc32(command.key) % 1024 if slot_index in migrating_slots: doMigratingKey(command.key) redis = slots[slot_index].new_redis else: redis = slots[slot_index].redis复制代码
SLOTSSCAN 與Redis本身的Scan指令一樣,無法避免掃描出來的資料重複,但這不會影響到遷移的正確性,因為單一key遷移之後,就立刻從舊實例中刪除了,無法再被掃描出來。
自動均衡槽位
#每次新增實例,如果都需要人工維護slot的映射關係太麻煩,Codis提供自動均衡,該功能會在系統比較空閒的時候觀察每個Redis實例對應的slot數量,如果不平衡,就進行自動均衡,遷移資料的操作。
缺點
Codis為Redis帶來擴容好處,但也造成了一些副作用。
不支援交易
一個交易可能對多個key做了操作,但交易只能在單一實例中完成,但是由於key分散在不同的實例中,因此Codis無法支援事務操作。
不支援rename
rename將一個key命名成另一個key,但是這兩個key可能hash出來的插槽並不是同一個,而是在不同實例的插槽上,因此rename也不被支援。
官方提供的不支援的指令清單:https://github.com/CodisLabs/codis/blob/master/doc/unsupported_cmds.md
##擴容卡頓
Codis在擴容過程中,對資料的遷移是將整個key直接遷移過去的,例如一個hash結構,Codis會直接hgetall 拉取所有的內容,使用hmset 放到新節點中,如果該hash的內容過大,將會引起卡頓,官方建議單一集合結構的總大小不超過1MB,在業務上可以透過分桶儲存等,將大型資料拆成多個小的,做一個折中。網路開銷
由於Codis 在客戶端與Redis實例之間充當網路Proxy,多了一層,網路開銷自然多一些,比直接連接Redis的性能要稍低一些。中間件運維開銷
Codis叢集配置需要使用Zk或Etcd,這表示引入Codis叢集又要引入其他中間件,增加運維機器資源成本。優點
Codis將分散式一致性的問題交給了第三方(ZK或Etcd)負責,省去了這方面的維護工作,降低實現代碼的複雜性,Redis官方的Cluster為了實現去中心化,引入了Raft與Gossip協議,以及大量需要調優的配置參數,複雜度驟增。批次取得
對於批次操作,例如使用mget 取得多個key的值,這些key可能分散在多個實例中, Codis將key依照所在的實例分組,然後對每個實例挨個呼叫mget,最後匯總傳回給客戶端。其他功能
#Codis 提供Dashboard 介面化,以及Codis-fe 對叢集進行管理,還可以進行增加分組、節點、執行自動均衡等操作,查看slot 狀態以及slot 對應的redis 實例,這些功能使的運維更加方便輕鬆。##走向歷史Codis是為了彌補Redis官方沒有提供集群這一概念時出現的,現在Redis官方提供Cluster功能,官方的支持自然比第三方的更有優勢,### ###同時第三方軟體也需要即時關注官方發布的新特性各種,而Cluster肯定是即時相容新特性,因此更推薦使用官方的Cluster,Codis作為曾經的一個知識點了解,某些想法與Cluster是有重合的。 ######更多程式相關知識,請造訪:###程式設計入門###! ! ###
以上是深入了解Redis中的Codis的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Redis的關鍵特性包括速度、靈活性和豐富的數據結構支持。 1)速度:Redis作為內存數據庫,讀寫操作幾乎瞬時,適用於緩存和會話管理。 2)靈活性:支持多種數據結構,如字符串、列表、集合等,適用於復雜數據處理。 3)數據結構支持:提供字符串、列表、集合、哈希表等,適合不同業務需求。

Redis的核心功能是高性能的內存數據存儲和處理系統。 1)高速數據訪問:Redis將數據存儲在內存中,提供微秒級別的讀寫速度。 2)豐富的數據結構:支持字符串、列表、集合等,適應多種應用場景。 3)持久化:通過RDB和AOF方式將數據持久化到磁盤。 4)發布訂閱:可用於消息隊列或實時通信系統。

Redis支持多種數據結構,具體包括:1.字符串(String),適合存儲單一值數據;2.列表(List),適用於隊列和棧;3.集合(Set),用於存儲不重複數據;4.有序集合(SortedSet),適用於排行榜和優先級隊列;5.哈希表(Hash),適合存儲對像或結構化數據。

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

Redis 集群中使用 zset:zset 是一種有序集合,將元素與評分關聯。分片策略: a. 哈希分片:根據 zset 鍵的哈希值分佈。 b. 範圍分片:根據元素評分劃分為範圍,並將每個範圍分配給不同的節點。讀寫操作: a. 讀操作:如果 zset 鍵屬於當前節點的分片,則在本地處理;否則,路由到相應的分片。 b. 寫入操作:始終路由到持有 zset 鍵的分片。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用