redis是乙個基於key-value的快取記憶體系統,類似於memcached,但是支援更複雜的資料結構list、set、sortedset,並且有持久化的功能。
由於近期工作很多地方都用到了它,所以花了不少時間來閱讀文章、編碼實驗,了解一下
redis
都能做些什麼,能有什麼樣的效能表現。
首先遇到的第乙個問題就是,
redis
究竟是什麼?
這個問題看似可笑,其實不然,我很贊同
timyang
的觀點,架構者對
redis
的理解不同、定位也不同,決定了
redis
在整個系統結構中會扮演什麼樣的角色。我總結一下,主流有
3種理解:
1、key valuestore.
是乙個以
key-value
形式儲存的資料庫,定位直指mysql
,用來作為唯一的儲存系統。
2、memory cache.
是乙個把資料儲存在記憶體中的快取記憶體,用來在應用和資料庫間提供緩衝,替代
memcached。
3、data structrueserver.
把它支援對複雜資料結構的高速操作作為賣點,提供某些特殊業務場景的計算和展現需求。比如排行榜應用,
top 10
之類的。
目前更多的人還是把它定位為乙個
memcached
的公升級版,提供更多的資料結構操作,仍然是乙個
cache。
傳統的memcached
在類似於
sns社群這樣的業務場景下,有一些弊端。比如儲存好友關係,不得不使用特殊字元分隔的長字串來儲存。在好友關係沒有上限的業務需求下,操作效能低下,達不到快取系統應有的效能水平。而且從資料庫中的關係型結構對映到
cache
中的長字串形式,很明顯也是架構中很蹩腳的乙個環節。 而
redis
提供的list
、set
和sorted set
就可以很好的業務模型對映到相應的資料結構上,契合度很高。按我的理解,關聯式資料庫理論幾乎可以照搬到
redis
的應用中來。
redis
官方教程中的
仿twitter案例就是乙個非常好的入手點。用
set結構來儲存
follower
和following
,用list
結構來儲存每個人的所有
post
,再加上一些普通的
key-value
來儲存使用者基本資訊,很直觀和清晰。
我再來舉乙個好友關係的業務場景來描述一下我的理解,標準關係型資料庫結構是怎麼和
redis
儲存結構實現一一對映的。
資料庫中有
3張表: 1、
使用者表有兩列:
id、暱稱 2、
好友關係表有列:使用者
id、好友
id、好友所屬分組
id、好友備註、新增好友時間 3、
分組表:分組
id、分組名稱、所屬使用者id
增加、刪除乙個好友,就是在好友關係表裡
insert
或delete
一條記錄。
獲取某使用者的所有好友分組,及分組內的好友數:
select g.gid, g.gname, count(f.fuid)
from groups g left join friends f
on g.gid=f.gid
where g.uid=#uid#
group by g.gid, g.gname
獲取某使用者某分組下的好友列表:
select f.fuid, u.nickname, f.remark, f.time
from friends f left join users u
on f.fuid=u.id
where f.uid=#uid# and f.gid=#gid#
order by f.time
limit #start#, #count#
再來看看redis如何實現類似的業務場景。
使用者暱稱:uid:***xx:nickname
,以string
結構儲存,相當於
user表
分組名稱:
gid:yyyyy:gname
,以string
結構儲存
使用者所有分組:
uid:***xx:groups
,以set
結構儲存
gid的集合
分組下好友:
gid:yyyyy:friends
,以set
結構儲存,儲存
fuid
的集合
好友:uid:***xx:fuid:zzzzz:gid
、uid:***xx:fuid:zzzzz:remark
、uid:***xx:fuid:zzzzz:time
各自使用
string
結構儲存,相當於
friends
表的每個字段
新增乙個好友需要把
uid:***xx:fuid:zzzzz:gid
、uid:***xx:fuid:zzzzz:remark
、uid:***xx:fuid:zzzzz:time
這三個字段
set好,再
sadd gid:yyyyy:friends zzzzz
,把好友加到這個組的集合內
獲取某使用者的所有好友分組,及分組內的好友數,需要用
smembers
獲取uid:***xx:groups
集合中的
gid,再用這些
gid來分別
scardgid:yyyyy:friends
獲取該分組下有多少好友。
獲取使用者
123456
在分組1001
下的好友列表:
sort gid:1001:friends
by uid:123456:fuid:*:time
limit 0 10
get #
get uid:*:nickname
get uid:123456:fuid:*:remark
get uid:123456:fuid:*:time
很有意思是不是,很像
sql語句,
key中的
*符號是個佔位符,可以被
sort
出的結果替換,進而
get到動態
key裡面的
value。
我們可以總結一下,傳統的關係型資料庫,處理一對多的問題,需要把外來鍵放在多的一端,因為
rdbms
理論中沒有集合這個直接概念。而使用
redis
,我們可以很直覺的在一的一端來管理一對多的關係,使用
set。
這只是使用上的區別,而理論上,
rdbms
的理論完全可以套用在
redis
上,所有用關係型資料庫理論可以描述的結構,用
redis
的資料結構,都可以實現。
最關鍵的是,如果使用
mysql
,當資料規模非常大時,上面兩個查詢操作都需要借助表關聯技術,而大表間的
join
在大型系統中是需要極力避免的操作。相反
redis
的每個操作都會侷限在乙個較小的資料集範圍內,而且
key-value
的儲存形式,定位
key只是乙個複雜度為
o(1)
的操作。在
very huge
的資料量下,
redis
效能效果非常優異,這就是
nosql
的優勢所在!
Redis 基礎常識原理介紹
redis 基礎常識原理介紹 磁碟 定址 ms 頻寬 g m 記憶體 定址 ns 頻寬 很大 秒 毫秒 微妙 納秒 磁碟比內存在定址上慢了10w倍 i o buffer 磁碟與磁軌 扇區 一扇區 512byte 讀取資料造成索引成本變大 作業系統 無論怎麼讀,都是從系統讀取4k資料 預設 資料庫 資...
Redis基本介紹
redis 優勢 redis與其他key value儲存有什麼不同?redis支援五種資料型別 string 字串 hash 雜湊 list 列表 set 集合 及zset sorted set 有序集合 string是redis最基本的型別,你可以理解成與memcached一模一樣的型別,乙個ke...
redis簡單介紹
多次查詢讓你懷疑人生 冗餘欄位過多會讓你看起來很傻 為啥不試試redis 大大減少了查詢數量,提高了效率 redis的api更加人性化,再也不需要構建sql語句,節省了sql的解析時間 redis 是完全開源免費的,遵守bsd協議,是乙個高效能的key value資料庫。redis 與其他 key ...