Redis-分片

来源:http://www.cnblogs.com/houziwty/archive/2016/01/28/5167075.html
-Advertisement-
Play Games

分片(partitioning)就是將你的數據拆分到多個 Redis 實例的過程,這樣每個實例將只包含所有鍵的子集。本文第一部分將向你介紹分片的概念,第二部分將向你展示 Redis 分片的可選方案。 分片能做什麼 Redis 的分片承擔著兩個主要目標: 允許使用很多電腦的記憶體總和來支持更大的資料庫。


分片(partitioning)就是將你的數據拆分到多個 Redis 實例的過程,這樣每個實例將只包含所有鍵的子集。本文第一部分將向你介紹分片的概念,第二部分將向你展示 Redis 分片的可選方案。

分片能做什麼

Redis 的分片承擔著兩個主要目標:

  • 允許使用很多電腦的記憶體總和來支持更大的資料庫。沒有分片,你就被局限於單機能支持的記憶體容量。
  • 允許伸縮計算能力到多核或多伺服器,伸縮網路帶寬到多伺服器或多網路適配器。

分片基礎

有很多不同的分片標準(criteria)。假想我們有 4 個 Redis 實例 R0,R1,R2,R3,還有很多表示用戶的鍵,像 user:1,user:2,… 等等,我們能找到不同的方式來選擇一個指定的鍵存儲在哪個實例中。換句話說,有許多不同的辦法來映射一個鍵到一個指定的 Redis 伺服器。

最簡單的執行分片的方式之一是範圍分片(range partitioning),通過映射對象的範圍到指定的 Redis 實例來完成分片。例如,我可以假設用戶從 ID 0 到 ID 10000 進入實例 R0,用戶從 ID 10001 到 ID 20000 進入實例 R1,等等。

這套辦法行得通,並且事實上在實踐中被採用,然而,這有一個缺點,就是需要一個映射範圍到實例的表格。這張表需要管理,不同類型的對象都需要一個表,所以範圍分片在 Redis 中常常並不可取,因為這要比替他分片可選方案低效得多。

一種範圍分片的替代方案是哈希分片(hash partitioning)。這種模式適用於任何鍵,不需要鍵像 object_name: 這樣的餓形式,就像這樣簡單:

  • 使用一個哈希函數(例如,crc32 哈希函數) 將鍵名轉換為一個數字。例如,如果鍵是 foobar,crc32(foobar)將會輸出類似於 93024922 的東西。
  • 對這個數據進行取模運算,以將其轉換為一個 0 到 3 之間的數字,這樣這個數字就可以映射到我的 4 台 Redis 實例之一。93024922 模 4 等於 2,所以我知道我的鍵 foobar 應當存儲到 R2 實例。註意:取模操作返回除法操作的餘數,在許多編程語言總實現為%操作符。

有許多其他的方式可以分片,從這兩個例子中你就可以知道了。一種哈希分片的高級形式稱為一致性哈希(consistent hashing),被一些 Redis 客戶端和代理實現。

分片的不同實現

分片可由軟體棧中的不同部分來承擔。

  • 客戶端分片(Client side partitioning)意味著,客戶端直接選擇正確的節點來寫入和讀取指定鍵。許多 Redis 客戶端實現了客戶端分片。
  • 代理協助分片(Proxy assisted partitioning)意味著,我們的客戶端發送請求到一個可以理解 Redis 協議的代理上,而不是直接發送請求到 Redis 實例上。代理會根據配置好的分片模式,來保證轉發我們的請求到正確的 Redis 實例,並返迴響應給客戶端。Redis 和 Memcached 的代理 Twemproxy 實現了代理協助的分片。
  • 查詢路由(Query routing)意味著,你可以發送你的查詢到一個隨機實例,這個實例會保證轉發你的查詢到正確的節點。Redis 集群在客戶端的幫助下,實現了查詢路由的一種混合形式 (請求不是直接從 Redis 實例轉發到另一個,而是客戶端收到重定向到正確的節點)。

分片的缺點

Redis 的一些特性與分片在一起時玩轉的不是很好:

  • 涉及多個鍵的操作通常不支持。例如,你不能對映射在兩個不同 Redis 實例上的鍵執行交集(事實上有辦法做到,但不是直接這麼乾)。
  • 涉及多個鍵的事務不能使用。
  • 分片的粒度(granularity)是鍵,所以不能使用一個很大的鍵來分片數據集,例如一個很大的有序集合。
  • 當使用了分片,數據處理變得更複雜,例如,你需要處理多個 RDB/AOF 文件,備份數據時你需要聚合多個實例和主機的持久化文件。
  • 添加和刪除容量也很複雜。例如,Redis 集群具有運行時動態添加和刪除節點的能力來支持透明地再均衡數據,但是其他方式,像客戶端分片和代理都不支持這個特性。但是,有一種稱為預分片(Presharding)的技術在這一點上能幫上忙。

數據存儲還是緩存

儘管無論是將 Redis 作為數據存儲還是緩存,Redis 的分片概念上都是一樣的,但是作為數據存儲時有一個重要的局限。當 Redis 作為數據存儲時,一個給定的鍵總是映射到相同的 Redis 實例。當 Redis 作為緩存時,如果一個節點不可用而使用另一個節點,這並不是一個什麼大問題,按照我們的願望來改變鍵和實例的映射來改進系統的可用性(就是系統回覆我們查詢的能力)。

一致性哈希實現常常能夠在指定鍵的首選節點不可用時切換到其他節點。類似的,如果你添加一個新節點,部分數據就會開始被存儲到這個新節點上。

這裡的主要概念如下:

  • 如果 Redis 用作緩存,使用一致性哈希來來實現伸縮擴展(scaling up and down)是很容易的。
  • 如果 Redis 用作存儲,使用固定的鍵到節點的映射,所以節點的數量必須固定不能改變。否則,當增刪節點時,就需要一個支持再平衡節點間鍵的系統,當前只有 Redis 集群可以做到這一點,但是 Redis 集群現在還處在 beta 階段,尚未考慮再生產環境中使用。

預分片

我們已經知道分片存在的一個問題,除非我們使用 Redis 作為緩存,增加和刪除節點是一件很棘手的事情,使用固定的鍵和實例映射要簡單得多。

然而,數據存儲的需求可能一直在變化。今天我可以接受 10 個 Redis 節點(實例),但是明天我可能就需要 50 個節點。

因為 Redis 只有相當少的記憶體占用(footprint)而且輕量級(一個空閑的實例只是用 1MB 記憶體),一個簡單的解決辦法是一開始就開啟很多的實例。即使你一開始只有一臺伺服器,你也可以在第一天就決定生活在分散式的世界里,使用分片來運行多個 Redis 實例在一臺伺服器上。

你一開始就可以選擇很多數量的實例。例如,32 或者 64 個實例能滿足大多數的用戶,並且為未來的增長提供足夠的空間。

這樣,當你的數據存儲需要增長,你需要更多的 Redis 伺服器,你要做的就是簡單地將實例從一臺伺服器移動到另外一臺。當你新添加了第一臺伺服器,你就需要把一半的 Redis 實例從第一臺伺服器搬到第二台,如此等等。

使用 Redis 複製,你就可以在很小或者根本不需要停機時間內完成移動數據:

  • 在你的新伺服器上啟動一個空實例。
  • 移動數據,配置新實例為源實例的從服務。
  • 停止你的客戶端。
  • 更新被移動實例的伺服器 IP 地址配置。
  • 向新伺服器上的從節點發送 SLAVEOF NO ONE 命令。
  • 以新的更新配置啟動你的客戶端。
  • 最後關閉掉舊伺服器上不再使用的實例。

Redis 分片的實現

Redis 集群是自動分片和高可用的首選方式。當前還不能完全用於生產環境,但是已經進入了 beta 階段。

一旦 Redis 集群可用,以及支持 Redis 集群的客戶端可用,Redis 集群將會成為 Redis 分片的事實標準。

Redis 集群是查詢路由和客戶端分片的混合模式。

Twemproxy 是 Twitter 開發的一個支持 Memcached ASCII 和 Redis 協議的代理。它是單線程的,由 C 語言編寫,運行非常的快。他是基於 Apache 2.0 許可的開源項目。

Twemproxy 支持自動在多個 Redis 實例間分片,如果節點不可用時,還有可選的節點排除支持(這會改變鍵和實例的映射,所以你應該只在將 Redis 作為緩存是才使用這個特性)。

這並不是單點故障(single point of failure),因為你可以啟動多個代理,並且讓你的客戶端連接到第一個接受連接的代理。

Twemproxy 之外的可選方案,是使用實現了客戶端分片的客戶端,通過一致性哈希或者別的類似演算法。有多個支持一致性哈希的 Redis 客戶端,例如 Redis-rb 和 Predis。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 代碼在評論中。 JNI: 為什麼需要JNI: 因為android是由【JAVA & C/C++】組成。Java運行在Dalvik虛擬機中。 沒有辦法直接訪問底層硬體。底層HW相關目前技術一般都用C語言,不會用java,C速度也比較快。 怎麼從JAVA語言傳送數據到C語言中: 1. java中會調用n
  • //自動調節輸入文本框的高度 - (void)textViewDidChange:(UITableView *)textView{ float height; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { CGRe
  • 一、//觸摸空白處隱藏鍵盤 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [_feedBackTextView resignFirstResponder]; [_telTextField resignFirstRe
  • srand(seed)用來將隨機序列的起始點設為seed srand((int)time(0))表示以當前時間對應的int值為隨機序列起點,這樣每次運行程式,由於起點不同才可以得到不同的隨機數 time函數給出從1970年1月1日00:00:00至今的秒數,它必須帶一個參數,用來存儲這個秒數,tim
  • 第一篇,寫的比較詳細,新手可以看得懂: http://www.360doc.com/content/16/0128/08/30422106_531162539.shtml
  • 相比看一下枯燥乏味的對於block的講解,為什麼不從大神的代碼中領路它的使用方法呢,瞭解一下大神是如何使用block的呢,見識它的強大。https://github.com/zwaldowski/BlocksKit該項目對iOS的一些常用類進行了擴展,你可以學習到block的精髓。
  • 本文介紹一些流行的iOS的開源項目庫 1.AFNetworking 更新頻率高的輕量級的第三方網路庫,基於NSURL和NSOperation,支持iOS和OSX。https://github.com/AFNetworking/AFNetworking 2.GPUImage 圖像處理庫,基於OpenG
  • 一、簡介 Redis的replication機制允許slave從master那裡通過網路傳輸拷貝到完整的數據備份。具有以下特點: 非同步複製 可以配置一主多從 可以配置從伺服器可以級聯從伺服器,既 M->S->S M replication時是非阻塞的(在replication期間,M依然能夠處理客戶
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...