string(字符串)
常用命令:
set,get,decr,incr,mget 等烁焙。
使用SETBIT航邢、GETBIT 實(shí)現(xiàn)日活,月活的統(tǒng)計(jì)
Redis Setbit 命令用于對 key 所儲存的字符串值骄蝇,設(shè)置或清除指定偏移量上的位(bit)翠忠。
假如:
日活的 數(shù)據(jù)格式 是這樣的 1101010(取七天的數(shù)據(jù)) 1為 簽到 0為未簽到。
只要統(tǒng)計(jì) 1的個(gè)數(shù) 即可知道 該用戶這個(gè)月(或周乞榨,年)的簽到次數(shù)秽之。
如 1101010 可表示 該月1,2吃既,4考榨,6號該用戶進(jìn)行了簽到, 其他時(shí)間未簽到鹦倚。
簽到時(shí)河质,只修改特定位置的數(shù)據(jù)即可。
如 源數(shù)據(jù) 1101010 第七天為未簽到 修改為 已簽到時(shí)震叙。
只需要 修改字符串的 第七個(gè)位置 設(shè)置為1 即可掀鹅。
即:1101011
語法
redis Setbit 命令基本語法如下:
redis 127.0.0.1:6379> Setbit KEY_NAME OFFSET
可用版本
>= 2.2.0
返回值
指定偏移量原來儲存的位。
實(shí)例
redis> SETBIT bit 10086 1
(integer) 0
redis> GETBIT bit 10086
(integer) 1
redis> GETBIT bit 100 # bit 默認(rèn)被初始化為 0
(integer) 0
hash(哈希)
Redis hash 是一個(gè)string類型的field和value的映射表媒楼,hash特別適合用于存儲對象乐尊。
常用命令:
hget,hset,hgetall 等。
使用 hash 的特性 做 數(shù)據(jù)緩存(用戶信息緩存)
# 添加測試數(shù)據(jù)
127.0.0.1:6379> HMSET user:1 name 'zhangsan' age '16' sex '1'
OK
127.0.0.1:6379> HMSET user:2 name 'lisi' age '18' sex '0'
OK
127.0.0.1:6379> HMSET user:3 name 'wangwu' age '20' sex '1'
OK
127.0.0.1:6379> HMSET user:4 name 'zhaoliu' age '22' sex '0'
OK
127.0.0.1:6379> HMSET user:5 name 'tianqi' age '23' sex '1'
OK
# 獲取user:5 的所有信息
127.0.0.1:6379> HGETALL user:5
1) "name"
2) "tianqi"
3) "age"
4) "11"
5) "sex"
6) "0"
# 修改 user:5 的年齡
127.0.0.1:6379> HSET user:5 age "20"
(integer) 0
# 獲取 user:5 的所有信息
127.0.0.1:6379> HGET user:5 age
"20"
127.0.0.1:6379>
list(列表)
常用命令:
lpush,rpush,lpop,rpop,lrange等划址。
應(yīng)用場景:
Redis list的應(yīng)用場景非常多扔嵌,也是Redis最重要的數(shù)據(jù)結(jié)構(gòu)之一限府,比如twitter的關(guān)注列表,粉絲列表等都可以用Redis的list結(jié)構(gòu)來實(shí)現(xiàn)痢缎。
實(shí)現(xiàn)方式:
Redis list的實(shí)現(xiàn)為一個(gè)雙向鏈表胁勺,即可以支持反向查找和遍歷,更方便操作独旷,不過帶來了部分額外的內(nèi)存開銷署穗,Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用的這個(gè)數(shù)據(jù)結(jié)構(gòu)嵌洼。
可以使用 redis + php 做郵件隊(duì)列
例如:
在使用 通過郵箱找回密碼的功能時(shí)蛇捌,通常郵件不是即時(shí)發(fā)送的。
如果是即時(shí)發(fā)送咱台,會造成用戶體驗(yàn)不好(延遲)络拌,程序耦合等。
這時(shí)候 可以使用隊(duì)列 回溺,先把要發(fā)送的郵箱 通過隊(duì)列存儲春贸,再通過隊(duì)列腳本來處理隊(duì)列。這樣異步操作會好很多遗遵。
set(集合)
Redis的Set是string類型的無序集合萍恕。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)车要。
Redis 中 集合是通過哈希表實(shí)現(xiàn)的允粤,所以添加,刪除翼岁,查找的復(fù)雜度都是O(1)类垫。
常用命令:
sadd,spop,smembers,sunion 等。
應(yīng)用場景:
Redis set對外提供的功能與list類似是一個(gè)列表的功能琅坡,
特殊之處在于set是可以自動(dòng)排重的悉患,當(dāng)你需要存儲一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí)榆俺,set是一個(gè)很好的選擇售躁,
并且set提供了判斷某個(gè)成員是否在一個(gè)set集合內(nèi)的重要接口,這個(gè)也是list所不能提供的茴晋。
利用集合成員是唯一的特性 陪捷。可以用來做訂票系統(tǒng)诺擅。
用集合來存儲定已經(jīng)被預(yù)定的票的編號市袖。如果有多個(gè)用戶預(yù)定了同一張票,只能有一個(gè)成功掀虎。
zset(sorted set:有序集合)
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員凌盯。
不同的是每個(gè)元素都會關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)。redis正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序烹玉。
有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)驰怎。
常用命令:
zadd,zrange,zrem,zcard等。
使用場景:
Redis sorted set的使用場景與set類似二打,區(qū)別是set不是自動(dòng)有序的县忌,
而sorted set可以通過用戶額外提供一個(gè)優(yōu)先級(score)的參數(shù)來為成員排序,并且是插入有序的继效,即自動(dòng)排序症杏。
當(dāng)你需要一個(gè)有序的并且不重復(fù)的集合列表,那么可以選擇sorted set數(shù)據(jù)結(jié)構(gòu)瑞信,
比如twitter 的public timeline可以以發(fā)表時(shí)間作為score來存儲厉颤,這樣獲取時(shí)就是自動(dòng)按時(shí)間排好序的。
利用有序集合的特性 來做 排行榜
例如:現(xiàn)在有一個(gè)需求就是對 所有用戶的錢包金額進(jìn)行排序凡简,取最富有的前十位用戶逼友。
那么redis的有序集合,就可以滿足要求了秤涩。
像 日榜帜乞,周榜,月榜等等 都可以用這個(gè)做筐眷。
周榜 和 月榜 都可以通過 日榜推算黎烈。
榜單的即時(shí)性 不強(qiáng),可以用mysql 在今天凌晨時(shí) 統(tǒng)計(jì)昨天的數(shù)據(jù) 再存入 redis的有序集合匀谣。
HyperLogLog(是用來做基數(shù)統(tǒng)計(jì)的算法)
Redis 在 2.8.9 版本添加了 HyperLogLog 結(jié)構(gòu)照棋。
Redis HyperLogLog 是用來做基數(shù)統(tǒng)計(jì)的算法,HyperLogLog 的優(yōu)點(diǎn)是武翎,在輸入元素的數(shù)量或者體積非常非常大時(shí)必怜,計(jì)算基數(shù)所需的空間總是固定 的、并且是很小的后频。
在 Redis 里面梳庆,每個(gè) HyperLogLog 鍵只需要花費(fèi) 12 KB 內(nèi)存,就可以計(jì)算接近 2^64 個(gè)不同元素的基 數(shù)卑惜。這和計(jì)算基數(shù)時(shí)膏执,元素越多耗費(fèi)內(nèi)存就越多的集合形成鮮明對比。
但是露久,因?yàn)?HyperLogLog 只會根據(jù)輸入元素來計(jì)算基數(shù)更米,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣毫痕,返回輸入的各個(gè)元素征峦。
常用命令:
PFADD key element [element ...]
添加指定元素到 HyperLogLog 中迟几。
PFCOUNT key [key ...]
返回給定 HyperLogLog 的基數(shù)估算值。
PFMERGE destkey sourcekey [sourcekey ...]
將多個(gè) HyperLogLog 合并為一個(gè) HyperLogLog
什么是基數(shù)?
比如數(shù)據(jù)集 {1, 3, 5, 7, 5, 7, 8}栏笆, 那么這個(gè)數(shù)據(jù)集的基數(shù)集為 {1, 3, 5 ,7, 8}, 基數(shù)(不重復(fù)元素)為5类腮。
基數(shù)就是在誤差可接受的范圍內(nèi),快速計(jì)算基數(shù)蛉加。
實(shí)例
以下實(shí)例演示了 HyperLogLog 的工作過程:
redis 127.0.0.1:6379> PFADD runoobkey "redis"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT runoobkey
(integer) 3
取最新N個(gè)數(shù)據(jù)的操作
比如典型的取你網(wǎng)站的最新文章蚜枢,通過下面方式,我們可以將最新的5000條評論的ID放在Redis的List集合中针饥,并將超出集合部分從數(shù)據(jù)庫獲取
使用LPUSH latest.comments<ID>命令厂抽,向list集合中插入數(shù)據(jù)
插入完成后再用LTRIM latest.comments 0 5000命令使其永遠(yuǎn)只保存最近5000個(gè)ID
然后我們在客戶端獲取某一頁評論時(shí)可以用下面的邏輯(偽代碼)
FUNCTION get_latest_comments(start,num_items):
id_list = redis.lrange("latest.comments",start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
END
RETURN id_list
END
如果你還有不同的篩選維度,比如某個(gè)分類的最新N條丁眼,那么你可以再建一個(gè)按此分類的List筷凤,只存ID的話,Redis是非常高效的
排行榜應(yīng)用苞七,取TOP N操作
這個(gè)需求與上面需求的不同之處在于嵌施,前面操作以時(shí)間為權(quán)重,這個(gè)是以某個(gè)條件為權(quán)重莽鸭,比如按頂?shù)拇螖?shù)排序吗伤,這時(shí)候就需要我們的sorted set出馬了,將你要排序的值設(shè)置成sorted set的score硫眨,將具體的數(shù)據(jù)設(shè)置成相應(yīng)的value足淆,每次只需要執(zhí)行一條ZADD命令即可。
需要精準(zhǔn)設(shè)定過期時(shí)間的應(yīng)用
比如你可以把上面說到的sorted set的score值設(shè)置成過期時(shí)間的時(shí)間戳礁阁,那么就可以簡單地通過過期時(shí)間排序巧号,定時(shí)清除過期數(shù)據(jù)了,不僅是清除Redis中的過期數(shù)據(jù)姥闭,你完全可以把Redis里這個(gè)過期時(shí)間當(dāng)成是對數(shù)據(jù)庫中數(shù)據(jù)的索引丹鸿,用Redis來找出哪些數(shù)據(jù)需要過期刪除,然后再精準(zhǔn)地從數(shù)據(jù)庫中刪除相應(yīng)的記錄棚品。
計(jì)數(shù)器應(yīng)用
Redis的命令都是原子性的靠欢,你可以輕松地利用INCR,DECR命令來構(gòu)建計(jì)數(shù)器系統(tǒng)铜跑。
Uniq操作门怪,獲取某段時(shí)間所有數(shù)據(jù)排重值
這個(gè)使用Redis的set數(shù)據(jù)結(jié)構(gòu)最合適了,只需要不斷地將數(shù)據(jù)往set中扔就行了锅纺,set意為集合掷空,所以會自動(dòng)排重。
Pub/Sub構(gòu)建實(shí)時(shí)消息系統(tǒng)
Redis的Pub/Sub系統(tǒng)可以構(gòu)建實(shí)時(shí)的消息系統(tǒng),比如很多用Pub/Sub構(gòu)建的實(shí)時(shí)聊天系統(tǒng)的例子坦弟。
構(gòu)建隊(duì)列系統(tǒng)
使用list可以構(gòu)建隊(duì)列系統(tǒng)护锤,使用sorted set甚至可以構(gòu)建有優(yōu)先級的隊(duì)列系統(tǒng)。