Redis分散

4150 ワード


 
Redis-2.4.15は現在クラスタの機能を提供していないが、Redisの著者らはブログで3.0でクラスタメカニズムを実現すると述べた.現在Redisがクラスタを実現する方法は,主にコンシステンシハスキースライス(Shard)を用い,MemberCacheと同様に異なるkeyを異なるredis serverに割り当て,横方向拡張の目的を達成している.一般的な分散シーンについて説明します.
 
読み書き操作が比較的均一でリアルタイム性の要求が高い場合、下図の分散モードを使用することができる:読み書き操作が書き込み操作よりはるかに多い場合、下図の分散モードを使用することができる:コンシステンシハスキースライスのアルゴリズムに対して、Jedis-2.0はすでに提供されており、以下はサンプルコードを使用する(ShardedJeddisPoolを例にとる):
package com.redis.client;

import java.util.ArrayList;

import java.util.List;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisShardInfo;

import redis.clients.jedis.ShardedJedis;

import redis.clients.jedis.ShardedJedisPool;

import redis.clients.util.Hashing;

import redis.clients.util.Sharded;

 

publicclass RedisShardPoolTest {

    static ShardedJedisPoolpool;

    static{

        JedisPoolConfig config =new JedisPoolConfig();//Jedis   

        config.setMaxActive(500);//         

          config.setMaxIdle(1000 * 60);//        

          config.setMaxWait(1000 * 10);//           

          config.setTestOnBorrow(true);

        String hostA = "10.10.224.44";

          int portA = 6379;

          String hostB = "10.10.224.48";

          int portB = 6379;

        List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(2);

        JedisShardInfo infoA = new JedisShardInfo(hostA, portA);

        infoA.setPassword("redis.buy");

        JedisShardInfo infoB = new JedisShardInfo(hostB, portB);

        infoB.setPassword("redis.buy");

        jdsInfoList.add(infoA);

        jdsInfoList.add(infoB);

        pool =new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,

Sharded.DEFAULT_KEY_TAG_PATTERN);

    }

  

    /**

     * @param args

     */

    publicstaticvoid 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);

            }

        }

    }

 

    privatestaticintindex = 1;

    publicstatic String generateKey(){

        return String.valueOf(Thread.currentThread().getId())+"_"+(index++);

    }

}

実行結果から、異なるキーが異なるRedis-Serverに割り当てられていることがわかります.実際には、上記のクラスタモードには2つの問題がある:1.拡張問題:コンシステンシハッシュを使用して分割するため、異なるkeyが異なるRedis-Serverに分布し、拡張が必要な場合、分割リストにマシンを追加する必要があります.この場合、同じkeyが元の異なるマシンに計算され、ある値を取ると取れない場合があります.この場合、Redisの著者らは、Pre-Shardingという方法を提案した.Pre-Sharding方法は、各物理マシン上で、複数の異なる切断口のRedisインスタンスを実行することであり、もし3つの物理マシンがあり、各物理マシンが3つのRedis実際を実行するならば、私たちのスライスリストには実際に9つのRedisインスタンスがあり、拡張が必要な場合、1台の物理マシンを追加し、ステップは以下の通りである.A.新しい物理マシン上でRedis-Serverを実行する.B.当該Redis-Serverは、スライスリストに属するあるRedis-Server(RedisAと仮定する)に属する.C.等主従レプリケーションが完了した後、クライアントスライスリストのRedisAのIPとポートを新しい物理マシン上のRedis-ServerのIPとポートに変更する.D.RedisAを停止します.2.単点故障問題:やはりRedis主従レプリケーションの機能を使用して、2台の物理ホスト上でそれぞれRedis-Serverが運行して、その中の1つのRedis-Serverは別の従ライブラリで、デュアルマシンホットスペア技術を採用して、クライアントは仮想IPを通じて主ライブラリの物理IPにアクセスして、主ライブラリがダウンタイムした時、従ライブラリの物理IPに切り替えます.ただし、後でマスターライブラリを修復する場合は、以前のスレーブライブラリをマスターライブラリ(コマンドslabeof no oneを使用)に変更し、マスターライブラリをスレーブライブラリ(コマンドslabeofIP PORT)に変更することで、修復期間中の新規データの一貫性を保証できます.