1.NoSQL主要用於解決如下幾種問題html
1.少許數據存儲,高速讀寫訪問。此類產品經過數據所有in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。redis
2.海量數據存儲,分佈式系統支持,數據一致性保證,方便的集羣節點添加/刪除。mongodb
3.這方面最具表明性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個徹底無中心的設計,節點之間經過gossip方式傳遞集羣信息,數據保證最終一致性,後者是一箇中心化的方案設計,經過相似一個分佈式鎖服務來保證強一致性,數據寫入先寫內存和redo log,而後按期compat歸併到磁盤上,將隨機寫優化爲順序寫,提升寫入性能。數據庫
4.Schema free,auto-sharding等。好比目前常見的一些文檔數據庫都是支持schema-free的,直接存儲json格式數據,而且支持auto-sharding等功能,好比mongodb。json
面對這些不一樣類型的NoSQL產品,咱們須要根據咱們的業務場景選擇最合適的產品。api
Redis最適合全部數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差異,那麼可能你們就會有疑問,彷佛Redis更像一個增強版的Memcached,那麼什麼時候使用Memcached,什麼時候使用Redis呢?數組
2.Redis與Memcached的區別,大多數都會獲得如下觀點:安全
1 、Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。服務器
2 、Redis支持數據的備份,即master-slave模式的數據備份。數據結構
3 、Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用。
四、Redis能夠實現主從複製,實現故障恢復。
五、Redis的Sharding技術: 很容易將數據分佈到多個Redis實例中
1.redis.conf
啓動redis服務須要指定配置文件的,後臺啓動的話須要修改redis.conf文件,daemonize no ---- >daemonize yes。redis服務端默認連接端口是6379,最好也將IP綁定爲本機IP。
經常使用的數據類型主要有五種:String、List、Hash、Set和Sorted Set。
Redis內部使用一個redisObject對象來表示全部的key和value。redisObject主要的信息包括數據類型(type)、編碼方式(encoding)、數據指針(ptr)、虛擬內存(vm)等。type表明一個value對象具體是何種數據類型,encoding是不一樣數據類型在redis內部式。
vm字段,只有打開了Redis的虛擬內存功能,此字段纔會真正的分配內存,該功能默認是關閉狀態的,該功能會在後面具體描述。經過上圖咱們能夠發現Redis使用redisObject來表示全部的key/value數據是比較浪費內存的,固然這些內存管理成本的付出主要也是爲了給Redis不一樣數據類型提供一個統一的管理接口,實際做者也提供了多種方法幫助咱們儘可能節省內存使用。
字符串是Redis值的最基礎的類型。Redis中使用的字符串是經過包裝的,基於c語言字符數組實現的簡單動態字符串(simple dynamic string, SDS)一個抽象數據結構。其源碼定義以下:
struct sdshdr {
int len; //len表示buf中存儲的字符串的長度。
int free; //free表示buf中空閒空間的長度。
char buf[]; //buf用於存儲字符串內容。
};
C語言字符串內存結構示意圖
假設上圖是」hello」字符串的內存結構,這個時候len=5,free=2那麼redis包裝後(sds)其長度爲:
sizeof(struct sdshdr) + len + free + 1
其中buf的大小爲:
len + free + 1
1表示1個字節是用來存儲結束符’\0’的。Redis字符串是二進制安全的,由於二進制數據一般會有中間某個字節存儲’\0’的這種狀況,這意味着一個Redis字符串能夠包含任何種類的數據,例如一個JPEG圖像或者一個序列化的Ruby對象。二進制是否安全,簡單的理解就是能不能在字符串中間有‘\0’,以下圖:
C語言字符串內存結構示意圖
對於上圖,sds認爲這個字符串是「hello world」,而C語言的字符處理函數認爲這個字符串是「hello」。
應用場景
String是最經常使用的一種數據類型,普通的key/value存儲均可以歸爲此類。
經常使用命令
命令 | 說明 |
---|---|
set | 設置key對應value,可選擇指定失效時間 |
incr(decr) | 將 key 中儲存的數字值增(減)1 |
incrby(decrby) | 將 key 所儲存的值加上(減去)給定的增量值(減量值) |
setnx |
設置key對應的值爲String類型的value,若是key已經存在則返回0 |
setex |
設置key對應的值爲String類型的value,並設定有效期 |
setrange |
設置key對應value的子字符串 |
getrange |
獲取key對應value的子字符串 |
mset |
批量設置多個key的值,若是成功表示全部值都被設置,不然返回0表示沒有任何值被設置 |
msetnx |
同mset,不存在就設置,不會覆蓋已有的key |
getset |
設置key的值,並返回key舊的值 |
append |
給指定key的value追加字符串,並返回新字符串的長度 |
strlen |
取指定key的value的長度 |
注意:對int型的age和string型的age1都能進行incr操做時,實際上type=string表明value存儲的是一個普通字符串,那麼對應的encoding能夠是raw或者是int,若是是int則表明實際redis內部是按數值型類存儲和表示這個字符串的,固然前提是這個字符串自己能夠用數值表示,好比"20"這樣的字符串,當遇到incr、decr等操做時會轉成數值型進行計算,此時redisObject的encoding字段爲int。若是你試圖對name進行incr操做則報錯。
Hash是一個String類型的field和value之間的映射表,即redis的Hash數據類型的key(hash表名稱)對應的value實際的內部存儲結構爲一個HashMap,所以Hash特別適合存儲對象。相對於把一個對象的每一個屬性存儲爲String類型,將整個對象存儲在Hash類型中會佔用更少內存。
實現方式:當前HashMap的實現有兩種方式:當HashMap的成員比較少時Redis爲了節省內存會採用相似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding爲zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding爲ht。
應用場景
用一個對象來存儲用戶信息,商品信息,訂單信息等等。
經常使用命令
命令 |
說明 |
---|---|
hset | 設置key對應的HashMap中的field的value |
hget | 獲取key對應的HashMap中的field的value |
hgetall | 獲取key對應的HashMap中的全部field的value |
hsetnx |
設置key對應的HashMap中的field的value,若是不存在則先建立 |
hmset |
批量設置key對應的HashMap中的field的value |
hmget |
批量獲取key對應的HashMap中的field的value |
hincrby |
給key對應的HashMap中的field的value加指定的值 |
hexits |
測試key對應的HashMap中的field是否存在 |
hlen |
返回key對應的HashMap中的field的數量 |
hdel |
刪除key對應的HashMap中的field |
hkeys |
返回key對應的HashMap中全部的field |
hvals |
返回key對應的HashMap中全部的field的value |
Redis的List類型其實就是每個元素都是String類型的雙向鏈表。咱們能夠從鏈表的頭部和尾部添加或者刪除元素。這樣的List既能夠做爲棧,也能夠做爲隊列使用。Redis list的實現爲一個雙向鏈表,便可以支持反向查找和遍歷,更方便操做,不過帶來了部分額外的內存開銷,Redis內部的不少實現,包括髮送緩衝隊列等也都是用的這個數據結構。
List數據結構內部示意圖
應用場景
如好友列表,粉絲列表,消息隊列,最新消息排行等。
一個應用就是消息隊列,能夠利用Lists的PUSH操做,將任務存在Lists中,而後工做線程再用POP操做將任務取出進行執行。Redis還提供了操做Lists中某一段的api,你能夠直接查詢,刪除Lists中某一段的元素。
經常使用命令:
命令 |
說明 |
---|---|
lpush | 在key對應的list的頭部添加一個元素 |
lpop | 從key對應的list的尾部刪除一個元素,並返回該元素 |
lrange | 獲取key對應的list的指定下標範圍的元素(lrange key 0 -1 查看全部) |
rpush | 在key對應的list的尾部添加一個元素 |
rpop | 從key對應的list的尾部刪除一個元素,並返回該元素 |
linsert |
在key對應的list的特定元素的前或後插入元素 |
lset |
設置key對應的list中指定下標元素的值 |
lrem |
從key對應的list中刪除n個和value相同的元素 |
ltrim |
保留key對應的list中指定範圍的元素 |
rpoplpush |
從第一個list的尾部移除一個元素並添加到第二個list的頭部 |
llen |
返回key對應的list的長度 |
lindex |
返回key對應的list中index的元素 |
lpush、lpop
rpush、rpop
Redis 集合(Set類型)是一個無序的String類型數據的集合,相似List的一個列表,與List不一樣的是Set不能有重複的數據。
set 的內部實現是一個 value永遠爲null的HashMap,只用了HashMap的key列來存儲對象,實際就是經過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的緣由。
應用場景
集合有取交集、並集、差集等操做,所以能夠求共同好友、共同興趣、分類標籤等。
set是能夠自動排重的,當你須要存儲一個列表數據,又不但願出現重複數據時,set是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。
Sets 集合的概念就是一堆不重複值的組合。利用Redis提供的Sets數據結構,能夠存儲一些集合性的數據,好比在微博應用中,能夠將一個用戶全部的關注人存在一個集合中,將其全部粉絲存在一個集合。Redis還爲集合提供了求交集、並集、差集等操做,能夠很是方便的實現如共同關注、共同喜愛、二度好友等功能,對上面的全部集合操做,你還可使用不一樣的命令選擇將結果返回給客戶端仍是存集到一個新的集合中。
經常使用命令:
命令 |
說明 |
---|---|
sadd | 在key對應的set中添加一個元素 |
spop | 隨機返回並刪除key對應的set中的一個元素 |
smembers | 獲取key對應的set的全部元素 |
sdiff | 求給定key對應的set與第一個key對應的set的差集(sdiff set1 set2 返回在set1中但不在 set2 中的數據) |
suion | 求給定key對應的set並集 |
sinter | 求給定key對應的set交集 |
srem |
刪除key對應的set中的一個元素 |
sdiffstore |
求給定key對應的set與第一個key對應的set的差集,並存儲到另外一個key對應的set中 |
sinterstore |
求給定key對應的set交集,並存儲到另外一個key對應的set中 |
suionstore |
求給定key對應的set並集,並存儲到另外一個key對應的set中 |
somve |
從第一個key對應的set中刪除指定元素並添加到第二個key對應的set中 |
scard |
返回key對應的set的元素個數 |
sismember |
測試某個元素是否爲key對應的set中的元素個數 |
srandmember |
隨機返回key對應的set中的一個元素,但不刪除元素 |
SortSet顧名思義,是一個排好序的Set,它在Set的基礎上增長了一個順序屬性score,這個屬性在添加修改元素時能夠指定,每次指定後,SortSet會自動從新按新的值排序。
Redis sorted set的內部使用HashMap和跳躍表(SkipList)來保證數據的存儲和有序,HashMap裏放的是成員到score的映射,而跳躍表裏存放的是全部的成員,排序依據是HashMap裏存的score,使用跳躍表的結構能夠得到比較高的查找效率,而且在實現上比較簡單。
應用場景
如按時間排序的時間軸。
Redis sorted set的使用場景與set相似,區別是set不是自動有序的,而sorted set能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,即自動排序。當你須要一個有序的而且不重複的集合列表,那麼能夠選擇sorted set數據結構,好比twitter 的public timeline能夠以發表時間做爲score來存儲,這樣獲取時就是自動按時間排好序的。
另外還能夠用Sorted Sets來作帶權重的隊列,好比普通消息的score爲1,重要消息的score爲2,而後工做線程能夠選擇按score的倒序來獲取工做任務。讓重要的任務優先執行。
經常使用命令:
命令 |
說明 |
---|---|
zadd | 在key對應的zset中添加一個元素 |
zrange | 獲取key對應的zset中指定範圍的元素,-1表示獲取全部元素 |
zrem | 刪除key對應的zset中的一個元素 |
zincrby |
若是key對應的zset中已經存在元素member,則對member的score屬性加指定的值 |
zrank |
返回key對應的zset中指定member的排名。其中member按score值遞增(從小到大);排名以0爲底,也就是說,score值最小的成員排名爲0 |
zrevrank |
得到成員按score值遞減(從大到小)排列的排名 |
zrevrange |
返回有序集key中,指定區間內的成員。其中成員的位置按score值遞減(從大到小)來排列 |
zrangebyscore |
返回有序集key中,指定分數範圍的元素列表 |
zcount |
返回有序集key中,score值在min和max之間(默認包括score值等於min或max)的成員 |
zcard |
返回key的有序集元素個數 |
Pub/Sub 從字面上理解就是發佈(Publish)與訂閱(Subscribe),在Redis中,你能夠設定對某一個key值進行消息發佈及消息訂閱,當一個key值上進行了消息發佈後,全部訂閱它的客戶端都會收到相應的消息。這一功能最明顯的用法就是用做實時消息系統,好比普通的即時聊天,羣聊等功能。
Redis的Transactions提供的並非嚴格的ACID的事務(好比一串用EXEC提交執行的命令,在執行中服務器宕機,那麼會有一部分命令執行了,剩下的沒執行),可是這個Transactions仍是提供了基本的命令打包執行的功能(在服務器不出問題的狀況下,能夠保證一連串的命令是順序在一塊兒執行的,中間有會有其它客戶端命令插進來執行)。Redis還提供了一個Watch功能,你能夠對一個key進行Watch,而後再執行Transactions,在這過程當中,若是這個Watched的值進行了修改,那麼這個Transactions會發現並拒絕執行。
參考:
redis實際運用案例:http://blog.csdn.net/jinfeiteng2008/article/details/53711752
redis基礎參考:http://www.cnblogs.com/hjwublog/category/848303.html