一種關(guān)于Redis使用的方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及一種數(shù)據(jù)庫使用方法技術(shù)領(lǐng)域,具體地說是一種關(guān)于Redis使用的方法。
【背景技術(shù)】
[0002]Redis是一個key-value存儲系統(tǒng)。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set —有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持pUSh/p0p、add/rem0Ve及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,Redis支持各種不同方式的排序。與memcached—樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是Redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實現(xiàn)了master-slave(主從)同步。
[0003]Redis是一個高性能的key-value數(shù)據(jù)庫。redis的出現(xiàn),很大程度補(bǔ)償了memcached這類key/value存儲的不足,在部分場合可以對關(guān)系數(shù)據(jù)庫起到很好的補(bǔ)充作用。它提供了支持Java的客戶端,使用很方便。
Redis支持主從同步。數(shù)據(jù)可以從主服務(wù)器向任意數(shù)量的從服務(wù)器上同步,從服務(wù)器可以是關(guān)聯(lián)其他從服務(wù)器的主服務(wù)器。這使得Redis可執(zhí)行單層樹復(fù)制。存盤可以有意無意的對數(shù)據(jù)進(jìn)行寫操作。由于完全實現(xiàn)了發(fā)布/訂閱機(jī)制,使得從數(shù)據(jù)庫在任何地方同步樹時,可訂閱一個頻道并接收主服務(wù)器完整的消息發(fā)布記錄。同步對讀取操作的可擴(kuò)展性和數(shù)據(jù)冗余很有幫助。
[0004]如何在服務(wù)器上更好的使用Redis是目前需要解決的問題。
【發(fā)明內(nèi)容】
[0005]本發(fā)明的技術(shù)任務(wù)是針對以上不足之處,提供一種關(guān)于Redis使用的方法,來解決如何在服務(wù)器上更好的使用Redis的問題。
[0006]本發(fā)明解決其技術(shù)問題所采用的技術(shù)方案是:
一種關(guān)于Redis使用的方法,包括如下步驟:
(1)、配置硬件環(huán)境,采用裝有Linux操作系統(tǒng)或者Windows操作系統(tǒng)的服務(wù)器;
(2)、服務(wù)器上安裝Redis;
(3)、安裝成功后,啟動Redis,再創(chuàng)建Java客戶端;
(4)、在eclipse中新建一個java項目,然后添加javaredis包引用;
(5)、Redis保存排序結(jié)果,默認(rèn)情況下,SORT操作只是簡單地返回排序結(jié)果,若需要保存排序結(jié)果,可以給STORE選項指定一個key;作為參數(shù),排序結(jié)果將以列表的形式被保存到這個key上;結(jié)果保存用EXPIRE為結(jié)果集設(shè)置生存時間,結(jié)果集為SORT操作的一個緩存;
(6)、自增一個key,得到一個自增ID,然后通過此ID創(chuàng)建對象,為對象的每個字段設(shè)置一個key,最后將新對象的ID壓入submitted.news list;
(7)、對每個想加標(biāo)簽的對象,用一個標(biāo)簽ID集合與之關(guān)聯(lián),并且對每個已有的標(biāo)簽,一組對象ID與之關(guān)聯(lián);
(8)、Redis集合和list都是可排序的;
(9)、Redis具有發(fā)布訂閱功能,一個publish客戶端的Redisclient發(fā)布消息,其他多個subscribe客戶端的redis client訂閱消息。
[0007]Redis支持以下五種數(shù)據(jù)類型:字符串(strings)、字符串列表(lists)、字符串集合(sets)、有序字符串集合(sorted sets)、哈希(hashes)。
[0008]步驟(9)中,使用JMS或者基于Redis中做如下方式使得訂閱消息持久:
①、Subscribe客戶端首先向一個Set集合中增加訂閱者ID,此Set集合保存了活躍的訂閱者ID,訂閱者ID標(biāo)記每個唯一的訂閱者,例如:sub: email, sub:web;此Set集合稱為活躍訂閱者集合;
②、subcribe客戶端開啟訂閱操作,并基于Redis創(chuàng)建一個以訂閱者ID為KEY的LIST數(shù)據(jù)結(jié)構(gòu),此LIST中存儲了所有的尚未消費(fèi)的消息;此LIST稱為訂閱者消息隊列;
③、publish客戶端,每發(fā)布一條消息之后,publish客戶端遍歷活躍訂閱者集合,并依次向每個訂閱者消息隊列尾部追加此次發(fā)布的消息;
④、發(fā)布的每一條消息,能偶持久保存在每個訂閱者消息隊列中;
⑤、subscribe客戶端,每收到一個訂閱消息,在消費(fèi)之后,刪除自己的訂閱者消息隊列頭部的一條記錄;
⑥、subscribe客戶端啟動時,若發(fā)現(xiàn)自己的訂閱者消息隊列有殘存記錄,那么將會首先消費(fèi)這些記錄,然后再去訂閱。
[0009]本發(fā)明的一種關(guān)于Redis使用的方法和現(xiàn)有技術(shù)相比,具有以下有益效果:
1、能夠在服務(wù)器上更好的使用Redis;
2、Redis具有發(fā)布訂閱功能,使用JMS或者基于Redi s中通過本發(fā)明使得訂閱消息持久。
【具體實施方式】
[0010]下面結(jié)合具體實施例對本發(fā)明作進(jìn)一步說明。
[0011]本發(fā)明的一種關(guān)于Redis使用的方法,包括如下步驟:
(1)、配置硬件環(huán)境,采用裝有Linux操作系統(tǒng)或者Windows操作系統(tǒng)的服務(wù)器;
(2)、服務(wù)器上安裝Redis;
(3)、安裝成功后,啟動Redis,再創(chuàng)建Java客戶端;
(4)、在eelipse中新建一個java項目,然后添加jredis包引用;代碼如下:
import org.jredis.*; import org.jredis.r1.alphazer0.JRedisClient; publicclass App { public static void main(String[] args) { try {JRedis
jr = new JRedisClient(^l27.0.0.1^,6379); //redis服務(wù)地址和端口號String
key = 〃mKey〃;jr.set (key, ,,hello,redis !〃);String v
=new String(jr.get(key));String k2 = 〃count〃;jr.1ncr
(k2);jr.1ncr(k2);System.0ut.println(v); System.0ut.printIn
(new String(jr.get(k2)));} catch (Except1n e) { // T0D0: handleexcept1n} } }0
[0012]Redis支持以下五種數(shù)據(jù)類型:字符串(strings)、字符串列表(lists)、字符串集合(sets)、有序字符串集合(sorted sets)、哈希(hashes)。
[0013]關(guān)于key,注意以下幾點(diǎn):(l)、key不要太長,盡量不要超過1024字節(jié),這不僅消耗內(nèi)存,而且會降低查找的效率;(2)、key也不要太短,太短的話,key的可讀性會降低;(3)、在一個項目中,key最好使用統(tǒng)一的命名模式,例如user: 10000:passwcL
[0014]下面是一個java代碼的Demo D
[0015]import java.util.Date;import java.util.HashMap;import java.util.1terator;import java.util.List;import java.util.Map;import java.util.Set;import org.junit.Test;
import redis.clients.jedis.Jedis;import redis.clients.jedis.Pipeline;import redis.clients.jedis.SortingParams;import com.wujinta0.redis.util.RedisUtil;public class TestCase {......0
[0016]不同的線程中使用相同的Jedis實例會發(fā)生奇怪的錯誤。但是創(chuàng)建太多的實現(xiàn)也不好因為這意味著會建立很多sokcet連接。也會導(dǎo)致奇怪的錯誤發(fā)生。單一Jedis實例不是線程安全的。為了避免這些問題,可以使用JedisPool,JedisPool是一個線程安全的網(wǎng)絡(luò)連接池。可以用JedisPool創(chuàng)建一些可靠Jedis實例,可以從池中拿到Jedis的實例。這種方式可以解決那些問題并且會實現(xiàn)高效的性能。
[0017](5)、Redis保存排序結(jié)果,默認(rèn)情況下,SORT操作只是簡單地返回排序結(jié)果,若需要保存排序結(jié)果,可以給STORE選項指定一個key;作為參數(shù),排序結(jié)果將以列表的形式被保存到這個key上;結(jié)果保存用EXPIRE為結(jié)果集設(shè)置生存時間,結(jié)果集為SORT操作的一個緩存;操作時,只有當(dāng)結(jié)果集過期時,才需要再調(diào)用一次SORT操作;有時候為了正確實現(xiàn)這一用法,需要加鎖以避免多個客戶端同時進(jìn)行緩存重建(也就是多個客戶端,同一時間進(jìn)行SORT操作,并保存為結(jié)果集),具體參見SETNX命令;
(6)、自增一個key,得到一個自增ID,然后通過此ID創(chuàng)建對象,為對象的每個字段設(shè)置一個key,最后將新對象的ID壓入submitted.news list;
在命令參考文檔中可以讀到所有和list有關(guān)的命令,可以刪除元素,旋轉(zhuǎn)list,根據(jù)索引獲取和設(shè)置元素,也可以用LLEN得到list的長度,部分代碼如下:public void testListStrUsage() {
String title = 〃太陽能是綠色能源4〃 ;
String url = "http://javacreazyer.1teye.com";
Jedis jedis = RedisUtil.getjedis();
long adlnfold = jedis.1ncr(〃ad:adinfo:next.1d〃);jedis.set(〃ad:adinfo:〃 + adlnfold + 〃:title〃,title);jedis.set(〃ad:adinfo:〃 + adlnfold + 〃:url〃, url);jedis.1push("ad:adinfo",String.valueOf(adlnfold));
String resultTitle = jedis.get(〃ad:adinfo:〃 + adlnfold + 〃:
title,,);
String resultUrl = jedis.get(〃ad:adinfo:〃 + adlnfold + 〃:url〃);List〈String> ids = jedis.lrange(〃ad:adinfo〃, 0, -1);
System.0ut.printIn(resultTitle);
System.0ut.printIn(resultUrl);
System.0ut.println(ids);
/#
* dbsize返回的是所有key的數(shù)目,包括已經(jīng)過期的,而redis_cli keys〃*〃查詢得到的是有效的key數(shù)目
V
System.0ut.print In (jedis.dbSizeO); jedis.flushAllO ;
} O
[0018](7)、對每個想加標(biāo)簽的對象,用一個標(biāo)簽ID集合與之關(guān)聯(lián),并且對每個已有的標(biāo)簽,一組對象ID與之關(guān)聯(lián);
例如假設(shè)我們的新聞ID:
*1000被加了三個標(biāo)簽tag I,2,5和77,就可以設(shè)置下面兩個集合:$ redis-cli sadd news:1000:tags I
木(integer) I $ redis-cli sadd news:1000:tags 2 (integer) I $ redis-cli
*sadd news:1000:tags 5 (integer) I $ redis-cli sadd news:1000:tags 77 木(integer) I $ redis-cli sadd tag:1: objects 1000 (integer) I $
redis-cli
*sadd tag:2!objects 1000 (integer) I $ redis-cli sadd tag:5!objects 1000木(integer) I $ redis-cli sadd tag:77:objects 1000 (integer) I ;
要獲取一個對象的所有標(biāo)簽,如此簡單:$ redis-cli smembers news: 1000:tags 1.5 2.1 3.77 4;而有些看上去并不簡單的操作仍然能使用相應(yīng)的Redis命令輕松實現(xiàn);例如我們也許想獲得一份同時擁有標(biāo)簽I,2,10和27的對象列表;這可以用SINTER命令來做,他可以在不同集合之間取出交集。因此為達(dá)目的我們只需:$ redis-cli sinter
木 tag:1:objects tag:2:objects tag:10:objects tag:27!objects...no
result
氺 in our dataset composed of just one object...;
(8)、Redis集合和list都是可排序的;部分代碼如下:public void testSetUsage() {
Jedis jedis = RedisUtil.getjedis();
jedis.sadd(,,zhongsou:news: 1000: tags,,,〃1〃);jedis.sadd(,,zhongsou:news: 1000: tags,,,〃2〃);jedis.sadd(,,zhongsou:news: 1000: tags,,,〃5〃);jedis.sadd(,,zhongsou:news: 1000: tags,,,〃77〃);jedis.sadd(,,zhongsou:news: 2000: tags,,,〃1〃);jedis.sadd(,,zhongsou:news: 2000: tags,,,〃2〃);jedis.sadd (,,zhongsou: news: 2000: tags,,,〃5〃);jedis.sadd (,,zhongsou