redis總結
redis與memcached
- redis支持更多的數據結構
- redis支持數據持久化
redis支持兩種存儲方式:snapshot(快照)和aof(append only mode),快照是定時將內存快照持久化到硬盤(crash會丟失數據),aof是在寫入數據的同時將操作命令保存到日志(不會丟失數據,但操作日志管理維護成本高)
- redis單線程,memcached是多線程的
- redis修改libevent實現小巧的epoll,memcached完全依賴libevent(性能影響)
- memcached使用CAS避免資源競爭修改,redis提供了事務功能
CAS是通過為每一個cacke key設置一個隱藏的cas token作為版本號,每次set操作都會檢查並更新token
數據類型
string
string
是key/value的存儲結構(同memcached一樣),支持的命令:
get/set/del
incr/incrby
decr/descby
append/strlen
getrange/setrange
問題:計數
一般情況都需要額外使用鎖來避免並發寫的問題。
解決方法:
使用incr
命令來實現原子遞增,使用get/set
來重置計數狀態。
與memcached相同,可作為key/value數據庫,例如session共享。
hash
hash
的value實際上是一個hashmap,可以直接操作value的各個feild的值,支持的命令:
hset/hget/hgetall
hmset/hmget
hlen/hexists
hkeys/hvals
hash
兩種實現方式,
- 當數據較少時,為了節省內存采用線性存儲來節省空間
- 當數據較多時,才會使用hashmap來降低時間復雜度
問題:商品維度計數
商品有各種計數(喜歡、評論、鑒定、瀏覽等)
解決方法:
使用hash
的field
字段來存儲喜歡、評論等計數值。
同理,用戶維度計數(動態、關注、粉絲、喜歡、發帖等)。
該存儲結構適用於常用的商品、熱門新聞動態等經常被大量訪問的數據對象。
list
list
通過雙向鏈表實現,支持反向查找和遍歷,支持的命令:
lpush/rpush
lpop/rpop
lrange/lrem
利用push
和pop
操作可以實現消息隊列,也可以實現關注列表、粉絲/在線好友列表等功能。
問題:顯示最新的項目列表
SELECT * FROM foo WHERE ... ORDER BY TIME DESC LIMIT 10;
數據庫上的查詢語句如上,隨着數據的增多,排序會越來越慢。
解決方法:
- 為每一條數據選擇一個唯一的ID(可選自增ID)
- 緩存最新的N個數據,利用
redis
做數據緩存(list
結構不斷LPUSH最新的數據) - 當查詢內容超過
redis
緩存內容后,才會穿透緩存訪問數據庫
消息隊列的實現:
- 用
list
數據結構作為channel - 生產者lpush消息
- 消費者rpop消息
- 設定超時時間
上述消息隊列與PUB/SUB相比,不會丟失數據,但也沒有失敗重傳的機制(也就是沒有消息狀態)
set
set
是一個不允許重復的數據組合,支持的命令:
sadd/spop
sismembers
sinter/sunion/sdiff
smembers
可以用來實現好友列表中判斷是否為已存在好友或關注好友,也可以通過集合操作來實現共同好友、共同興趣、共同關注列表等。
問題:判斷微博的共同好友、共同興趣、是否為關注好友
解決方法:
- 利用set集合存儲用戶的好友ID
- 通過
sismembers
判斷用戶是否存在好友集合中 - 通過
sinter
來判斷兩個好友集合的共同好友 - 通過
sunion
來獲取兩個集合的所有好友 - 通過
sdiff
來獲取兩個集合的非共同好友,用於好友推薦
sorted set
sorted set
是有序的set
,通過提供一個優先級score
來實現自動排序,支持的命令:
zadd/zrem
zrange/zcard
score
可以用來實現權重隊列,也可以實現按時間、評分的自動排序列表。
問題:在線游戲實時排行榜
在線游戲的排行榜都需要實時更新操作,不可能去頻繁地更改關系型數據庫,
解決方法:
- 為用戶設置唯一的ID,采用
sorted set
來存儲用戶的得分情況 - 利用有序集合來對用戶得分進行排名,這里不可能存儲全部的用戶,可能只關心前100個用戶,那么就需要在redis之外做限制
問題:新聞排序
新聞排序是按照新聞的關注度(點擊率)和時間做排序,
score = points / (time^alpha)
上面的公式可以說明,點擊率越高,越可能獲得更多的評分;時間越久遠,也會降低新聞的評分。
因此,需要有一個專門用於計算新聞評分的進程,實時地處理最新的N條數據
解決方法:
- 拉取最新的N條數據
- 計算各個數據的評分
- 添加到有序集合中
Pub/Sub
實現消息隊列、實時消息系統。
Transactions
redis
提供事務的支持,
- 事務可以一次執行多個命令,多個命令按照順序執行,不會被其他客戶單的命令所打斷
- 事務是原子操作,要么全部執行,要么不執行
使用方法:
> MULTI
> ...
> EXEC
錯誤處理:
- 在EXEC之前產生的錯誤,
redis
會自動放棄這個事務 - 在EXEC之后產生的錯誤,並沒有特殊處理
其他應用
- 實時統計,而全量操作數據記錄到log日志,利用Hadoop進行更全面的離線分析
- web緩存,減輕數據庫壓力