redis學(xué)習(xí)-新手入門詳解_第1頁
redis學(xué)習(xí)-新手入門詳解_第2頁
redis學(xué)習(xí)-新手入門詳解_第3頁
redis學(xué)習(xí)-新手入門詳解_第4頁
redis學(xué)習(xí)-新手入門詳解_第5頁
免費(fèi)預(yù)覽已結(jié)束,剩余25頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

文章來源 整理補(bǔ)充:redis之環(huán)境搭rediskey-valuevaluestring類型還有l(wèi)ist,setsortedsethashstring操作。比如對一個字符value追加字符串(APPEND命令)。加加或者減減一個數(shù)字字符串(INCRset(intersectionuniondifference)。memcache也有類似與一樣為了性能,redisredis可以每間隔一定時間將內(nèi)存中數(shù)據(jù)寫入到磁盤以防止數(shù)據(jù)丟失。redis也支持主從機(jī)制(master-slavereplication)。redis的其他特性地址 /files/redis-2.0目前 穩(wěn)定$tar$tarxzfredis-$cdredis-$make完后redis-2.0.4 下面啟動redis服務(wù)redis.conf是一個默認(rèn)的配置文件。我們可以根據(jù)需要使用自己的配啟動redis服務(wù)進(jìn)程后,就可以使用測試客戶端程序redis-cli和redis服務(wù)交互了.$$./redis-cli沒linux的可以通過這個的來練習(xí),當(dāng)然版的很多管理相關(guān)令是不支持的。 java /downloads/alphazero/jredis/jredis-1.0-版本目前有點(diǎn)老,支持到Redis1.2.6。版2.0的還沒 o,world程importorg.jredis.*;publicclassApp{{tryJRedisjrnewJRedisClient("5",6379redis服務(wù)地址和端Stringkey="mKey"; Stringv=newStringk2="count";}catch(Exceptione)//TODO:handle}}}redis之?dāng)?shù)據(jù)類redisstring,list,set,sortedsethashkeykeybinarysafe的字符串,所以像"mykey"和"mykey\n"這樣包含邊界字符當(dāng)成的key吧,免得被bug糾纏。另外關(guān)于key的一個格式約定介紹下,object-type:id:field。比如user:1000:password,blog:xxidxx:title,還key的長度最好不要太長。道理很明顯占內(nèi)存啊,而且查找時候相對短key也更慢。不過也不推薦過短的key,比如u:1000:pwd,這樣的。顯然沒上面的user:1000:password可讀性好。 無序集合類型redis>keysredis>keysredis>keys失敗??赡苁莖ldkey不存在或者和newkey相同

返回設(shè)置過過期時間的key的剩余過期秒數(shù)-1key不存在或者沒有設(shè)置過過期時間示成功,0stringstringredis最基本string類型是二redisstring可以包含任何數(shù)據(jù)。比如jpg或者序列化的對象。從實(shí)現(xiàn)來看其實(shí)string可以看作byte數(shù)組,最大上限是1G字節(jié)。下面是string類型的定義。struct{longlen;longfree;charbuf[];buf是個char數(shù)組用于存貯實(shí)際的字符串內(nèi)容。其實(shí)char和c#中的byte是等價的,都安全的了。因?yàn)樗举|(zhì)上就是個byte數(shù)組。當(dāng)然可以包含任何數(shù)據(jù)了。另外string類型可以被部分命令按int處理.比如incr等命令,下面詳細(xì)介紹。還有redislist,set,sortedsethash它們包含的元素與都只能是string類型。的操作比memcached多很多啊。如下:同上,如key已經(jīng)存在,返回0。nxnotexist的意思下面是個實(shí)驗(yàn),首先清空當(dāng)前數(shù)據(jù)庫,然后設(shè)置k1,k2.獲取時k3對應(yīng)返回nil.redis>dbsize(integer)0redis>mgetk1k20

個不存在的key,則設(shè)置key為1rincrkeykeyvaluerredis>redis>setoredis>appendk,world(integer)11redis>getk redis>substrk08 redis>getk list類redisliststring類型的雙向鏈表。所以[lr]push和[lr]pop命令的算法時間復(fù)雜度都是O(1)。另外list會記錄鏈表的長度。所以llen操作也是O(1).鏈表的最大長當(dāng)然可以加超時時間,超時后也會返回nil。有任務(wù)存在。當(dāng)任務(wù)來時候工作線程可以立即返回,也可以避免輪詢帶來的延遲。oklistkeylist中指定下標(biāo)的元素值,成功返回1,key或者下標(biāo)不存在返回錯誤果key對應(yīng)值不是list返回錯誤listtimeout秒,timeout0表示一直阻塞。當(dāng)阻塞時,如果有如果超時發(fā)生,則返回nil。有點(diǎn)像unixselectpoll。從srckey對應(yīng)list的尾部移除元素并添加到destkey對應(yīng)list的頭部,最后返回被移除的元素值,整個操作是原子的.如果srckey是空或者不存在返回nil。setredissetstring類型的無序集合。set元素最大可以包含(232次方-1)個元素。set的是通hashtableO(1)。hashtable會隨著添加或者刪除自可能不久后就會改用跳表(skiplist)來實(shí)現(xiàn),跳表已經(jīng)在sortedset中使用了。(intersection),差集(difference)。通過這些操作可以很容易的實(shí)現(xiàn)sns中的好友推薦和blog的tag功string元素到,key對應(yīng)的set1,如果元素已經(jīng)在集合中返回0,key對應(yīng)的set不存在返回錯誤setsetkey0

key返回所有給定key的并集返回所有給定key的差集keyset的所有元素,結(jié)果是無序的sortedsetset一樣,sortedsetstring類型元素的集合,不同的是每個元素都double類型score的被添加到hashtable中,所以給定一個元素獲取score的開銷是O(1),另一個score到元素的被添加到skiplist并按照score排序,所以就可以有序的獲取集合中的元素。添加,刪除操作O(log(N))skiplist的開銷一致,redisskiplist實(shí)現(xiàn)用的是雙向鏈表,這樣就可以逆序從尾部取元素。sortedset最經(jīng)常的使用方式應(yīng)該是作為索引來使用。我們可以把要排序的字段作為score,對象的id當(dāng)元素。memberscoreskiplist保持有序。返score同上,但是集合中元素是按score從大到小排序同上,返回結(jié)果是按score逆序的返回集合中score在給定區(qū)間的數(shù)量 刪除集合中在給定區(qū)間的元素hashredishash是一個string類型的field和value的表它的添加,刪除操作都是O(1)平均.hash特別適合用于對象。相較于將對象的每個字段存成單個string類型。將一個對象在hash類O(n),但是由于一般對象的field數(shù)量都不太多。所以使用zipmap也是很快的,也就是說添加刪除平均還是O(1)。如果field或者value的大小超出一定限制后,redis會在自動將zipmap替換成正常的hash實(shí)現(xiàn).這個限制可以在配置文件中指定。#下面介紹hash相關(guān)命令獲取指定的hashfieldhashfiled加上給定值測試指定field是否存在返回hash的所有field排序。排序命令是sort完整令格式如下:SORTSORTkey[BYpattern][LIMITstartcount][GETpattern][ASC|DESC][ALPHA][STOREsortredis>lpushredis>lpushml12(integer)1redis>lpushml11(integer)2redis>lpushml23(integer)3redis>lpushml13(integer)4redis>sort.[ASC|DESC]desc選項(xiàng),想按字母順序排可以加alpha選項(xiàng),當(dāng)然alphadesc一起用。下面是個按字母順序排的例子redis>redis>lpushmylistbaidu(integer)1redis>lpushmylist (integer)2redis>lpushmylistxhan(integer)3(integer)4redis>sort redis>sortmylist redis>sortmylistdesc [BY并按照新key中對應(yīng)的內(nèi)容進(jìn)行排序。下面的例子接著使用第一個例子中的ml集合做演示:redis>sortmlby.序的,[這個例子加上alpha,更容易理解]當(dāng)然返回的還是排序后ml集合中的元素。[GETredis>sortmlbyname*getname*redis>sortmlbyname*getname*name12name13name23name23get選項(xiàng)可以有多個??蠢觬edis>redis>sortmlbyname*getname*get redis>redis>hsetuser1namehanjie(integer)1redis>hsetuser11namehanjie(integer)1redis>hsetuser12name86(integer)1redis>hsetuser13namelxl(integer)1redis>sortmlgetuser*-[LIMITstart上面例子返回結(jié)果都是全部。limit選項(xiàng)可以限定返回結(jié)果的數(shù)量。例子redis>redis>sortmlgetname*limit1[STOREredis>sortmlgetname*limit12storecl(integer)2redis>sortmlgetname*limit12storecl(integer)2redis>lrangecl0-功能介紹完后,再下關(guān)于排序的一些問題。如果我們有多個redisserver的話,不同的key可能存在于不同的server上。比name12name13name23name23,很有可能分別在四個不serverkey,都這樣命名[name]12name]13name]11name]23client程序就會把他們都放到同一server上。還有一個問題也比較嚴(yán)重。如果要sort的集合非常大的話排序就會消耗很長時間。由于redis單制到多個slave上。然后我們只在slave上做排序操作。并進(jìn)可能的對排序結(jié)果緩存。另外就是一個方案是就是采用sortedset對需要按某個順序的集合建立索引。sadd sadd sadd sadd setuid:sort:123setuid:sort:456setuid:sort:789setuid:sort:101setuid:123setuid:456setuid:789setuid:101sorttom:friend:listbyuid:sort:*getsorttom:friend:listbyuid:sort:*getuid:*getredis對事務(wù)的支持目前還比較簡單。redis只能保證一個client發(fā)起的事務(wù)中令可以連續(xù)的執(zhí)行,而中間不會其他client令。由于redis是單線程來處理所有client的請求的所以做到一般情況下redis在接受到一個client發(fā)來令后會立即處理并返回處理結(jié)果,但是當(dāng)一個client在接中發(fā)出multi命令后,這個連接會進(jìn)入一個事務(wù)上下文,該連接后續(xù)令并不是client.然后此連接就結(jié)束事務(wù)上下文。下面可以redis>redis>redis>incraincrbexec后我們可以調(diào)用discard命令來取消一個事務(wù)。接著上面redis>redis>redis>可以發(fā)現(xiàn)這次incraincrb都沒被執(zhí)行。discard命令其實(shí)就是清空事務(wù)令隊列并退出事務(wù)上實(shí)現(xiàn)Redis事務(wù)中的CAS操作。生改變,那么整個事務(wù)將跳出,exec命令返回(nil)。下面看個例子redis>redis>1.redis>redis>除。當(dāng)然了exec,discard,unwatch命令都會清除連接中的所有監(jiān)視。 redis>lpushb5(integer)1redis>setc5redis>redis>(integer)(error)ERROperationagainstakeyholdingthewrongkindof(integer)另一個十分罕見的問題是,redis意外的掛了。很遺憾只有部分命令執(zhí)行了,后面的也就被丟棄了。當(dāng)然如果我們使用append-onlyfile方式持久化,redis會用單個writeredis之redis是一個cs模式的tcpserver使用和http類似的請求響應(yīng)協(xié)議。一個client可以通過一個socketclientredis服務(wù)處理,redis處理完后請求命令后會將結(jié)果通過響應(yīng)報文返回給client?;镜耐ㄐ胚^程如下:Server:1Server:2Server:3Server:4基本上四個命令需要8tcp報文于通信會有網(wǎng)絡(luò)延遲,假如從clientserver之間的包傳輸時間需0.125秒。那么上面的四個命令8個報文至少會需要1秒才能完成這樣即使redis的方式從client打包多條命令一起發(fā)出,不需要等待單條命令的響應(yīng)返回,而redis服務(wù)端會處理完Client:Client:INCRXClient:INCRXClient:INCRXClient:INCRXServer:1Server:Server:Server:假設(shè)不會因?yàn)閠p個tp報文就能完成四條命令,lint可以將四個in個tp報一發(fā)送,erver則可以將四條命令的處理結(jié)果放到一個tp報文返回。通過pipeine方式當(dāng)有大批量的操作時候。我們可以節(jié)省很多原來浪費(fèi)在網(wǎng)絡(luò)延遲的時間。需要注意到是用pipline方式打包命令發(fā)送,redis必須在處理完所有命前先緩存所有命令處理結(jié)。 打包 令越多,緩存消耗內(nèi)存也越多。所以并是不是打包令越多越好。具體多少合適需要根據(jù)具體情況測試。packagejredisStudy;importpackagejredisStudy;importorg.jredis.JRedis;importimportpublicclassPipeLineTest{publicstaticvoidmain(String[]args)longstart=System.currentTimeMillis();longend=System.currentTimeMillis();start=System.currentTimeMillis();end=System.currentTimeMillis();}privatestaticvoid{tryJRedisjredis=newJRedisClient("5",6379);for(inti=0;i<100000;i++){}}catch(Exceptione)}}privateprivatestaticvoid{tryConnectionSpecspec=DefaultConnectionSpec.newSpec("5",6379,0,null);JRedisjredis=newJRedisPipelineService(spec);for(inti=0;i<100000;{}}catch(Exceptione)}}}104598redis之發(fā)布訂這點(diǎn)和設(shè)計模式中的觀察者模式比較相似。pub/sub不僅僅解決發(fā)布者和訂閱者直接代碼級別耦合也解決兩者在物理部署上的耦合。redis作為一個pub/subserver,在訂閱者和發(fā)布者之間起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redisserver訂閱自己感的消息類型,clientclient可以訂閱多個channel,也可以向多個channel發(fā)送消息。單的client。代碼如下.*;importjava.io.*;publicclassPubSubTest{Stringcmd=args[0]+"\r\n";try{SocketsocketnewSocket("5",6379);InputStreamin=socket.getInputStream();OutputStreamout=socket.getOutputStream();out.write(cmd.getBytes());//發(fā)送訂閱命令byte[]buffer=newwhile(true)intreadCount= System.out.write(buffer,0,readCount); }}catch(Exceptione)}}}然后進(jìn)入while循環(huán)一直redisserver傳過來訂閱的消息。并打印到控制啟動redis-Readingmessages...(pressCtrl-cto(integer)再啟動一個redis-cliredis>redis>publishnews.share"sharealink (integer)redis>publishnews.blog"Iposta(integer)sharealinkIposta另一個redis-cli輸出如"sharealink"Iposta"成功消息,可以看出redis的協(xié)議是文本類型的,這里不解釋具體協(xié)議內(nèi)容了,可以參考或者redisclient使用psubscribe訂閱了一個使用通配符的通道(*表示任意字符串),此訂閱會收到所有與news.*匹配的通道消息。redis-cli打印到控制臺的訂閱成功消息表示使用psubscribe命令news.*成功后,連接訂閱通道總數(shù)為1clientpublishnews.sharenews.blog通道發(fā)出兩個消息后。redis返回的看完一個小例子后應(yīng)該對pub/sub功能有了一個感性的認(rèn)識。需要注意的是當(dāng)接通過subscribe或者psubscribe訂閱通道后就進(jìn)入訂閱模式。在這種模式除了再訂閱額外的通道或者用jredispub/sub支持,不過自己實(shí)現(xiàn)一個應(yīng)該也挺簡單的。整個應(yīng)用程序可以共到消息后可以根據(jù)不同的通道信息去調(diào)用不同的callback來處理。另外個人覺得redis的pub/sub還是有點(diǎn)太單?。▽?shí)現(xiàn)才用150行代碼)。在安全,認(rèn)證,可靠證持久化。redis支持兩種持久化方式,一種是Snapshotting(快照)也是默認(rèn)方式,另一種是Append-onlyfile(縮寫aof)的方式。下面分別介紹:默認(rèn)的文件名為dump.rdb。可以通過配置設(shè)置自動做快照持久化的方式。save9001#9001keysave30010#30010keysave60onwrite)父子進(jìn)共享相同的物理頁面,當(dāng)父進(jìn)程處理寫請求時os會為父進(jìn)程要修改的頁面創(chuàng)建fork時刻整個數(shù)據(jù)庫的一個快照。rdis是用一個主線程來處理所有l(wèi)intlint請求。所以不推薦使用。另一點(diǎn)需要注意的是,每次快照持久化都是將內(nèi)存數(shù)據(jù)完整寫入到磁盤一次,并io操作,可能會嚴(yán)重影響性能。后一次快照后的所有修改。如果應(yīng)用要求不能丟失任何修改的話,可以采用aof持久化方式。Append-onlyaofaof持久化方式時,redis會將每一個收到的寫write函數(shù)追加到文件中(appendonly.aof)redis重啟時會通過重新執(zhí)行文件中oswrite做的修改,所aof方式的持久化也還是有可能會丟失部分修改。不過我們可以是:每秒fsync一次)appendonly

appendfsync //完全依賴os,性能最好,持久化aofincrtest命令100次,文件中必須保存全部的100條命令,其實(shí)有99條都是多余的。因?yàn)橐謴?fù)數(shù)據(jù)庫的狀態(tài)其實(shí)文件中保存一條settest100就夠?yàn)榱藟篴of的持久化redis提供了bgrewriteaof命令。子進(jìn)程根據(jù)內(nèi)存中的數(shù)據(jù)庫快照,往臨時文件中寫入重建數(shù)據(jù)庫狀態(tài)令用命令的方式重寫了一個新的aof文件,這點(diǎn)和快照有點(diǎn)類似。redisM/Sserver相同的數(shù)據(jù)庫副本。下面是關(guān)于redis主從的一些特點(diǎn):主從不會阻塞master。也就是說當(dāng)一個或多個slave與master進(jìn)行初次同步數(shù)據(jù)時,如sort操作可以使用slave來處理,也可以用來做簡單的數(shù)據(jù)冗余。在slave上配置數(shù)據(jù)持久化M/S下面介紹下主從的過程slave服務(wù)器后,slavemastersync命令。無論是第一次同步建立的連接還是連接斷開后的重新連接,master都會啟動一個進(jìn)程,將數(shù)據(jù)庫快照保存到文件中,同時master主進(jìn)開始收集新的寫命令并緩存起來。進(jìn)程完成寫文件后,master就發(fā)從master到slave的同步數(shù)據(jù)令和從client發(fā)送令使用相同的協(xié)議格式。當(dāng)master和slaveslavemasterslave發(fā)來的同步連接命令,只會使用啟動一個進(jìn)程來寫數(shù)據(jù)庫鏡像,然后發(fā)送給所有slave。M/Sslaveofslaveof6379#masteripredis之虛擬內(nèi)尤其是對于redis這樣的內(nèi)存數(shù)據(jù)庫,內(nèi)存總是不夠用的。除了可以將數(shù)據(jù)分割到多個redisserver外。另外的能夠提高數(shù)據(jù)庫容量的辦法就是使用vm把那些不經(jīng)常的的磁盤上。如果我們的的數(shù)據(jù)總是有少部分?jǐn)?shù)據(jù)被經(jīng)常,大部分?jǐn)?shù)據(jù)很少被,對于來說確實(shí)總是只有少量用戶經(jīng)?;钴S。當(dāng)少量數(shù)據(jù)被經(jīng)常時,使用vm不但能提高單臺redisserver數(shù)據(jù)庫的容量, osredisredislist,set可能存在與多個os頁面有內(nèi)存真正耗盡時os才會交換頁面。指針和對象元數(shù)據(jù)信息。一般壓縮后的對象會比內(nèi)存中的對象小10倍。這redisvmosvm能少做很多io操作。VM vms134217728#最多使用在文件中使用多少頁面,交換文件的大小=vmsize*vmsvaluekeyvmosredis也是按頁面會選擇較老的對象。如果兩個對象一樣老會優(yōu)先交換比較大的對象,精確的公式swappability=對于vmsize的設(shè)置應(yīng)該根據(jù)自己的應(yīng)用將頁面的大小設(shè)置為可以容納大多數(shù)對象的大小。太大了會浪費(fèi)磁盤空間,太小了會造成交換文件出現(xiàn)碎片。對于交換文件中的每個頁面,redis會16M內(nèi)存用來記錄頁面空閑狀態(tài)。vm-max-threads表示用做交換任務(wù)的線程數(shù)量。如果大于0推薦設(shè)為服務(wù)器的cpucore的數(shù)量。如果是0則交換過程在主線程進(jìn)行。vm-max-threads0時(Blocking件中,并對象占用的內(nèi)存,此過一直重復(fù)直到下面條件滿足:加載時此時會阻塞所有client,然后再處理client的請求。作線程處理,主線繼續(xù)處理client請求。如果有client請求的key被換出了,主線阻塞發(fā)出命令的client,然后將加載對象的信息放這種方式只阻塞請求value被換出keyclient。blockingvm的方式。redisvm/post/redis-virtual-memory-隨著SNS 隨著SNS 的是MongoDb和Redis,因?yàn)閱渭兊腒ey-Value 雜的邏輯業(yè)務(wù),仍這兩個數(shù)據(jù)庫分別加入了一些關(guān)系性的特性,如能有效利用會有很好的效果。zset是個非常好的 value(待)排序的元素)和score(用來排序的得分依據(jù))。例如用來 榜,value可 用戶的ID,而score則是該用戶的關(guān)注數(shù)。 沒有順序的,排序計算是在獲取的時候來做的.redisTopN外面的元素,保持例如一個需要發(fā)30名的榜,我們使用的時候可以保留500名的數(shù)據(jù),防止需求變化。然后不斷的往其中添加新數(shù)據(jù),1000trim操作,將集合的元素數(shù)量壓縮成500。當(dāng)獲取前30名的時候,同樣用redis做一個緩存,緩存時間設(shè)成ps.的應(yīng)用大家一起來補(bǔ)充吧Redis指令文 連接控制QUITAUTH(僅限啟用時)簡單的驗(yàn)適合全體類型EXISTSkey1;DELkeykey,key;DELkey1key2key3KEYSpatternkey(KEYSfoo*:fookeys)RENAMEoldnamenewnamekey的名字,新鍵如果存在將被覆蓋SELECTindexMOVEkeydbindexdbindex1;0(源數(shù)據(jù)庫不存在key或目標(biāo)數(shù)據(jù)庫已存在同名key);FLUSHDB清空當(dāng)前數(shù)據(jù)庫中的所有鍵處理字符串令SETkeyvalueSETkeynamedatalengthdata(SETbruce10paitoubing:GETSETkeyvaluekeySET(SETbruce10bruce101234567890)MGETkey1key2…keyN返回多個鍵的MSETkey1value1key2value2…keyNvalueN在一次原子操作下 MSETNXkey1value1key2value2…keyNvalueN在一次原子操作下 標(biāo)鍵不存在情況下,如果有一個以上的key已存在,則失?。㊣NCRkeyINCRBYkeyintegerDECRkeyDECRBYkeyinteger處理listsRPUSHkeyvalueList(KeyLPUSHkeyvalueListLLENkeyList012LTRIMkeystartend(LTRIMtestlist02;012LSETkeyindexvalue更新某個位置元素的值匹配value的元素,返回刪除的元素數(shù)量。LPOPkeyListRPOPkeyListRPOPLPUSHsrckeydstkey_srckey__dstkey_頭部,key處理集合(sets)令(有索引無序序列testlist3\none)3\None)SPOPkeySMOVE

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論