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的幾種使用方式
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發布前,還沒有類似的開源項目