Redis特性和應用場景
Redis特性
速度快
Redis使用標準C編寫實現,而且將所有資料載入到記憶體中,所以速度非常快。官方提供的資料表明,在一個普通的Linux機器上,Redis讀寫速度分別達到81000/s和110000/s。
資料結構
可以將Redis看做“資料結構伺服器”。目前,Redis支援5種資料結構。
持久化
由於所有資料保持在記憶體中,所以對資料的更新將非同步地儲存到磁碟上,Redis提供了一些策略來儲存資料,比如根據時間或更新次數。資料超過記憶體,使用swap,保證資料;
memcacache不能持久化,mongo是部分在記憶體;
自動操作
Redis對不同資料型別的操作是自動的,因此設定或增加key值,從一個集合中增加或刪除一個元素都能安全的操作。
支援多種語言
Redis支援多種語言,諸如Ruby,Python, Twisted Python, PHP, Erlang, Tcl, Perl, Lua, Java, Scala, Clojure等。
主-從複製
Redis支援簡單而快速的主-從複製。
官方提供了一個數據,Slave在21秒即完成了對Amazon網站10Gkey set的複製。
Sharding
很容易將資料分佈到多個Redis例項中,但這主要看該語言是否支援。目前支援Sharding功能的語言只有PHP、Ruby和Scala。
1. redis資料使用方式
redis 的作者antirez曾笑稱其為一個數據結構伺服器(data structures server
Redis的幾種使用方式
Redis的七種特性以及適合的應用場景:
1.1. Strings
Strings 資料結構是簡單的key-value型別,value其實不僅是String,也可以是數字。使用Strings型別,完全實現目前 Memcached 的功能,並且效率更高。還可以享受Redis的定時持久化,操作日誌及 Replication等功能。除了提供與 Memcached 一樣的get、set、incr、decr 等操作外,Redis還提供了下面一些操作:
- 獲取字串長度 strlen
- 往字串append內容 append
- 設定和獲取字串的某一段內容 setrange getrange
- 設定及獲取字串的某一位getrange
- 批量設定一系列字串的內容
String是最簡單的資料型別,一個key對應一個Value,String是二進位制安全的。它可以包含任何資料,圖片或者其他序列化後的物件
方法 |
說明 |
特性 |
set |
設定key對應的的值為String型別的value |
|
get |
獲取對應key對應的String的值,如果不存在返回nil |
|
setnx |
設定可以為對應的值為String型別的value,如果key存在返回0不覆蓋,不存在返回1 |
nx的意思為not exist Set the value of a key, only if the key does not exist |
setex |
置key對應的值為String型別的value,並指定此鍵值對應的有效期 SETEX key seconds value |
例:setex mykey 10 你好 |
setrange |
設定key的value的子字串 |
setrange key 位置 替換的內容 如果替換內容沒有原value長,則原value剩餘的內容將被保留 |
mset |
一次設定多個key的值,成功返回ok,失敗返回0,要成功都成功,要不成功全部失敗。 |
mset key1 內容一 key2 內容二 |
msetnx |
一次設定多個key的值,成功返回ok,失敗返回0,不覆蓋已經存在的值,要成功都成功,要失敗都失敗。 |
|
getset |
設定key的值並返回key的舊值 |
getset key newValuse |
getrange |
獲取key對應的value子字串 |
getrange key 0 5 //獲取前6個字元 |
mget |
批量獲取 |
mget key1 key2 key3 //沒有設定則返回空 |
incr |
對key的值做增加操作,並返回新的值 |
+1 |
incrby |
對可以的value加指定的值, |
key如果不存在會設定key並value為0 incrby key1 5 //對key1的值加5 |
decr |
對key的值做減減操作 |
-1 |
decrby |
對key的值減去指定值 |
|
append |
給指定key的字串追加value,返回新的字串長度 |
|
strlen |
取指定key的value值的長度 |
|
1.2. Hashs
在Memcached中,我們經常將一些結構化的資訊打包成hashmap,在客戶端序列化後儲存為一個字串的值,比如使用者的暱稱、年齡、性別、積分等,這時候在需要修改其中某一項時,通常需要將所有值取出反序列化後,修改某一項的值,再序列化儲存回去。這樣不僅增大了開銷,也不適用於一些可能併發操作的場合(比如兩個併發的操作都需要修改積分)。而Redis的Hash結構可以使你像在資料庫中Update一個屬性一樣只修改某一項屬性值。
它是一個String型別的field和value的對映表,它的新增和刪除都是平均的,hash特別適合用於儲存物件,對於將物件儲存成字串而言,hash會佔用更少的記憶體,並且可以更方便的存取整個物件. 它和java的HashMap完全類似
方法 |
說明 |
特性 |
hset |
設定一個hash 的field為指定值,如果key不存在則先建立 |
hset tab ke1 val1 |
hget |
獲取某個hash的某個field值 |
hget tab ke1 |
hsetnx |
類似string只是操作的是hash |
|
hmset |
批量設定hash的內容 |
|
hmget |
獲取hash表的全部key值 |
Hmget key field1 field2 |
hincrby |
給hash表的某個欄位增加值 |
|
hexists |
判斷hash表中某個key是否存在 |
|
hlen |
返回hash表中的key數量 |
|
hdel |
刪除指定hash表的某個鍵值對 |
|
hkeys |
返回hash表中所有的key |
|
hvals |
返回hash表中所有的value |
|
hgetall |
獲取hash表中所有key和value |
|
1.3. Lists
Lists 就是連結串列,略有資料結構知識的人都應該能理解其結構。使用Lists結構,我們可以輕鬆地實現最新訊息排行等功能。Lists的另一個應用就是訊息佇列,可以利用Lists的PUSH操作,將任務存在Lists中,然後工作執行緒再用POP操作將任務取出進行執行。Redis還提供了操作Lists中某一段的api,你可以直接查詢,刪除Lists中某一段的元素。
Redis的list是每個子元素都是String型別的雙向連結串列,可以通過push和pop操作從列表的頭部或者尾部新增或者刪除元素,這樣List即可以作為棧,也可以作為佇列。
方法 |
說明 |
特性 |
lpush |
在key所對應的list頭部新增一個元素 |
l的意思是left |
rpush |
在key說對應的list尾部新增一個元素 |
r的意思是right |
lrange |
顯示list裡面的內容 |
lrange 0 -1 //全部顯示 |
linsert |
在key對應的list |
linsert mylist before one myvalue |
lset |
設定list中指定下標元素的值 |
lset mylist index myvalue |
lrem |
從key對應的list中刪除n個和value相同的元素,結果返回影響元素的個數,n<0從尾部開始刪除,n=0全刪除 |
lrem mylist count "value" |
ltrim |
保留指定key範圍內的資料,返回ok成功 |
ltrim mylist 0 3 //0-3是保留的範圍 |
lpop |
從list的頭部刪除一個元素,並返回該刪除的元素 |
|
rpop |
從list的尾部彈出一個元素,並返回該刪除的元素 |
|
rpoplpush |
從第一個list的尾部元素異常元素並新增到第二個list的頭部 |
rpoplpush mylistA mylistB |
lindex |
返回list位置的元素 |
lindex mylist 3 |
llen |
返回list中元素的個數 |
llen mylist |
1.4. Sets
Sets 就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的Sets資料結構,可以儲存一些集合性的資料。
案例:
在微博應用中,可以將一個使用者所有的關注人存在一個集合中,將其所有粉絲存在一個集合。Redis還為集合提供了求交集、並集、差集等操作,可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中。
Set是集合,是String型別的無序集合,set是通過hashtable實現的,概念和數學中個的集合基本類似,可以交集,並集,差集等等,set中的元素是沒有順序的。
方法 |
說明 |
特性 |
sadd |
向名稱為key的set中新增元素,返回影響元素的個數,0為失敗,1為成功 |
sadd myset value |
smembers |
檢視集合中所有的成員 |
smebers myset |
srem |
刪除集合的一個元素 |
srem myset two |
spop |
隨機返回並刪除set中一個元素 |
spop myset |
sdiff |
返回所有set與第一個set的差集 |
sdiff myset1 myset2 |
sdiffstore |
比較差集並且儲存到另一個set中,返回1代表成功 |
sdiffstore setstoreSet mySet1 myset2 |
sinter |
返回所有給定集合的交集 |
sinter myset1 mysert2 //1集合和2集合的交集 |
sinterstore |
返回給定集合的交集並存儲到另一個集合 |
sinterstore desset myset1 myset2 //存到desset集合中 |
sunion |
返回所有給定集合的並集 |
sunion set1 set2 |
sunionstore |
返回所有的並集並且儲存到另一個集合中,返回影響的元素個數 |
sunionstore destSet myset1 myset2 |
smove |
把第一個集合的元素移動到第二個集合中 |
smove myset myset 你好 |
scard |
返回集合中元素的個數 |
scard myset1 |
sismember |
測試某個元素是否在集合中,返回0是不是,大於0是存在 |
sismember mykey1 你好 |
srandmember |
隨機返回個集合中的元素 |
srandmemeber myset1 |
1.5. Sorted Sets
和Sets相比,Sorted Sets增加了一個權重引數score,使得集合中的元素能夠按score進行有序排列,比如一個儲存全班同學成績的Sorted Sets,其集合value可以是同學的學號,而score就可以是其考試得分,這樣在資料插入集合的時候,就已經進行了天然的排序。
案例:
可以用Sorted Sets來做帶權重的佇列,比如普通訊息的score為1,重要訊息的score為2,然後工作執行緒可以選擇按score的倒序來獲取工作任務。讓重要的任務優先執行。
Zset型別
它是set的一個升級版本,在set的基礎上增加了順序,這一屬性在新增修改元素時可以指定,每次指定後,zset會自動按新的值調整順序。
方法 |
說明 |
特性 |
zadd |
向zset中新增元素member,score 用於排序,如果元素存在,則更新其順序,返回0代表沒新增成功 |
ZADD key score member zadd myset 3 itim |
zrange |
取出集合中的元素 |
zrange myset 0 -1 withscores//顯示序號 by index |
zrem |
刪除名稱為key的zset中的元素member |
zrem myset itim |
zincrby |
修改元素的排序,如果元素不存在則新增該元素,且排序的score值為增加值 |
zincrby myzset score itim |
zrank |
返回元素在集合中的排序位置,就是索引值 |
zrank myzset itim //itim在集合中的位置 |
zrevrank |
返回從大到小的排序索引值,就是逆序位置 |
zrevrangk myzset itim//逆序的位置 |
zrevrange |
返回集合中從大到小排序(降序)的,索引start到end的所有元素 |
zrevrange myzset 0 -1 //逆序後的元素 |
zrangebyscore |
根據排序索引的scores來返回元素 |
zrangebyscore myzset 1 3 withscores// |
zcount |
返回集合中給定區間的數量 |
zcount myzset 2 4 //集合中2-4索引元素的個數 |
zcard |
返回集合中所有元素的個數 |
zcard myzset //返回所有元素的個數 |
zremrangebyrank |
刪除集合中排序在給定區間的所有元素(按索引刪除) |
zremrangebyrank myzset 2 3 // |
zremrangebyscore |
刪除集合中在給定排序區間的元素 (按順序刪除) |
zremrangebyscore myzset 2 5 // |
1.6. Pub/Sub
Pub/Sub 從字面上理解就是釋出(Publish)與訂閱(Subscribe),在Redis中,你可以設定對某一個key值進行訊息釋出及訊息訂閱,當一個key值上進行了訊息釋出後,所有訂閱它的客戶端都會收到相應的訊息。這一功能最明顯的用法就是用作實時訊息系統,比如普通的即時聊天,群聊等功能。
案例:
Qlocenter 下發策略
2. redis資料儲存
redis的儲存分為記憶體儲存、磁碟儲存和log檔案三部分,配置檔案中有三個引數對其進行配置。
l save seconds updates
save配置,指出在多長時間內,有多少次更新操作,就將資料同步到資料檔案。這個可以多個條件配合,比如預設配置檔案中的設定,就設定了三個條件。
l appendonly yes/no
appendonly配置,指出是否在每次更新操作後進行日誌記錄,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為redis本身同步資料檔案是按上面的save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。
l appendfsync no/always/everysec
appendfsync配置,no表示等作業系統進行資料快取同步到磁碟,always表示每次更新操作後手動呼叫fsync()將資料寫到磁碟,everysec表示每秒同步一次。
redis使用了兩種檔案格式:全量資料和增量請求。
全量資料格式是把記憶體中的資料寫入磁碟,便於下次讀取檔案進行載入;
增量請求檔案則是把記憶體中的資料序列化為操作請求,用於讀取檔案進行replay得到資料,序列化的操作包括SET、RPUSH、SADD、ZADD。
redis是一個支援持久化的記憶體資料庫,也就是說redis需要經常將記憶體中的資料同步到磁碟來保證持久化。redis支援兩種持久化方式,一種是 Snapshotting(快照)也是預設方式,另一種是Append-only file(縮寫aof)的方式。下面分別介紹
Snapshotting(RDB方式)
快照是預設的持久化方式。這種方式是就是將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb。可以通過配置設定自動做快照持久 化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照,下面是預設的快照儲存配置
save 900 1 #900秒內如果超過1個key被修改,則發起快照儲存
save 300 10 #300秒內容如超過10個key被修改,則發起快照儲存
save 60 10000
下面介紹詳細的快照儲存過程
1.redis呼叫fork,現在有了子程序和父程序。
2. 父程序繼續處理client請求,子程序負責將記憶體內容寫入到臨時檔案。由於os的寫時複製機制(copy on write)父子程序會共享相同的物理頁面,當父程序處理寫請求時os會為父程序要修改的頁面建立副本,而不是寫共享的頁面。所以子程序的地址空間內的數 據是fork時刻整個資料庫的一個快照。
3.當子程序將快照寫入臨時檔案完畢後,用臨時檔案替換原來的快照檔案,然後子程序退出。
client 也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主執行緒中儲存快照的,由於redis是用一個主執行緒來處理所有 client的請求,這種方式會阻塞所有client請求。所以不推薦使用。另一點需要注意的是,每次快照持久化都是將記憶體資料完整寫入到磁碟一次,並不 是增量的只同步髒資料。如果資料量大的話,而且寫操作比較多,必然會引起大量的磁碟io操作,可能會嚴重影響效能。
另外由於快照方式是在一定間隔時間做一次的,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改。如果應用要求不能丟失任何修改的話,可以採用aof持久化方式。下面介紹
Append-only file(AOF方式)
aof 比快照方式有更好的持久化性,是由於在使用aof持久化方式時,redis會將每一個收到的寫命令都通過write函式追加到檔案中(預設是 appendonly.aof)。當redis重啟時會通過重新執行檔案中儲存的寫命令來在記憶體中重建整個資料庫的內容。當然由於os會在核心中快取 write做的修改,所以可能不是立即寫到磁碟上。這樣aof方式的持久化也還是有可能會丟失部分修改。不過我們可以通過配置檔案告訴redis我們想要 通過fsync函式強制os寫入到磁碟的時機。有三種方式如下(預設是:每秒fsync一次)
appendonly yes //啟用aof持久化方式
# appendfsync always //每次收到寫命令就立即強制寫入磁碟,最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec //每秒鐘強制寫入磁碟一次,在效能和持久化方面做了很好的折中,推薦
# appendfsync no //完全依賴os,效能最好,持久化沒保證
aof 的方式也同時帶來了另一個問題。持久化檔案會變的越來越大。例如我們呼叫incr test命令100次,檔案中必須儲存全部的100條命令,其實有99條都是多餘的。因為要恢復資料庫的狀態其實檔案中儲存一條set test 100就夠了。為了壓縮aof的持久化檔案。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照類似的方式將記憶體中的資料 以命令的方式儲存到臨時檔案中,最後替換原來的檔案。具體過程如下
1. redis呼叫fork ,現在有父子兩個程序
2. 子程序根據記憶體中的資料庫快照,往臨時檔案中寫入重建資料庫狀態的命令
3. 父程序繼續處理client請求,除了把寫命令寫入到原來的aof檔案中。同時把收到的寫命令快取起來。這樣就能保證如果子程序重寫失敗的話並不會出問題。
4. 當子程序把快照內容寫入已命令方式寫到臨時檔案中後,子程序發訊號通知父程序。然後父程序把快取的寫命令也寫入到臨時檔案。
5. 現在父程序可以使用臨時檔案替換老的aof檔案,並重命名,後面收到的寫命令也開始往新的aof檔案中追加。
需要注意到是重寫aof檔案的操作,並沒有讀取舊的aof檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似。
3. 主從複製
redis主從複製配置和使用都非常簡單。
通過主從複製可以允許多個slave server擁有和master server相同的資料庫副本。下面是關於redis主從複製的一些特點
l master可以有多個slave
l 除了多個slave連到相同的master外,slave也可以連線其他slave形成圖狀結構
l 主從複製不會阻塞master。也就是說當一個或多個slave與master進行初次同步資料時,master可以繼續處理client發來的請求。相反slave在初次同步資料時則會阻塞不能處理client的請求。
l 主從複製可以用來提高系統的可伸縮性,我們可以用多個slave 專門用於client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的資料冗餘
l 可以在master禁用資料持久化,只需要註釋掉master 配置檔案中的所有save配置,然後只在slave上配置資料持久化。
主從複製的過程
當設定好slave伺服器後,slave會建立和master的連線,然後傳送sync命令。無論是第一次同步建立的連線還是連線斷開後的重新連 接,master都會啟動一個後臺程序,將資料庫快照儲存到檔案中,同時master主程序會開始收集新的寫命令並快取起來。後臺程序完成寫檔案後,master就傳送檔案給slave,slave將檔案儲存到磁碟上,然後載入到記憶體恢復資料庫快照到slave上。接著master就會把快取的命 令轉發給slave。而且後續master收到的寫命令都會通過開始建立的連線傳送給slave。從master到slave的同步資料的命令和從 client傳送的命令使用相同的協議格式。當master和slave的連線斷開時slave可以自動重新建立連線。如果master同時收到多個 slave發來的同步連線命令,只會使用啟動一個程序來寫資料庫映象,然後傳送給所有slave。
4. Redis應用場景
毫無疑問,Redis開創了一種新的資料儲存思路,使用Redis,我們不用在面對功能單調的資料庫時,把精力放在如何把大象放進冰箱這樣的問題上,而是利用Redis靈活多變的資料結構和資料操作,為不同的大象構建不同的冰箱。
Redis比較適合的一些應用場景,NoSQLFan簡單列舉在這裡,供大家一覽:
1.7.1.取最新N個數據的操作
記錄前N個最新登陸的使用者Id列表,超出的範圍可以從資料庫中獲得。
//把當前登入人新增到連結串列裡
ret = r.lpush("login:last_login_times", uid)
//保持連結串列只有N位
ret = redis.ltrim("login:last_login_times", 0, N-1)
//獲得前N個最新登陸的使用者Id列表
last_login_list = r.lrange("login:last_login_times", 0, N-1)
比如sina微博:
在Redis中我們的最新微博ID使用了常駐快取,這是一直更新的。但是我們做了限制不能超過5000個ID,因此我們的獲取ID函式會一直詢問Redis。只有在start/count引數超出了這個範圍的時候,才需要去訪問資料庫。
我們的系統不會像傳統方式那樣“重新整理”快取,Redis例項中的資訊永遠是一致的。SQL資料庫(或是硬碟上的其他型別資料庫)只是在使用者需要獲取“很遠”的資料時才會被觸發,而主頁或第一個評論頁是不會麻煩到硬碟上的資料庫了。
1.7.2.排行榜應用,取TOP N操作
這個需求與上面需求的不同之處在於,前面操作以時間為權重,這個是以某個條件為權重,比如按頂的次數排序,這時候就需要我們的sorted set出馬了,將你要排序的值設定成sorted set的score,將具體的資料設定成相應的value,每次只需要執行一條ZADD命令即可。
//將登入次數和使用者統一儲存在一個sorted set裡
zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3
ZADD key score member
//當用戶登入時,對該使用者的登入次數自增1
ret = r.zincrby("login:login_times", 1, uid)
//那麼如何獲得登入次數最多的使用者呢,逆序排列取得排名前N的使用者
ret = r.zrevrange("login:login_times", 0, N-1)
ZREVRANGE key start stop [WITHSCORES]
另一個很普遍的需求是各種資料庫的資料並非儲存在記憶體中,因此在按得分排序以及實時更新這些幾乎每秒鐘都需要更新的功能上資料庫的效能不夠理想。
典型的比如那些線上遊戲的排行榜,比如一個Facebook的遊戲,根據得分你通常想要:
- 列出前100名高分選手
- 列出某使用者當前的全球排名
這些操作對於Redis來說小菜一碟,即使你有幾百萬個使用者,每分鐘都會有幾百萬個新的得分。
模式是這樣的,每次獲得新得分時,我們用這樣的程式碼:
ZADD leaderboard <score> <username>
你可能用userID來取代username,這取決於你是怎麼設計的。
得到前100名高分使用者很簡單:ZREVRANGE leaderboard 0 99。
使用者的全球排名也相似,只需要:ZRANK leaderboard <username>。
ZRANK key member
Determine the index of a member in a sorted set
1.7.3.需要精準設定過期時間的應用
比如你可以把上面說到的sorted set的score值設定成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期資料了,不僅是清除Redis中的過期資料,你完全可以把Redis裡這個過期時間當成是對資料庫中資料的索引,用Redis來找出哪些資料需要過期刪除,然後再精準地從資料庫中刪除相應的記錄。
1.7.4.獲取某段時間所有資料去重值
這個使用Redis的set資料結構最合適了,只需要不斷地將資料往set中扔就行了,set意為集合,所以會自動排重。
1.7.5.Pub/Sub構建實時訊息系統
Redis的Pub/Sub系統可以構建實時的訊息系統
比如很多用Pub/Sub構建的實時聊天系統的例子。
1.7.6.訊息佇列系統
使用list可以構建佇列系統,使用sorted set甚至可以構建有優先順序的佇列系統。
比如:將Redis用作日誌收集器
實際上還是一個佇列,多個端點將日誌資訊寫入Redis,然後一個worker統一將所有日誌寫到磁碟。
1.7.7. 快取
效能優於Memcached,資料結構更多樣化。
1.7.8.範圍查詢
比如:有一個IP範圍對應地址的列表,現在需要給出一個IP的情況下,迅速的查詢到這個IP在哪個範圍,也就是要判斷此IP的所有地。
例如:查詢IP是否存在的問題;
ADSM,查詢IP是否在其他分組中存在。寫json檔案
sadd向名稱為key的set中新增元素,返回影響元素的個數,0為失敗,1為成功
例如:有下面兩個範圍,10-20和30-40
· A_start 10, A_end 20
· B_start 30, B_end 40
我們將這兩個範圍的起始位置存在Redis的Sorted Sets資料結構中,基本範圍起始值作為score,範圍名加start和end為其value值:
redis 127.0.0.1:6379> zadd ranges 10 A_start
(integer) 1
redis 127.0.0.1:6379> zadd ranges 20 A_end
(integer) 1
redis 127.0.0.1:6379> zadd ranges 30 B_start
(integer) 1
redis 127.0.0.1:6379> zadd ranges 40 B_end
(integer) 1
這樣資料在插入Sorted Sets後,相當於是將這些起始位置按順序排列好了。
現在我需要查詢15這個值在哪一個範圍中,只需要進行如下的zrangbyscore查詢:
redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1
1) "A_end"
這個命令的意思是在Sorted Sets中查詢大於15的第一個值。(+inf在Redis中表示正無窮大,15前面的括號表示>15而非>=15)
查詢的結果是A_end,由於所有值是按順序排列的,所以可以判定15是在A_start到A_end區間上,也就是說15是在A這個範圍裡。至此大功告成。
當然,如果你查詢到的是一個start,比如咱們用25,執行下面的命令
redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1
1) "B_start"
返回結果表明其下一個節點是一個start節點,也就是說25這個值不處在任何start和end之間,不屬於任何範圍。
11.儲存社交關係
Sina例項
l hash sets: 關注列表, 粉絲列表, 雙向關注列表(key-value(field), 排序)
l string(counter): 微博數, 粉絲數, ...(避免了select count(*) from ...)
l sort sets(自動排序): TopN, 熱門微博等, 自動排序
l lists(queue): push/sub新提醒,...
12.交集,並集,差集:(Set)
//book表儲存book名稱
set book:1:name ”The Ruby Programming Language”
set book:2:name ”Ruby on rail”
set book:3:name ”Programming Erlang”
//tag表使用集合來儲存資料,因為集合擅長求交集、並集
sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3
//即屬於ruby又屬於web的書?
inter_list = redis.sinter("tag.web", "tag:ruby")
//即屬於ruby,但不屬於web的書?
inter_list = redis.sdiff("tag.ruby", "tag:web")
//屬於ruby和屬於web的書的合集?
inter_list = redis.sunion("tag.ruby", "tag:web")
5. Redis Tools
1.8. 實用命令
l Keys * : 返回所有的key,* 可使用正則表示式查詢
l Type key :返回key的型別(string ,zset ,list)
l Select 1 : 選擇第一個資料庫;預設0-15個數據庫;預設是第0個數據庫庫中
l Dbsize : 當前資料庫中的key的個數
l Monitor : 監控收到的請求
1.9. phpRedisAdmin
類似phpmyadmin是一個PHP的MySQL WEB管理工具,是一個PHP的Redis WEB管理工具。
圖例:
1.10. RedBridge: 為Redis提供HTTP API及連線池功能
RedBridge 是一款基於Redis的 HTTP API。使用LUA直接跟Redis互動,對Redis的連線實現連線池。(類似資料庫的儲存過程) 高效的實現複雜的業務邏輯。
特性介紹
RedBridge 具有以下特徵:
1. 使用C+epoll 編寫的Web Server,支援HTTP GET操作
2. 連線池,連線控制代碼複用,提高跟Redis連線效率
3. 部分類庫使用Redis的程式碼,更加的穩定
4. 使用LUA直接呼叫Redis命令,實現一次性資料互動實現 複雜的業務邏輯。不需要多次資料互動
5. 服務模型採用單程序,雙執行緒模式
6. 配置檔案採用Lua 語法,容易讀取和書寫
7. RedBridge釋出前,還沒有類似的開源專案