Java連線Redis (key-value儲存系統)

九天高遠發表於2013-08-19

Redis簡介:

redis是一個效能非常優秀的記憶體資料庫,透過key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set --有序集合)和hashs(雜湊型別)。這些資料型別都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是快取在記憶體中。區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。
Redis 是一個高效能的key-value資料庫。 redis的出現,很大程度補償了memcached這類key/value儲存的不足,在部 分場合可以對關聯式資料庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。redis的安裝配置,比較簡單,詳見官方網站。

在多執行緒下使用Jedis 

在不同的執行緒中使用相同的Jedis例項會發生奇怪的錯誤。但是建立太多的實現也不好因為這意味著會建立很多sokcet連線,也會導致奇怪的錯誤發生。單一Jedis例項不是執行緒安全的。為了避免這些問題,可以使用JedisPool, JedisPool是一個執行緒安全的網路連線池。可以用JedisPool建立一些可靠Jedis例項,可以從池中拿到Jedis的例項。這種方式可以解決那些問題並且會實現高效的效能. 
初始化JedisPool 

JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");

可以以靜態的方式處理以上程式碼,它是執行緒安全的. 

static {
        pool = new JedisPool(new Config(), "host", 6379);
    }

JedisPoolConfig包含了許多有用的redis指定的連線池的預設引數。比如,如果一個連線300秒內沒有任何的返回Jedis將關閉這個連線. 

可以這樣使用:

Jedis jedis = pool.getResource(); 
try { 
   //隨便做一些對於redis的操作 
   jedis.set("foo", "bar"); 
   String foobar = jedis.get("foo"); 
   jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");  
   Set<String> sose = jedis.zrange("sose", 0, -1); 
 } finally { 
   //這裡很重要,一旦拿到的jedis例項使用完畢,必須要返還給池中 
   pool.returnResource(jedis); 
 } 
 //程式關閉時,需要呼叫關閉方法 
 pool.destroy();

設定主/從分佈 

啟用同步複製 
Redis主要為了主/從分佈而構建。這意味著"write"請求必須要指向"master", "master"會同步複製改變的內容到"slave". "read"請求可以(不是必須的)被指向"slave",緩解"master"的讀寫壓力. 
可以按以下的步驟使用"master". 為了啟用同步複製,有兩個方式去告訴"slave"將"slaveOf"到一個給定的"master":   1.在redis server的config檔案(redis.conf)指明   2.在拿到的jedis例項中呼叫"slaveOf"方法並指定IP和埠 

jedis.slaveOf("192.168.1.35", 6379);

注意:"slave"也是一個redis server,也可以接收"write"請求並不會報錯,但是改變不會被同步複製,所以如果弄反了jedis的例項則一些操作會被覆蓋. 
禁用同步複製/master失敗後,提升slave 
如果"master"down掉,可以提升"slave"成為新的"master".首先試著禁用同步複製離線的"master",如果有幾個"slave",啟用同步複製其餘的"slave"到新的"master". 

slave1jedis.slaveofNoOne(); 
slave2jedis.slaveOf("192.168.1.36", 6379);

因為自己在使用Hadoop做join的時候,小表也很大,導致記憶體爆滿,所以打算用Redis來看看。把資料加入Redis的程式碼如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException; 

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisInutAccount {

    private static String parseRaw(String str) {
        if (str==null) {
            return "";
        }
        str = str.trim();
        if (str.startsWith("\"")) {
            str = str.substring(1);
        }
        if (str.endsWith("\"")) {
            str = str.substring(0, str.length() - 1);
        }
        return str;
    }

    public static void main(String[] args) throws IOException {
        JedisPool pool = new JedisPool("192.168.2.101", 6379);
        Jedis jedis = pool.getResource();
 
        jedis.flushAll();
 
        File file = new File("sample_account.del");
        FileReader is = new FileReader(file);
        BufferedReader br = new BufferedReader(is);
        String tmp = null;
        while ((tmp = br.readLine()) != null) {
            System.out.println(tmp);
            jedis.set(parseRaw(tmp), "1");
        }
        br.close();
      pool.returnResource(jedis);
      pool.destroy();
  
    }
}

 

 

相關文章