Redis相關介紹
一、為什麼需要NoSQL(泛指非關係型資料庫,英文:Not Only SQL)
(關係型資料庫是基於關係表的資料庫,最終會將資料持久化到磁碟上,而nosql資料 庫是基於特殊的結構,並將資料儲存到記憶體的資料庫。從效能上而言,nosql資料庫 要優於關係型資料庫,從安全性上而言關係型資料庫要優於nosql資料庫,所以在實 際開發中一個專案中nosql和關係型資料庫會一起使用,達到效能和安全性的雙保證。)
隨著網際網路Web2.0網站的興起,傳統的關係資料庫在應付Web2.0網站,特別是超大規模和高併發的SNS型別的Web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題。例如:
1、對資料庫高併發讀寫的需求
網站要根據使用者個性化資訊來實時生成動態頁面和提供動態資訊,所以基本上無法使用動態頁面靜態化技術,因此資料庫併發負載非常高,往往要達到每秒上萬次讀寫請求。關係資料庫應付上萬次SQL查詢還勉強頂得住,但是應付上萬次SQL寫資料請求,硬碟IO就已經無法承受了。
2、對海量資料的高效率儲存和訪問的需求
對於大型的SNS網站,每天使用者產生海量的使用者動態,以國外的Friendfeed為例,一個月就達到了2.5億條使用者動態,對於關係資料庫來說,在一張2.5億條記錄的表裡面進行SQL查詢,效率是極其低下乃至不可忍受的。
3、對資料庫的高可擴充套件性和高可用性的需求
在基於Web的架構當中,資料庫是最難進行橫向擴充套件的,當一個應用系統的使用者量和訪問量與日俱增的時候,你的資料庫卻沒有辦法像Web伺服器和應用伺服器那樣簡單的通過新增更多的硬體和服務節點來擴充套件效能和負載能力。對於很多需要提供7*24小時不間斷服務的網站來說,對資料庫系統進行升級和擴充套件是非常痛苦的事情,往往需要停機維護和資料遷移,為什麼資料庫不能通過不斷的新增伺服器節點來實現擴充套件呢?
任何大資料量的Web系統,都非常忌諱多個大表的關聯查詢,以及複雜的資料分析型別的複雜SQL報表查詢,特別是SNS型別的網站,從需求以及產品設計角度,就避免了這種情況的產生。往往更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。
因此,關係資料庫在這些越來越多的應用場景下顯得不那麼合適了,為了解決這類問題的非關係資料庫應運而生。NoSQL 是非關係型資料儲存的廣義定義。它打破了長久以來關係型資料庫與ACID理論大一統的局面。NoSQL 資料儲存不需要固定的表結構(例如以鍵值對儲存,它的結構不固定,每一個元組可以有不一樣的欄位,每個元組可以根據需要增加一些自己的鍵值對,這樣就不會侷限於固定的結構,可以減少一些時間和空間的開銷),通常也不存在連線操作。
二、NoSQL的特點
1、易擴充套件
NoSQL資料庫種類繁多,但是一個共同的特點都是去掉關係資料庫的關係型特性。資料之間無關係,這樣就非常容易擴充套件。也無形之間,在架構的層面上帶來了可擴充套件的能力。
2、大資料量,高效能
NoSQL資料庫都具有非常高的讀寫效能,尤其在大資料量下,同樣表現優秀。這得益於它的無關係性,資料庫的結構簡單。
3、靈活的資料模型
NoSQL無需事先為要儲存的資料建立欄位,隨時可以儲存自定義的資料格式。而在關係資料庫裡,增刪欄位是一件非常麻煩的事情。如果是非常大資料量的表,增加欄位簡直就是一個噩夢。這點在大資料量的Web2.0時代尤其明顯。
4、高可用
NoSQL在不太影響效能的情況,就可以方便的實現高可用的架構。比如Cassandra,HBase模型,通過複製模型也能實現高可用。
綜上所述,NoSQL的非關係特性使其成為了後Web2.0時代的寵兒,助力大型Web2.0網站的再次起飛,是一項全新的資料庫革命性運動。
三、Redis的常用命令
redis是一種高階的key-value的儲存系統
其中的key是字串型別,儘可能滿足如下幾點:
1)key不要太長,最好不要操作1024個位元組,這不僅會消耗記憶體還會降低查詢 效率
2)key不要太短,如果太短會降低key的可讀性
3)在專案中,key最好有一個統一的命名規範(根據企業的需求)
其中value 支援五種資料型別:
1)字串型 string
2)字串列表 lists
3)字串集合 sets
4)有序字串集合 sorted sets
5)雜湊型別 hashs
我們對Redis的學習,主要是對資料的儲存,下面將來學習各種Redis的資料型別的 儲存操作:
1.儲存字串string
字串型別是Redis中最為基礎的資料儲存型別,它在Redis中是二進位制安全的,這 便意味著該型別可以接受任何格式的資料,如JPEG影象資料或Json物件描述資訊等。 在Redis中字串型別的Value最多可以容納的資料長度是512M
1)set key value:設定key持有指定的字串value,如果該key存在則進行覆蓋 操作。總是返回”OK”
2)get key:獲取key的value。如果與該key關聯的value不是String型別,redis 將返回錯誤資訊,因為get命令只能用於獲取String value;如果該key不存在, 返 回null。
3)getset key value:先獲取該key的值,然後在設定該key的值。
4)incr key:將指定的key的value原子性的遞增1.如果該key不存在,其初始值 為0,在incr之後其值為1。如果value的值不能轉成整型,如hello,該操作將執 行失敗並返回相應的錯誤資訊。
5)decr key:將指定的key的value原子性的遞減1.如果該key不存在,其初始值 為0,在incr之後其值為-1。如果value的值不能轉成整型,如hello,該操作將執 行失敗並返回相應的錯誤資訊。
6)incrby key increment:將指定的key的value原子性增加increment,如果該 key不存在,器初始值為0,在incrby之後,該值為increment。如果該值不能轉成 整型,如hello則失敗並返回錯誤資訊
7)decrby key decrement:將指定的key的value原子性減少decrement,如果 該key不存在,器初始值為0,在decrby之後,該值為decrement。如果該值不能 轉成整型,如hello則失敗並返回錯誤資訊
8)append key value:如果該key存在,則在原有的value後追加該值;如果該 key 不存在,則重新建立一個key/value
2.儲存lists型別
在Redis中,List型別是按照插入順序排序的字串連結串列。和資料結構中的普通連結串列 一樣,我們可以在其頭部(left)和尾部(right)新增新的元素。在插入時,如果該鍵並不 存在,Redis將為該鍵建立一個新的連結串列。與此相反,如果連結串列中所有的元素均被移 除,那麼該鍵也將會被從資料庫中刪除。List中可以包含的最大元素數量是 4294967295。
從元素插入和刪除的效率視角來看,如果我們是在連結串列的兩頭插入或刪除元素,這將 會是非常高效的操作,即使連結串列中已經儲存了百萬條記錄,該操作也可以在常量時間 內完成。然而需要說明的是,如果元素插入或刪除操作是作用於連結串列中間,那將會是 非常低效的。相信對於有良好資料結構基礎的開發者而言,這一點並不難理解。
1)lpush key value1 value2...:在指定的key所關聯的list的頭部插入所有的 values,如果該key不存在,該命令在插入的之前建立一個與該key關聯的空鏈 表,之後再向該連結串列的頭部插入資料。插入成功,返回元素的個數。
2)rpush key value1、value2…:在該list的尾部新增元素
3)lrange key start end:獲取連結串列中從start到end的元素的值,start、end可 為負數,若為-1則表示連結串列尾部的元素,-2則表示倒數第二個,依次類推…
4)lpushx key value:僅當引數中指定的key存在時(如果與key管理的list中沒 有值時,則該key是不存在的)在指定的key所關聯的list的頭部插入value。
5)rpushx key value:在該list的尾部新增元素
6)lpop key:返回並彈出指定的key關聯的連結串列中的第一個元素,即頭部元素。
7)rpop key:從尾部彈出元素。
8)rpoplpush resource destination:將連結串列中的尾部元素彈出並新增到頭部
9)llen key:返回指定的key關聯的連結串列中的元素的數量。
10)lset key index value:設定連結串列中的index的腳標的元素值,0代表連結串列的頭元 素,-1代表連結串列的尾元素。
11)lrem key count value:刪除count個值為value的元素,如果count大於0,從頭向尾遍歷並刪除count個值為value的元素,如果count小於0,則從尾向頭遍歷並刪除。如果count等於0,則刪除連結串列中所有等於value的元素。
12)linsert key before|after pivot value:在pivot元素前或者後插入value這個 元素。
3.儲存sets型別
在Redis中,我們可以將Set型別看作為沒有排序的字元集合,和List型別一樣,我 們也可以在該型別的資料值上執行新增、刪除或判斷某一元素是否存在等操作。需要 說明的是,這些操作的時間是常量時間。Set可包含的最大元素數是4294967295。
和List型別不同的是,Set集合中不允許出現重複的元素。和List型別相比,Set類 型在功能上還存在著一個非常重要的特性,即在伺服器端完成多個Sets之間的聚合計 算操作,如unions、intersections和differences。由於這些操作均在服務端完成, 因此效率極高,而且也節省了大量的網路IO開銷
1)sadd key value1、value2…:向set中新增資料,如果該key的值已有則不會 重複新增
2)smembers key:獲取set中所有的成員
3)scard key:獲取set中成員的數量
4)sismember key member:判斷引數中指定的成員是否在該set中,1表示存 在,0表示不存在或者該key本身就不存在
5)srem key member1、member2…:刪除set中指定的成員
6)srandmember key:隨機返回set中的一個成員
7)sdiff sdiff key1 key2:返回key1與key2中相差的成員,而且與key的順序有 關。即返回差集。
8)sdiffstore destination key1 key2:將key1、key2相差的成員儲存在 destination上
9)sinter key[key1,key2…]:返回交集。
10)sinterstore destination key1 key2:將返回的交集儲存在destination上
11)sunion key1、key2:返回並集。
12)sunionstore destination key1 key2:將返回的並集儲存在destination上
4.儲存sortedset
Sorted-Sets和Sets型別極為相似,它們都是字串的集合,都不允許重複的成員出 現在一個Set中。它們之間的主要差別是Sorted-Sets中的每一個成員都會有一個分 數(score)與之關聯,Redis正是通過分數來為集合中的成員進行從小到大的排序。然 而需要額外指出的是,儘管Sorted-Sets中的成員必須是唯一的,但是分數(score) 卻是可以重複的。
在Sorted-Set中新增、刪除或更新一個成員都是非常快速的操作,其時間複雜度為 集合中成員數量的對數。由於Sorted-Sets中的成員在集合中的位置是有序的,因此, 即便是訪問位於集合中部的成員也仍然是非常高效的。事實上,Redis所具有的這一 特徵在很多其它型別的資料庫中是很難實現的,換句話說,在該點上要想達到和Redis 同樣的高效,在其它資料庫中進行建模是非常困難的。
例如:遊戲排名、微博熱點話題等使用場景。
1)zadd key score member score2 member2 … :將所有成員以及該成員的 分數存放到sorted-set中
2)zcard key:獲取集合中的成員數量
3)zcount key min max:獲取分數在[min,max]之間的成員
zincrby key increment member:設定指定成員的增加的分數。
zrange key start end [withscores]:獲取集合中腳標為start-end的成員,[withscores]引數表明返回的成員包含其分數。
zrangebyscore key min max [withscores] [limit offset count]:返回分數在[min,max]的成員並按照分數從低到高排序。[withscores]:顯示分數;[limit offset count]:offset,表明從腳標為offset的元素開始並返回count個成員。
zrank key member:返回成員在集合中的位置。
zrem key member[member…]:移除集合中指定的成員,可以指定多個成員。
zscore key member:返回指定成員的分數
5.儲存hash
Redis中的Hashes型別可以看成具有String Key和String Value的map容器。所 以該型別非常適合於儲存值物件的資訊。如Username、Password和Age等。如果 Hash中包含很少的欄位,那麼該型別的資料也將僅佔用很少的磁碟空間。每一個Hash 可以儲存4294967295個鍵值對。
1)hset key field value:為指定的key設定field/value對(鍵值對)。
2)hgetall key:獲取key中的所有filed-vaule
3)hget key field:返回指定的key中的field的值
4)hmset key fields:設定key中的多個filed/value
5)hmget key fileds:獲取key中的多個filed的值
6)hexists key field:判斷指定的key中的filed是否存在
7)hlen key:獲取key所包含的field的數量
8)hincrby key field increment:設定key中filed的值增加increment,如:age 增加20
四、Redis特性
1、多種資料型別儲存
字串型別,雜湊型別,列表型別,集合型別,有序集合型別
2、記憶體儲存與持久化
記憶體的讀寫速度遠快於硬碟
自身提供了持久化功能(RDB、AOF兩種方式)
3、功能豐富
可用作快取、佇列、訊息訂閱/釋出 ; 支援鍵的生存時間 ; 按照一定規則刪除相應的鍵
4、簡單穩定
相比SQL而言更加簡單 ; 不同語言的客戶端豐富 ;基於C語言開發
5、配置檔案
在windows平臺下配置有檔案:redis.windows.conf,redis.windows-service.conf;當具體使用哪個則看啟動時引用的是哪個。配置檔案包含了非常多的資訊,一般配置保持預設,在一些特定的場景下可以自定義配置,常用到的配置項如下:
port -- 服務埠
bind – 繫結ip其他ip不能訪問(多個ip空格隔開)
databases – 資料庫數量,預設16個
daemonize – 設定為守護程序(Linux平臺)
maxmemory – 最大的記憶體大小(1MB、1GB、1m、1g)
maxmemory-policy -- 達到記憶體限制後的處理策略(策略如下六種)
規則 |
說明 |
volatile-lru |
使用LRU演算法刪除一個鍵(只對設定了生存時間的鍵) |
allkeys-lru |
使用LRU演算法刪除一個鍵 |
volatile-random |
隨機刪除一個鍵(只對設定了生存時間的鍵) |
allkeys-random |
隨機刪除一個鍵 |
volatile-ttl |
刪除生存時間最近的一個鍵 |
noeviction |
不刪除鍵,只返回錯誤 |
LRU(Least Recently Used)演算法:最近最少使用
說明:修改後配置檔案需要重啟Redis服務才能生效。
6、多資料庫
Redis預設支援16個數據庫,對外都是以一個從0開始的遞增數字命名,可以通過引數databases來修改預設資料庫個數。客戶端連線Redis服務後會自動選擇0號資料庫,可以通過SELECT命令更換資料庫。
【例如】選擇1號資料庫:
127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6379> GET test (nil) |
說明:
Redis不支援自定義資料庫名稱。
Redis不支援為每個資料庫設定訪問密碼
Redis的多個數據庫之間不是完全隔離的,FLUSHALL命令會清空所有資料庫的資料。
多資料庫不適用儲存不同應用的資料。