1. 程式人生 > >Redis資料分片

Redis資料分片

Redis的分片(Sharding或者Partitioning)技術是指將資料分散到多個Redis例項中的方法,分片之後,每個redis擁有一部分原資料集的子集。在資料量非常大時,這種技術能夠將資料量分散到若干主機的redis例項上,進而減輕單臺redis例項的壓力。分片技術能夠以更易擴充套件的方式使用多臺計算機的儲存能力(這裡主要指記憶體的儲存能力)和計算能力:

(1)從儲存能力的角度,分片技術通過使用多臺計算機的記憶體來承擔更大量的資料,如果沒有分片技術,那麼redis的儲存能力將受限於單臺主機的記憶體大小。

(2) 從計算能力的角度,分片技術通過將計算任務分散到多核或者多臺主機中,能夠充分利用多核、多臺主機的計算能力。


下面將以舉例的方式說明分片技術及其存在的優勢:

示例1:未採用分片技術,有1000萬條使用者資訊資料,以鍵值對:UsrID:UsrInfo的形式儲存在一個redis例項中,此時所有的使用者資訊都會儲存在一個redis例項中,對這1000萬條資料的所有插、查、刪、該操作壓力都會集中在這個redis所在的主機上;此時所要考慮的問題不僅有儲存和操作對該主機的壓力,還有該主機失效時將導致所有操作都無法進行的問題。

示例2:採用分片技術;有1000萬條使用者資訊資料,以鍵值對:UsrID:UsrInfo的形式儲存於redis中,此時有4臺主機,每臺主機執行一個Redis例項:主機A (Redis1)、主機B(Redis2)、主機C(Redis3)、主機D(Redis4),分片時演算法為:

redis_index = 使用者的ID % 4 + 1;

例如ID為10000654則可得到到redis_index的值:10000654 % 4 + 1 = 1,即使用者10000654的資訊將被放到Redis1上,所有對使用者1000654的操作也將被分片到Redis1上;假如使用者ID以順序方式出現,這1000萬條使用者資訊將被平均分配到這四臺主機的各Redis例項上。

採用分片演算法


採用分片之後,資料將被分散到4個redis例項中,對資料的操作也被分散到每個redis例項中,此時單臺主機的壓力將大大減輕。

分片的部署,即例項2中分片演算法被放在哪裡?是在分片時需要首先考慮的問題,分片部署方式一般分為以下三種:

(1)在客戶端做分片;這種方式在客戶端確定要連線的redis例項,然後直接訪問相應的redis例項;

(2)在代理中做分片;這種方式中,客戶端並不直接訪問redis例項,它也不知道自己要訪問的具體是哪個redis例項,而是由代理轉發請求和結果;其工作過程為:客戶端先將請求傳送給代理,代理通過分片演算法確定要訪問的是哪個redis例項,然後將請求傳送給相應的redis例項,redis例項將結果返回給代理,代理最後將結果返回給客戶端。


(3)在redis伺服器端做分片;這種方式被稱為“查詢路由”,在這種方式中客戶端隨機選擇一個redis例項傳送請求,如果所請求的內容不再當前redis例項中它會負責將請求轉交給正確的redis例項,也有的實現中,redis例項不會轉發請求,而是將正確redis的資訊發給客戶端,由客戶端再去向正確的redis例項傳送請求。

上面主要描述了分片的優點,當然分片的存在也有缺陷,例如:

(1) 通常無法支援涉及多鍵的操作;在redis中有很多一次操作多個key的操作,例如求集合交集的SINTER操作,該操作將涉及到多個鍵,而這多個鍵有可能被分片到不同的redis例項中,此時就無法執行這種操作。

(2)Redis的事務操作中涉及多個鍵時也不能用;

(3)分片將導致資料處理更加複雜;例如在分片過程中,隨著redis例項的增加,資料備份等操作都將會變得更加複雜。

(4)Redis目前不支援動態分片操作,擴容和縮容操作都會比較複雜,尤其分片操作部署在客戶端時,需要重新配置和啟動客戶端。在使用過程中縮容用的不多,擴容可以採用後面介紹的預分片策略來緩解此問題。

預分片技術

因為使用了一致性哈稀進行分片,那麼不同的key分佈到不同的Redis-Server上,當我們需要擴容時,需要增加機器到分片列表中,這時候會使得同樣的key算出來落到跟原來不同的機器上,這樣如果要取某一個值,會出現取不到的情況。而且在正常運營環境中,一般所儲存的資料會逐漸增加,可能今天只要10個redis例項就能應付,但是到了一年以後就需要50個redis例項才能支撐,因此,redis的擴容是經常用到的功能,在redis的分散式部署中,有預分片技術是非常好用的方法之一;


預分片技術是指在開始時就啟動足夠多的redis例項(例如32或64個,估計一下夠以後擴充套件用就行了),等到後續需要擴容的時候,只需要將其中一部分的redis例項轉移到新增加的機子上即可,在redis例項遷移過程中使用redis的複製功能可以最大限度的降低redis的停工時間甚至可以做到沒有停工時間。由於redis例項是輕量級的程序,而且佔用記憶體較少,這裡指單純的空的redis例項,一個空的redis例項大約佔用1M的記憶體;因此,這種方式即不會佔用太多系統開銷,又便於實現;

Redis的預分片技術可以按照以下步驟進行例項遷移操作:

(1)在新機子上啟動新的redis例項;

(2)將新redis例項作為slave將原redis例項作為master,將資料從原redis例項遷移到新redis例項上;

(3)停止客戶端(分片操作在客戶端上時)或代理伺服器(分片操作在代理上)

(4)更新客戶端或者代理伺服器中的配置資訊,去掉被遷移的原redis例項的ip和埠等資訊,加上新啟動redis例項的IP地址和埠;

(5)向新啟動的redis傳送SLAVEOF NOONE命令,終止新redis例項對原redis例項的從屬關係;

(6)重啟客戶端程式或者代理程式,此時它們將會使用新的redis例項;

(7)關掉被遷移走資料的原redis例項;

Jedis分片連線池

1. 部署2個Redis master節點。

2. 用ShardedJedisPool連線Redis maser節點,並將資料根據一致性雜湊演算法存放到不同的master節點,從而達成資料分片。

客戶端程式碼如下:

public class RedisShardPoolTest {
    static ShardedJedisPool pool;
    static{
        JedisPoolConfig config =new JedisPoolConfig();//Jedis池配置
        config.setMaxActive(500);//最大活動的物件個數
          config.setMaxIdle(1000 * 60);//物件最大空閒時間
          config.setMaxWait(1000 * 10);//獲取物件時最大等待時間
          config.setTestOnBorrow(true);
        String hostA = "10.7.12.52";
          int portA = 6379;
          String hostB = "10.7.112.52";
          int portB = 6379;
        List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(2);
        JedisShardInfo infoA = new JedisShardInfo(hostA, portA);
        infoA.setPassword("redis.360buy");
        JedisShardInfo infoB = new JedisShardInfo(hostB, portB);
        infoB.setPassword("redis.360buy");
        jdsInfoList.add(infoA);
        jdsInfoList.add(infoB);
       
        pool =new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,
Sharded.DEFAULT_KEY_TAG_PATTERN);
    }
   
    /**
     * @param args
     */
    public static void main(String[] args) {
        for(int i=0; i<100; i++){
           String key =generateKey();
           //key += "{aaa}";
           ShardedJedis jds =null;
           try {
               jds =pool.getResource();
               System.out.println(key+":"+jds.getShard(key).getClient().getHost());
               System.out.println(jds.set(key,"1111111111111111111111111111111"));
           }catch (Exception e) {
               e.printStackTrace();
           }
           finally{
               pool.returnResource(jds);
           }
        }
    }
 
    private static int index = 1;
    public static String generateKey(){
        return String.valueOf(Thread.currentThread().getId())+"_"+(index++);
    }
}
通過執行結果會發現這100條資料會被分開存放到10.7.12.52和10.7.112.52機器上的master節點中,檢視原始碼會發現jds.set(key,value)方法會呼叫jds.getShared(key)來根據key的hash值來獲取該key應該存放到那個節點上。

相關推薦

Redis資料分片處理(六)

Redis分片處理(twemproxy代理機制) 代理元件:twemproxy 不管你現在的電腦效能有多好,只要你運行了Redis,那麼就有可能造成一種可怕的局面,你電腦的記憶體將立刻被佔滿。而且一臺Redis資料庫的效能終歸是有限制的,那麼現在如果要保證使

Redis資料分片

Redis的分片(Sharding或者Partitioning)技術是指將資料分散到多個Redis例項中的方法,分片之後,每個redis擁有一部分原資料集的子集。在資料量非常大時,這種技術能夠將資料量分散到若干主機的redis例項上,進而減輕單臺redis例項的壓力。

Redis資料分片以及擴容

投稿介紹:xiaotianqio,資深linux菜鳥程式設計師,搜尋系統磚家,曾混跡於百度的網際網路吊絲。剛開始接觸Redis,大言不慚,聊卿一讀。 場景 一開始資料比較少,一臺伺服器的記憶體就足夠,因此一個Redis 就能滿足需求,但是隨著業務發展,資料量變大,可能需要在

資料學習之路103-redis分片代理

哨兵的出現是為了實現主節點的HA,那麼從節點會不會出現問題呢? 假如所有的讀取操作都在從節點6380上,那麼6380節點就會很累,而6381節點就會很清閒。 這個時候就需要負載均衡,我們這裡的負載均衡需要通過代理伺服器來實現。我們可以將需要訪問的從節點的位置配置在代理伺服器上。

高階開發不得不懂的Redis Cluster資料分片機制

Redis 叢集簡介 Redis Cluster 是 Redis 的分散式解決方案,在 3.0 版本正式推出,有效地解決了 Red

Redis Cluster 的資料分片機制

上一篇《分散式資料快取中的一致性雜湊演算法》 文章中講述了一致性雜湊演算法的基本原理和實現,今天就以 Redis Cluster 為例,詳細講解一下分散式資料快取中的資料分片,上線下線時資料遷移以及請求重定向等操作。 Redis 叢集簡介 Redis Cluster 是 Redis 的分散式解決方案,在

在 Istio 中實現 Redis 叢集的資料分片、讀寫分離和流量映象

Redis 是一個高效能的 key-value 儲存系統,被廣泛用於微服務架構中。如果我們想要使用 Redis 叢集模式提供的高階特性,則需要對客戶端程式碼進行改動,這帶來了應用升級和維護的一些困難。利用 Istio 和 Envoy ,我們可以在不修改客戶端程式碼的前提下實現客戶端無感知的 Redis Clu

Redis基礎篇(八)資料分片

現在有一個場景:要用Redis儲存5000萬個鍵值對,每個鍵值對大約是512B,要怎麼部署Redis服務呢? 第一個方案,也是最容易想到的,需要儲存5000萬個鍵值對,每個鍵值對約為512B,一共需要25GB空間,選擇一臺32GB記憶體的用品來部署Redis,還剩餘7GB空間,可以採用RDB對資料做持續久。

redis學習(二) redis資料結構介紹以及常用命令

redis資料結構介紹   我們已經知道redis是一個基於key-value資料儲存的資料結構資料庫,這裡的key指的是string型別,而對應的value則可以是多樣的資料結構。其中包括下面五種型別:   1.string 字串    string字串型別是redis最基礎的資料儲存型別。

分散式系統之資料分片前言2

轉載:https://www.cnblogs.com/xybaby/p/7076731.html 目錄 三種資料分片方式 hash方式: 一致性hash  range based 小結: 分片特徵值的選擇

分散式系統之資料分片前言1

轉載:https://www.cnblogs.com/xybaby/p/7076731.html 目錄 寫在前面 帶著問題出發 資料分片 資料冗餘 其他 總結: 正文   很長一段時間,對分散式系統都比較感興趣,也

深入剖析Redis系列(八) - Redis資料結構之集合

前言 集合(set)型別也是用來儲存多個 字串元素,但和 列表型別 不一樣的是,集合中 不允許有重複元素,並且集合中的元素是 無序的,不能通過 索引下標 獲取元素。 如圖所示,集合 user:1:follow 包含著 "it"、"music"、"his"、"sports

Redis資料型別基本操作

String型別:   設定鍵值對: set key value    設定鍵值對和過期時間:setex key seconds value ( 以秒為單位 )   設定多個鍵值對: mset key1 value1 key2 value2    給已有鍵的值追加: ap

redis介紹、redis安裝、redis持久化、redis資料型別

一:redis介紹 Redis和Memcached類似,也屬於k-v資料儲存Redis官網redis.io, 當前最新穩定版4.0.1支援更多value型別,除了和string外,還支援hash、lists(連結串列)、sets(集合)和sorted sets(有序集合)redis使用了兩種檔案格式:全量資

Redis資料結構-string

Redis的5種資料結構:string、list、hash、set和zset 基本操作 1、string表示的是一個可變的位元組陣列; 2、Redis的字串時動態字串,是可以修改的; 3、內部結構實現上類似與Java的ArrayList,用預分配冗餘空間的方式來減少記憶體的頻繁分配;

Redis資料結構:點陣圖

原文:https://scalegrid.io/blog/introduction-to-redis-data-structure-bitmaps/ 點陣圖(也稱為位陣列,位向量等)是緊湊儲存位的陣列資料結構。它可以用來實現一個簡單的集資料結構。位陣列可以有效地利用硬體中的位級並行性來快速執行操

redis - 通俗易懂的Redis資料結構基礎教程

通俗易懂的Redis資料結構基礎教程 Redis有5個基本資料結構,string、list、hash、set和zset。它們是日常開發中使用頻率非常高應用最為廣泛的資料結構,把這5個數據結構都吃透了,你就掌握了Redis應用知識的一半了。 string   首先我們從

002-redis-資料型別

Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。 使用桌面工具檢視,預設有16個庫,Redis支援多個數據庫,並且每個資料庫的資料是隔離的不能共享,並且基於單機才有,如果是叢集就沒有資料庫的概念。   &nb

redis 第 9 篇 Redis資料型別----Keys命令

Keys命令  常用命令 keys 返回滿足給定pattern 的所有key redis 127.0.0.1:6379> keys mylist* 1) "mylist" 2) "mylist5" 3) "mylist6" 4) "mylis

redis 第 8 篇 Redis資料型別----Sortedset

Sortedset Sortedset又叫zset   Sortedset是有序集合,可排序的,但是唯一。   Sortedset和set的不同之處,是會給set中的元素新增一個分數,然後通過這個分數進行排序。   命令