1 nosql的簡介html
1.1 nosql簡介
隨着互聯網Web2.0網站的興起,傳統的關係數據庫在應付Web2.0網站,特別是超大規模和高併發的SNS類型的Web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,如:mysql
1.1.1 對數據庫高併發讀寫的需求
網站要根據用戶個性化信息來實時生成動態頁面和提供動態信息,因此基本上沒法使用動態頁面靜態化技術,所以數據庫併發負載很是高,每每要達到每秒上萬次讀寫請求。關係數據庫應付上萬次SQL查詢還勉強頂得住,可是應付上千萬次SQL寫數據請求,硬盤IO就已經沒法承受了。git
1.1.2 對海量數據的高效率存儲和訪問的需求
對於大型的SNS網站,天天用戶產生海量的用戶動態,以國外的Friendfeed爲例,一個月就達到了2.5億條用戶動態,對於關係數據庫來講,在一張2.5億條記錄的表裏面進行SQL查詢,效率是極其低下乃至不可忍受的。github
1.1.3 對數據庫的高可擴展性和高可用性的需求
在基於Web的架構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,你的數據庫卻沒有辦法像Web服務器和應用服務器那樣簡單的經過添加更多的硬件和服務節點來擴展性能和負載能力。對於不少須要提供7*24小時不間斷服務的網站來講,對數據庫系統進行升級和擴展是很是痛苦的事情,每每須要停機維護和數據遷移,爲何數據庫不能經過不斷的添加服務器節點來實現擴展呢?redis
在上面提到的「三高」的需求面前,關係數據庫遇到了難以克服的障礙,而對於Web2.0網站來講,關係數據庫的不少主要特性卻每每無用武之地,例如:sql
(1)數據庫事務一致性需求數據庫
不少Web實時系統並不要求嚴格的數據庫事務,對讀一致性的要求很低,有些場合對寫一致性要求也不高。所以數據庫事務管理成了數據庫高負載下一個沉重的負擔。數組
(2)數據庫的寫實時性和讀實時性需求緩存
對關係數據庫來講,插入一條數據以後馬上查詢,是確定能夠讀出來這條數據的。並不要求這麼高的實時性。安全
(3)對複雜的SQL查詢,特別是多表關聯查詢的需求
任何大數據量的Web系統,都很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的複雜SQL報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免了這種狀況的產生。每每更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。
所以,關係數據庫在這些愈來愈多的應用場景下顯得不那麼合適了,爲了解決這類問題的非關係數據庫應運而生。NoSQL 是非關係型數據存儲的廣義定義。它打破了長久以來關係型數據庫與ACID理論大一統的局面。NoSQL 數據存儲不須要固定的表結構(例如以鍵值對存儲,它的結構不固定,每個元組能夠有不同的字段,每一個元組能夠根據須要增長一些本身的鍵值對,這樣就不會侷限於固定的結構,能夠減小一些時間和空間的開銷),一般也不存在鏈接操做。
1.2 NoSQL無與倫比的特色
在大數據存取上具有關係型數據庫沒法比擬的性能優點,例如:
1.2.1 易擴展
NoSQL數據庫種類繁多,可是一個共同的特色都是去掉關係數據庫的關係型特性。數據之間無關係,這樣就很是容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。
1.2.2 大數據量,高性能
NoSQL數據庫都具備很是高的讀寫性能,尤爲在大數據量下,一樣表現優秀。這得益於它的無關係性,數據庫的結構簡單。
1.2.3 靈活的數據模型
NoSQL無需事先爲要存儲的數據創建字段,隨時能夠存儲自定義的數據格式。而在關係數據庫裏,增刪字段是一件很是麻煩的事情。若是是很是大數據量的表,增長字段簡直就是一個噩夢。這點在大數據量的Web2.0時代尤爲明顯。
1.2.4 高可用
NoSQL在不太影響性能的狀況,就能夠方便的實現高可用的架構。好比Cassandra,HBase模型,經過複製模型也能實現高可用。
綜上所述,NoSQL的非關係特性使其成爲了後Web2.0時代的寵兒,助力大型Web2.0網站的再次起飛,是一項全新的數據庫革命性運動。
1.3 redis簡介
隨着應用對高性能需求的增長,NoSQL逐漸在各大名企的系統架構中生根發芽。時至今日,涌現出的NoSQL產品已經有不少種了,例如Membase、MongoDB、Apache Cassandra、CouchDB等。不過,在國內外互聯網巨頭例如社交巨頭新浪微博、傳媒巨頭Viacom及圖片分享領域佼佼者Pinterest等名企都不約而同地採用了Redis做爲其NoSQL數據庫的選擇,到底Redis是何方神聖呢?能讓如此多的名企爲它而癡狂。
按照官方的說法,Redis是一個開源的,使用C語言編寫,面向「鍵/值」(Key/Value)對類型數據的分佈式NoSQL數據庫系統,特色是高性能,持久存儲,適應高併發的應用場景。所以,能夠說Redis純粹爲應用而產生,它是一個高性能的key-value數據庫,而且還提供了多種語言的API(包括咱們的大C#)。那麼,也許咱們會問:到底性能如何呢?如下是官方的bench-mark數據:
測試完成了50個併發執行100000個請求。
設置和獲取的值是一個256字節字符串。
Linux box是運行Linux 2.6,這是X3320 Xeon 2.5 ghz。
文本執行使用loopback接口(127.0.0.1)。
結果:讀的速度是110000次/s,寫的速度是81000次/s 。(固然不一樣的服務器配置性能也有所不一樣)。
和Memcached相似,Redis支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,Redis支持各類不一樣方式的排序。與Memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是Redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步(數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。)。
所以,Redis的出現,很大程度補償了Memcached這類key/value存儲的不足,在部分場合能夠對關係數據庫起到很好的補充做用。
1.4 redis是什麼
redis是一個開源的、使用C語言編寫的、支持網絡交互的、可基於內存也可持久化的Key-Value數據庫。
redis的做者,Salvatore Sanfilippo,來自意大利的西西里島,如今居住在卡塔尼亞。目前供職於Pivotal公司。他使用的網名是antirez,若是你有興趣,能夠去他的博客逛逛,地址是antirez.com,他的github地址是http://github.com/antirez。
2 CentOS下安裝redis
步驟:
一、 將Windows下下載的壓縮文件上傳到Linux下。咱們能夠經過filezilla等FTP軟件上傳,這裏經過secureCRT進行上傳。步驟以下:
l alt + p
l put c:/redis-2.6.16.tar.gz
l 完成上傳
二、 解壓文件
l tar –zxvf redis-2.6.16.tar.gz
三、 編譯redis
l 進入解壓文件夾,cd redis-2.6.16
l 執行make[編譯,將.c文件編譯爲.o文件]
四、 安裝
l make PREFIX=/usr/local/redis install
l 安裝完後,在/usr/local/redis/bin下有幾個可執行文件
redis-benchmark ----性能測試工具
redis-check-aof ----檢查修復aof文件 appendonly file
redis-check-dump ----檢查快照持久化文件
redis-cli ----命令行客戶端
redis-server ----redis服務器啓動命令
五、 copy文件
redis啓動須要一個配置文件:cp redis.conf /usr/local/redis
六、 啓動redis /usr/local/redis/bin… 查看該進程: ps -ef | grep redis 結束該進程:kill -9 pid(進程號)
命令:bin/redis-server redis.conf,這種方式又稱爲前臺啓動。後臺啓動可修redis.conf文件,daemonize no-àyes便可。
3 redis的數據結構
redis是一種高級的key-value的存儲系統,其中value支持五種數據類型。
一、 字符串(String)
二、 字符串列表(lists)
三、 字符串集合(sets)
四、 有序字符串集合(sorted sets)
五、 哈希(hashs)
而關於key的定義呢,須要你們注意的幾點:
一、 key不要太長,最好不要操做1024個字節,這不只會消耗內存還會下降查找效率
二、 key不要過短,若是過短會下降key的可讀性
三、 在項目中,key最好有一個統一的命名規範
3.1 存儲string
3.1.1 概述
字符串類型是Redis中最爲基礎的數據存儲類型,它在Redis中是二進制安全的,這便意味着該類型能夠接受任何格式的數據,如JPEG圖像數據或Json對象描述信息等。在Redis中字符串類型的Value最多能夠容納的數據長度是512M。
3.1.2 經常使用命令
l set key value:設定key持有指定的字符串value,若是該key存在則進行覆蓋操做。老是返回」OK」
l get key:獲取key的value。若是與該key關聯的value不是String類型,redis將返回錯誤信息,由於get命令只能用於獲取String value;若是該key不存在,返回null。
l getset key value:先獲取該key的值,而後在設置該key的值。
l incr key:將指定的key的value原子性的遞增1.若是該key不存在,其初始值爲0,在incr以後其值爲1。若是value的值不能轉成整型,如hello,該操做將執行失敗並返回相應的錯誤信息。
l decr key:將指定的key的value原子性的遞減1.若是該key不存在,其初始值爲0,在incr以後其值爲-1。若是value的值不能轉成整型,如hello,該操做將執行失敗並返回相應的錯誤信息。
l incrby key increment:將指定的key的value原子性增長increment,若是該key不存在,器初始值爲0,在incrby以後,該值爲increment。若是該值不能轉成整型,如hello則失敗並返回錯誤信息
l decrby key decrement:將指定的key的value原子性減小decrement,若是該key不存在,器初始值爲0,在decrby以後,該值爲decrement。若是該值不能轉成整型,如hello則失敗並返回錯誤信息
l append key value:若是該key存在,則在原有的value後追加該值;若是該key不存在,則從新建立一個key/value
3.2 存儲list
3.2.1 概述
在Redis中,List類型是按照插入順序排序的字符串鏈表。和數據結構中的普通鏈表同樣,咱們能夠在其頭部(left)和尾部(right)添加新的元素。在插入時,若是該鍵並不存在,Redis將爲該鍵建立一個新的鏈表。與此相反,若是鏈表中全部的元素均被移除,那麼該鍵也將會被從數據庫中刪除。List中能夠包含的最大元素數量是4294967295。
從元素插入和刪除的效率視角來看,若是咱們是在鏈表的兩頭插入或刪除元素,這將會是很是高效的操做,即便鏈表中已經存儲了百萬條記錄,該操做也能夠在常量時間內完成。然而須要說明的是,若是元素插入或刪除操做是做用於鏈表中間,那將會是很是低效的。相信對於有良好數據結構基礎的開發者而言,這一點並不難理解。
一、 ArrayList使用數組方式存儲數據,因此根據索引查詢數據速度快,而新增或者刪除元素時須要設計到位移操做,因此比較慢。
二、 LinkedList使用雙向連接方式存儲數據,每一個元素都記錄先後元素的指針,因此插入、刪除數據時只是更改先後元素的指針指向便可,速度很是快,而後經過下標查詢元素時須要從頭開始索引,因此比較慢。
三、 雙向鏈表中添加數據
四、 雙向鏈表中刪除數據
五、 時間複雜度
3.2.2 經常使用命令
l lpush key values[value1 value2…]:在指定的key所關聯的list的頭部插入全部的values,若是該key不存在,該命令在插入的以前建立一個與該key關聯的空鏈表,以後再向該鏈表的頭部插入數據。插入成功,返回元素的個數。
l lpushx key value:僅當參數中指定的key存在時(若是與key管理的list中沒有值時,則該key是不存在的)在指定的key所關聯的list的頭部插入value。
l lrange key start end:獲取鏈表中從start到end的元素的值,start、end可爲負數,若爲-1則表示鏈表尾部的元素,-2則表示倒數第二個,依次類推…
l lpop key:返回並彈出指定的key關聯的鏈表中的第一個元素,即頭部元素。若是該key不存在,返回nil;若key存在,則返回鏈表的頭部元素。
l llen key:返回指定的key關聯的鏈表中的元素的數量。
l lrem key count value:刪除count個值爲value的元素,若是count大於0,從頭向尾遍歷並刪除count個值爲value的元素,若是count小於0,則從尾向頭遍歷並刪除。若是count等於0,則刪除鏈表中全部等於value的元素。
l lset key index value:設置鏈表中的index的腳標的元素值,0表明鏈表的頭元素,-1表明鏈表的尾元素。操做鏈表的腳標則放回錯誤信息。
l linsert key before|after pivot value:在pivot元素前或者後插入value這個元素。
l rpush key values[value一、value2…]:在該list的尾部添加元素。
l rpushx key value’:在該list的尾部添加元素
l rpop key:從尾部彈出元素。
l rpoplpush resource destination:將鏈表中的尾部元素彈出並添加到頭部。[循環操做]
3.2.3 使用場景
rpoplpush的使用場景:
Redis鏈表常常會被用於消息隊列的服務,以完成多程序之間的消息交換。假設一個應用程序正在執行LPUSH操做向鏈表中添加新的元素,咱們一般將這樣的程序稱之爲"生產者(Producer)",而另一個應用程序正在執行RPOP操做從鏈表中取出元素,咱們稱這樣的程序爲"消費者(Consumer)"。若是此時,消費者程序在取出消息元素後馬上崩潰,因爲該消息已經被取出且沒有被正常處理,那麼咱們就能夠認爲該消息已經丟失,由此可能會致使業務數據丟失,或業務狀態的不一致等現象的發生。然而經過使用RPOPLPUSH命令,消費者程序在從主消息隊列中取出消息以後再將其插入到備份隊列中,直到消費者程序完成正常的處理邏輯後再將該消息從備份隊列中刪除。同時咱們還能夠提供一個守護進程,當發現備份隊列中的消息過時時,能夠從新將其再放回到主消息隊列中,以便其它的消費者程序繼續處理。
3.3 存儲hash
3.3.1 概述
Redis中的Hashes類型能夠當作具備String Key和String Value的map容器。因此該類型很是適合於存儲值對象的信息。如Username、Password和Age等。若是Hash中包含不多的字段,那麼該類型的數據也將僅佔用不多的磁盤空間。每個Hash能夠存儲4294967295個鍵值對。
3.3.2 經常使用命令
l hset key field value:爲指定的key設定field/value對(鍵值對)。
l hget key field:返回指定的key中的field的值
l hexists key field:判斷指定的key中的filed是否存在
l hlen key:獲取key所包含的field的數量
l hincrby key field increment:設置key中filed的值增長increment,如:age增長20
l hmset key fields:設置key中的多個filed/value
l hmget key fileds:獲取key中的多個filed的值
3.4 存儲set
3.4.1 概述
在Redis中,咱們能夠將Set類型看做爲沒有排序的字符集合,和List類型同樣,咱們也能夠在該類型的數據值上執行添加、刪除或判斷某一元素是否存在等操做。須要說明的是,這些操做的時間複雜度爲O(1),即常量時間內完成次操做。Set可包含的最大元素數量是4294967295。
和List類型不一樣的是,Set集合中不容許出現重複的元素,這一點和C++標準庫中的set容器是徹底相同的。換句話說,若是屢次添加相同元素,Set中將僅保留該元素的一份拷貝。和List類型相比,Set類型在功能上還存在着一個很是重要的特性,即在服務器端完成多個Sets之間的聚合計算操做,如unions、intersections和differences。因爲這些操做均在服務端完成,所以效率極高,並且也節省了大量的網絡IO開銷。
3.4.2 經常使用命令
l sad key values[value一、value2…]:向set中添加數據,若是該key的值已有則不會重複添加
l smembers key:獲取set中全部的成員
l scard key:獲取set中成員的數量
l sismember key member:判斷參數中指定的成員是否在該set中,1表示存在,0表示不存在或者該key自己就不存在
l srem key members[member一、member2…]:刪除set中指定的成員
l srandmember key:隨機返回set中的一個成員
l sdiff key[sdiff key1 key2…]:返回key1與key2中相差的成員,並且與key的順序有關。即返回差集。
l sdiffstore destination key[key一、key2…]:將key一、key2相差的成員存儲在destination上
l sinter key[key1,key2…]:返回交集。
l sinterstore destination key[key…]:將返回的交集存儲在destination上
l sunion key[key一、key2…]:返回並集。
l sunionstore destination key[key…]:將返回的並集存儲在destination上
3.4.3 使用場景
一、可使用Redis的Set數據類型跟蹤一些惟一性數據,好比訪問某一博客的惟一IP地址信息。對於此場景,咱們僅需在每次訪問該博客時將訪問者的IP存入Redis中,Set數據類型會自動保證IP地址的惟一性。
二、充分利用Set類型的服務端聚合操做方便、高效的特性,能夠用於維護數據對象之間的關聯關係。好比全部購買某一電子設備的客戶ID被存儲在一個指定的Set中,而購買另一種電子產品的客戶ID被存儲在另一個Set中,若是此時咱們想獲取有哪些客戶同時購買了這兩種商品時,Set的intersections命令就能夠充分發揮它的方便和效率的優點了。
3.5 存儲sortedset
3.5.1 概述
Sorted-Sets和Sets類型極爲類似,它們都是字符串的集合,都不容許重複的成員出如今一個Set中。它們之間的主要差異是Sorted-Sets中的每個成員都會有一個分數(score)與之關聯,Redis正是經過分數來爲集合中的成員進行從小到大的排序。然而須要額外指出的是,儘管Sorted-Sets中的成員必須是惟一的,可是分數(score)倒是能夠重複的。
在Sorted-Set中添加、刪除或更新一個成員都是很是快速的操做,其時間複雜度爲集合中成員數量的對數。因爲Sorted-Sets中的成員在集合中的位置是有序的,所以,即使是訪問位於集合中部的成員也仍然是很是高效的。事實上,Redis所具備的這一特徵在不少其它類型的數據庫中是很難實現的,換句話說,在該點上要想達到和Redis一樣的高效,在其它數據庫中進行建模是很是困難的。
例如:遊戲排名、微博熱點話題等使用場景。
3.5.2 經常使用命令
l zadd key score member score2 member2 … :將全部成員以及該成員的分數存放到sorted-set中
l zcard key:獲取集合中的成員數量
l zcount key min max:獲取分數在[min,max]之間的成員
l zincrby key increment member:設置指定成員的增長的分數。
l zrange key start end [withscores]:獲取集合中腳標爲start-end的成員,[withscores]參數代表返回的成員包含其分數。
l zrangebyscore key min max [withscores] [limit offset count]:返回分數在[min,max]的成員並按照分數從低到高排序。[withscores]:顯示分數;[limit offset count]:offset,代表從腳標爲offset的元素開始並返回count個成員。
l zrank key member:返回成員在集合中的位置。
l zrem key member[member…]:移除集合中指定的成員,能夠指定多個成員。
l zscore key member:返回指定成員的分數
3.5.3 使用場景
一、能夠用於一個大型在線遊戲的積分排行榜。每當玩家的分數發生變化時,能夠執行ZADD命令更新玩家的分數,此後再經過ZRANGE命令獲取積分TOPTEN的用戶信息。固然咱們也能夠利用ZRANK命令經過username來獲取玩家的排行信息。最後咱們將組合使用ZRANGE和ZRANK命令快速的獲取和某個玩家積分相近的其餘用戶的信息。
二、Sorted-Sets類型還可用於構建索引數據。
4 key的通用操做
l keys pattern:獲取全部與pattern匹配的key,返回全部與該key匹配的keys。*表示任意一個或多個字符,?表示任意字符,[abc]表示方括號中任意一個字母
l del key[key一、key2…]:刪除指定的key
l exists key:判斷該key是否存在,1表明存在,0表明不存在
l rename key newkey:爲當前的key重命名
l ttl key:獲取該key所剩的超時時間,若是不存在或沒有超時設置,返回-1
l type key:獲取指定key的類型。該命令將以字符串的格式返回。返回的字符串爲string、list、set、hash和zset,若是key不存在返回none。
5 redis其餘特性
5.1 消息訂閱與發佈
subscribe channel:訂閱頻道,例:subscribe mychat,訂閱mychat這個頻道
psubscribe channel*:批量訂閱頻道,例:psubscribe s*,訂閱以」s」開頭的頻道
publish channel content:在指定的頻道中發佈消息,如 publish mychat ‘today is a newday’
5.2 多數據庫
5.2.1 概念
一個Redis實例能夠包括多個數據庫,客戶端能夠指定鏈接某個redis實例的哪一個數據庫,就比如一個mysql中建立多個數據庫,客戶端鏈接時指定鏈接哪一個數據庫。
一個redis實例最多可提供16個數據庫,下標從0到15,客戶端默認鏈接第0號數據庫,也能夠經過select選擇鏈接哪一個數據庫,以下鏈接1號庫:
鏈接0號數據庫:
5.2.2 將newkey移植到1號庫
move newkey 1:將當前庫的key移植到1號庫中
5.2.3 注意問題
在0號數據庫存儲數據,在1號數據庫執行清空數據命令卻把0號數據庫的數據給清空了:
建議:不一樣的應用系統要使用不一樣的redis實例而不是使用同一個redis實例下的不一樣數據庫。
5.3 redis事務
5.3.1 概念
和衆多其它數據庫同樣,Redis做爲NoSQL數據庫也一樣提供了事務機制。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個命令是咱們實現事務的基石。
5.3.2 redis事務特徵
一、 在事務中的全部命令都將會被串行化的順序執行,事務執行期間,Redis不會再爲其它客戶端的請求提供任何服務,從而保證了事物中的全部命令被原子的執行
二、 和關係型數據庫中的事務相比,在Redis事務中若是有某一條命令執行失敗,其後的命令仍然會被繼續執行。
三、 咱們能夠經過MULTI命令開啓一個事務,有關係型數據庫開發經驗的人能夠將其理解爲"BEGIN TRANSACTION"語句。在該語句以後執行的命令都將被視爲事務以內的操做,最後咱們能夠經過執行EXEC/DISCARD命令來提交/回滾該事務內的全部操做。這兩個Redis命令可被視爲等同於關係型數據庫中的COMMIT/ROLLBACK語句。
四、 在事務開啓以前,若是客戶端與服務器之間出現通信故障並致使網絡斷開,其後全部待執行的語句都將不會被服務器執行。然而若是網絡中斷事件是發生在客戶端執行EXEC命令以後,那麼該事務中的全部命令都會被服務器執行。
五、 當使用Append-Only模式時,Redis會經過調用系統函數write將該事務內的全部寫操做在本次調用中所有寫入磁盤。然而若是在寫入的過程當中出現系統崩潰,如電源故障致使的宕機,那麼此時也許只有部分數據被寫入到磁盤,而另一部分數據卻已經丟失。Redis服務器會在從新啓動時執行一系列必要的一致性檢測,一旦發現相似問題,就會當即退出並給出相應的錯誤提示。此時,咱們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具能夠幫助咱們定位到數據不一致的錯誤,並將已經寫入的部分數據進行回滾。修復以後咱們就能夠再次從新啓動Redis服務器了。
5.3.3 命令解釋
l multi:開啓事務用於標記事務的開始,其後執行的命令都將被存入命令隊列,直到執行EXEC時,這些命令纔會被原子的執行,相似與關係型數據庫中的:begin transaction
l exec:提交事務,相似與關係型數據庫中的:commit
l discard:事務回滾,相似與關係型數據庫中的:rollback
5.3.4 測試
5.3.4.1 正常執行事務
5.3.4.2 失敗命令
5.3.4.3 回滾
6 jedis使用
同以前咱們講過的solrj同樣,經過jedis提供的API咱們鏈接redis服務並對其數據進行維護。並且其API與命令基本一致。
6.1 導入jar包
6.2 代碼
7 redis運維知識
7.1 redis持久化
一、 RDB持久化(默認支持,無需配置)
該機制是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。
二、 AOF持久化
該機制將以日誌的形式記錄服務器所處理的每個寫操做,在Redis服務器啓動之初會讀取該文件來從新構建數據庫,以保證啓動後數據庫中的數據是完整的。
三、 無持久化
咱們能夠經過配置的方式禁用Redis服務器的持久化功能,這樣咱們就能夠將Redis視爲一個功能增強版的memcached了。
四、 redis同時使用RDB和AOF
7.1.1 RDB
7.1.1.1 優點
一、 一旦採用該方式,那麼你的整個Redis數據庫將只包含一個文件,這對於文件備份而言是很是完美的。好比,你可能打算每一個小時歸檔一次最近24小時的數據,同時還要天天歸檔一次最近30天的數據。經過這樣的備份策略,一旦系統出現災難性故障,咱們能夠很是容易的進行恢復。
二、 對於災難恢復而言,RDB是很是不錯的選擇。由於咱們能夠很是輕鬆的將一個單獨的文件壓縮後再轉移到其它存儲介質上
三、 性能最大化。對於Redis的服務進程而言,在開始持久化時,它惟一須要作的只是fork出子進程,以後再由子進程完成這些持久化的工做,這樣就能夠極大的避免服務進程執行IO操做了。
四、 相比於AOF機制,若是數據集很大,RDB的啓動效率會更高。
7.1.1.2 劣勢
一、 若是你想保證數據的高可用性,即最大限度的避免數據丟失,那麼RDB將不是一個很好的選擇。由於系統一旦在定時持久化以前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
二、 因爲RDB是經過fork子進程來協助完成數據持久化工做的,所以,若是當數據集較大時,可能會致使整個服務器中止服務幾百毫秒,甚至是1秒鐘
7.1.1.3 配置說明Snapshotting
l save 900 1 #每900秒(15分鐘)至少有1個key發生變化,則dump內存快照。
l save 300 10 #每300秒(5分鐘)至少有10個key發生變化,則dump內存快照
l save 60 10000 #每60秒(1分鐘)至少有10000個key發生變化,則dump內存快照
7.1.2 AOF
7.1.2.1 優點
一、 該機制能夠帶來更高的數據安全性,即數據持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不一樣步。事實上,每秒同步也是異步完成的,其效率也是很是高的,所差的是一旦系統出現宕機現象,那麼這一秒鐘以內修改的數據將會丟失。而每修改同步,咱們能夠將其視爲同步持久化,即每次發生的數據變化都會被當即記錄到磁盤中。能夠預見,這種方式在效率上是最低的。至於無同步,無需多言,我想你們都能正確的理解它。
二、 因爲該機制對日誌文件的寫入操做採用的是append模式,所以在寫入過程當中即便出現宕機現象,也不會破壞日誌文件中已經存在的內容。然而若是咱們本次操做只是寫入了一半數據就出現了系統崩潰問題,不用擔憂,在Redis下一次啓動以前,咱們能夠經過redis-check-aof工具來幫助咱們解決數據一致性的問題。
三、 若是日誌過大,Redis能夠自動啓用rewrite機制。即Redis以append模式不斷的將修改數據寫入到老的磁盤文件中,同時Redis還會建立一個新的文件用於記錄此期間有哪些修改命令被執行。所以在進行rewrite切換時能夠更好的保證數據安全性。
四、 AOF包含一個格式清晰、易於理解的日誌文件用於記錄全部的修改操做。事實上,咱們也能夠經過該文件完成數據的重建。
7.1.2.2 劣勢
一、 對於相同數量的數據集而言,AOF文件一般要大於RDB文件
二、 根據同步策略的不一樣,AOF在運行效率上每每會慢於RDB。總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB同樣高效。
7.1.2.3 配置AOF
7.1.2.3.1 配置信息
dir /var/redis:能夠指定生成的AOF文件和dump文件的位置
appendonly yes:開啓AOF
appendfsync always/everysec/no:AOF策略
l always #每次有數據修改發生時都會寫入AOF文件
l everysec #每秒鐘同步一次,該策略爲AOF的缺省策略
l no #從不一樣步。高效可是數據不會被持久化
重寫AOF:若不知足重寫條件時,能夠手動重寫,命令:bgrewriteaof
7.1.2.3.2 數據恢復演示
一、 flushall操做 清空數據庫
二、 及時關閉redis服務器(防止dump.rdb)。 shutdown nosave
三、 編輯aof文件,將日誌中的flushall命令刪除並重啓服務便可
7.2 redis主從複製
7.2.1 步驟
一、 複製一份redis.conf文件並修更名稱,如:cp redis.conf redis6380.conf
二、 修改redis6380.conf文件中的
l 端口號
l 進程id號(pidfile /var/run/redis6380.pid)
l slaveof:主從複製信息
l 存放aof、rdb文件的目錄。
三、 啓動從服務器:bin/redis-cli –p 6380
7.2.2 測試
完成主從數據複製。
8 redis使用場景
一、 取最新N個數據的操做
好比典型的取你網站的最新文章,經過下面方式,咱們能夠將最新的5000條評論的ID放在Redis的List集合中,並將超出集合部分從數據庫獲取
(1)使用LPUSH latest.comments <ID>命令,向list集合中插入數據
(2)插入完成後再用LTRIM latest.comments 0 5000命令使其永遠只保存最近5000個ID
(3)而後咱們在客戶端獲取某一頁評論時能夠用下面的邏輯(僞代碼)
# 僞代碼
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
若是你還有不一樣的篩選維度,好比某個分類的最新N條,那麼你能夠再建一個按此分類的List,只存ID的話,Redis是很是高效的。
二、 排行榜應用,取TOP N操做
這個需求與上面需求的不一樣之處在於,前面操做以時間爲權重,這個是以某個條件爲權重,好比按頂的次數排序,這時候就須要咱們的sorted set出馬了,將你要排序的值設置成sorted set的score,將具體的數據設置成相應的value,每次只須要執行一條ZADD命令便可。
三、 須要精準設定過時時間的應用
好比你能夠把上面說到的sorted set的score值設置成過時時間的時間戳,那麼就能夠簡單地經過過時時間排序,定時清除過時數據了,不只是清除Redis中的過時數據,你徹底能夠把 Redis裏這個過時時間當成是對數據庫中數據的索引,用Redis來找出哪些數據須要過時刪除,而後再精準地從數據庫中刪除相應的記錄。
四、 計數器應用
Redis的命令都是原子性的,你能夠輕鬆地利用INCR,DECR命令來構建計數器系統。
五、 Uniq操做,獲取某段時間全部數據排重值
這個使用Redis的set數據結構最合適了,只須要不斷地將數據往set中扔就好了,set意爲集合,因此會自動排重。
六、 實時系統,反垃圾系統
經過上面說到的set功能,你能夠知道一個終端用戶是否進行了某個操做,能夠找到其操做的集合並進行分析統計對比等。沒有作不到,只有想不到。
七、 Pub/Sub構建實時消息系統
Redis的Pub/Sub系統能夠構建實時的消息系統,好比不少用Pub/Sub構建的實時聊天系統的例子。
八、 構建隊列系統
使用list能夠構建隊列系統,使用sorted set甚至能夠構建有優先級的隊列系統。