天天看點

Spring Data Redis Redis叢集---筆記5

繼續。。。

6.Redis Cluster(Redis叢集)

Redis叢集需要版本3.0+,它提供一些特性和叢集的能力,詳情參考Redis官網

注意: Redis 叢集目前隻支援 jedis和lettuce。

6.1.Enabling Redis Cluster(開啟redis叢集)

叢集支援是基于建構相同的塊作為非叢集通信。RedisClusterConnection擴充于RedisConnection。它處理叢集通訊和異常轉換成Spring DAO異常。

RedisClusterConnection是通過RedisConnectionFactory進行建立的。而RedisConnectionFactory根據RedisClusterConfiguration進行配置。

例子1:Redis 叢集的RedisConnectionFactory配置

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties {

    /*
     * spring.redis.cluster.nodes[0] = 127.0.0.1:7379
     * spring.redis.cluster.nodes[1] = 127.0.0.1:7380
     * ...
     */
    List<String> nodes;

    /**
     * Get initial collection of known cluster nodes in format {@code host:port}.
     *
     * @return
     */
    public List<String> getNodes() {
        return nodes;
    }

    public void setNodes(List<String> nodes) {
        this.nodes = nodes;
    }
}

@Configuration
public class AppConfig {

    /**
     * Type safe representation of application.properties
     */
    @Autowired ClusterConfigurationProperties clusterProperties;

    public @Bean RedisConnectionFactory connectionFactory() {

        return new JedisConnectionFactory(
            new RedisClusterConfiguration(clusterProperties.getNodes()));
    }
}
           

注意:

RedisClusterConfiguration也可以通過PropertySource進行定義。

配置屬性

spring.redis.cluster.nodes:逗号隔開分割多個host:port對

spring.redis.cluster.max-redirects:允許叢集重導的數量

提示:

初始化配置指定驅動庫去初始化叢集節點。從激活的叢集重新配置的結果隻會存在原生驅動中不會寫入到配置檔案中。

6.2. Working With Redis Cluster Connection(與redis叢集連接配接一起協作)

如上所述Redis叢集和單個節點Redi或者甚至是一個主從關系Redis環境都是不一樣的。這個原因就是Redis會自動分片。将會不同key映射到不同slot(槽)中,當然這些會分給不同的節點。是以指令在執行之前必須進行斷言是否在相同的slot(槽)内,以避免執行出現錯誤,跟進一步說,是以單個叢集節點,隻有伺服器才有keys集合單,指令下達到一個特定的伺服器,它隻傳回這個伺服器所有管理的key。這是一個非常簡單的例子擷取所有的keys。在叢集環境下達一個指令到一個伺服器,它隻會通過這個節點進行發送特定的keys,當要擷取所有的key的時候,你必須知道所有主節點。

當重定向一個特定keys到對應slot中,這個服務節點将會有driver庫進行操作。更進階的功能例如從節點中收集資訊或者發送指令到所有節點,這些都是RedisClusterConnection需要幹的活。在之前擷取keys例子,意思就是keys(pattern)方法将會擷取每個主節點,同時在每個主節點執行KEYS指令。為了僅僅是請求單一節點,RedisClusterConnection提供重載這些方法(例如 keys(node, pattern)).

一個RedisClusterNode可以通過RedisClusterConnection.clusterGetNodes擷取,或者構造函數傳入主機和端口或者節點ID

例子2.通過叢集簡單運作指令

[email protected]:7379 > cluster nodes

6b38bb... 127.0.0.1:7379 master - 0 0 25 connected 0-5460                   1      
7bb78c... 127.0.0.1:7380 master - 0 1449730618304 2 connected 5461-10922     2   
164888... 127.0.0.1:7381 master - 0 1449730618304 3 connected 10923-16383    3  
b8b5ee... 127.0.0.1:7382 slave 6b38bb... 0 1449730618304 25 connected         4 
           
RedisClusterConnection connection = connectionFactory.getClusterConnnection();

connection.set("foo", value);         5                                         
connection.set("bar", value);          6                                        

connection.keys("*");                  7                                        

connection.keys(NODE_7379, "*");         8                                      
connection.keys(NODE_7380, "*");           9                                    
connection.keys(NODE_7381, "*");          10                                     
connection.keys(NODE_7382, "*");          11                                     
           

上面序号解釋

1.主節點管理的slots 從0到5460  備份到端口為7382

2.主節點管理的slots 從5461到10922

3.主節點管理的slots 從10923到16383

4.從節點備份端口号為7379的資料

5.請求路由到節點端口7381服務的slot12182

6.請求路由到節點端口7379服務的slot5061

7.請求路由到節點端口7379,7380,7381-》[foo,bar]

8.請求路由到節點端口7379-》[bar]

9.請求路由到節點端口7380-》【】

10.請求路由到節點端口7381-》[foo]

11.請求路由到節點端口7382-》[bar]

通過slot請求 例如當所有的key映射到相同slot,MGET通過原生驅動庫将會自動擷取服務。然而一旦不是這種情況,RedisClusterConnection執行多個平行的GET指令,擷取多個節點slot的服務,最後傳回一個累計的結果。這種性能肯定沒有單個slot執行的效率高,是以在使用的時候必須小心。如果懷疑的話,請求考慮用在單個節點中 使用字首和括弧,例如{my-prefix}.foo 和 {my-prefix}.bar,他将會映射到相同的slot

例子3,跨slot請求處理案例

[email protected]:7379 > cluster nodes

6b38bb... 127.0.0.1:7379 master - 0 0 25 connected 0-5460                      
7bb...           1
           
RedisClusterConnection connection = connectionFactory.getClusterConnnection();

connection.set("foo", value);         // slot: 12182
connection.set("{foo}.bar", value);   // slot: 12182
connection.set("bar", value);         // slot:  5461

connection.mGet("foo", "{foo}.bar");                                           2

connection.mGet("foo", "bar");                                               3  
           

解釋:

1.配置如上例子一樣

2.Keys映射到相同的slot-》127.0.0.1:7381 MGET foo{foo}.bar

Keys映射到不同slots,分離到單個slot路由到對應的nodes

3.-》127.0.0.1:7379 GETbar

-》127.0.0.1:7379 GET foo

以上例子展示Spring Data Redis處理的一般政策。必須要考慮到某些操作可能會需要加載大量的資料到記憶體中。除此之外,并不是所有跨slot請求都是安全的,它也可能出現異常(例如指令PFCOUNT)。

6.3. Working With RedisTemplate and ClusterOperations(RedisTemplate叢集操作)、

對于一般RedisTemplate的一般目的,配置以及使用,請參考Working with Objects through RedisTemplate的章節。

警告:

請謹慎設定RedisTemplate#keySerializer。它使用任何json相關RedisSerializers 作為改變json結構将會立即影響到hash slot計算。

RedisTemplate通過ClusterOperations 提供特殊的操作。它可以通過RedisTemplate.opsForCluster()擷取。它允許在單個節點顯式執行指令來擷取序列化/反序列化特性。它提供進階管理指令例如Cluster MEET 或者 進階操作 例如 resharding(重新切片)

例子4. 通過RedisTemplate 擷取RedisClusterConnection

ClusterOperations clusterOps = redisTemplate.opsForCluster();
clusterOps.shutdown(NODE_7379);   1                                    
           

解釋:

1.關閉節點7379,然後從節點将會接管。

繼續閱讀