1、redis簡介node
Redis是當前比較熱門的NOSQL系統之一,它是一個開源的使用ANSI c語言編寫的key-value存儲系統(區別於MySQL的二維表格的形式存儲。)。和Memcache相似,但很大程度補償了Memcache的不足。和Memcache同樣,Redis數據都是緩存在計算機內存中,不一樣的是,Memcache只能將數據緩存到內存中,沒法自動按期寫入硬盤,這就表示,一斷電或重啓,內存清空,數據丟失。因此Memcache的應用場景適用於緩存無需持久化的數據。而Redis不一樣的是它會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,實現數據的持久化。redis
2、redis與meamache區別數據庫
一、Redis和Memcache都是將數據存放在內存中,都是內存數據庫。不過memcache還可用於緩存其餘東西,例如圖片、視頻等等。緩存
二、Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。安全
三、虛擬內存--Redis當物理內存用完時,能夠將一些好久沒用到的value 交換到磁盤服務器
四、存儲數據安全--memcache掛掉後,數據沒了;redis能夠按期保存到磁盤(持久化)網絡
五、災難恢復--memcache掛掉後,數據不可恢復; redis數據丟失後能夠經過aof恢復session
六、Redis支持數據的備份,即master-slave模式的數據備份。數據結構
3、redis爲何這麼快架構
一、純內存操做;
二、單線程操做,避免了頻繁的上下文切換;
三、採用C語言編寫,而C語言因爲更加接近計算機的底層,因此速度更快;
四、採用了非阻塞I/O多路複用機制: 咱們的redis-client在操做的時候,會產生具備不一樣事件類型的socket。在服務端,有一段I/0多路複用程序,將其置入隊列之中。而後,文件事件分派器,依次去隊列中取,轉發到不一樣的事件處理器中。
4、redis的應用場景
一、緩存
二、任務隊列
三、網站訪問統計
四、數據過時處理
五、應用排行榜
六、分佈式集羣架構中的session分離
5、redis的數據類型
Redis一共支持五種數據類:string(字符串),hash(哈希),list(列表),set(集合)和zset(sorted set有序集合)。
一、String:
經常使用命令:set(賦值)/get(查詢)/decr (自減)/incr(自增)/mget(查詢多個key)
這個其實沒啥好說的, value能夠是String也能夠是數字。通常作一些複雜的計數功能的緩存。
二、hash
命令:hset(添加賦值)/hget(查詢)/hgetall(查詢全部字段和值)等。
這裏value存放的是結構化的對象,比較方便的就是操做其中的某個字段。
三、list
經常使用命令:lpush(列表頭部添加元素)/rpush(列表尾部添加元素)/lpop(頭部刪除元素)/rpop(尾部刪除元素)/lrange(查詢元素)等.
Redis列表是字符串列表,不支持嵌套其餘數據類型,是redis中有序可重複結構。能夠向列表的頭部或者尾部進行添加和刪除操做;應用的場景很是多,好比存儲文章評論列表,存儲用戶的粉絲列表,黑名單列表等,也能夠做爲重要的消息隊列來使用。
四、set
經常使用命令有sadd(添加元素)/spop(刪除)/smembers(查詢)/sunion(添加多個集合)等,基本示例以下所示。
使用:Redis集合是字符串集合,不支持嵌套其餘數據類型,不重複無序結構。與list的功能類似,可是提供了自動去重功能,而且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。另外,就是利用交集、並集、差集等操做,能夠計算共同喜愛,所有的喜愛,本身獨有的喜愛等功能。
五、sorted set
使用:Redis有序集合是在集合的基礎上增長了排序功能,規則是按照該元素對應的Score進行排序。實際應用來說主要是涉及到排序的功能場景均可以使用,例如實現文章按點擊量排序,微博熱搜榜,論壇熱帖等。sorted set多了一個權重參數score,集合中的元素可以按score進行排列。能夠作排行榜應用,取TOP N操做。sorted set在set基礎上爲每一個元素都關聯了一個分數score,經過score來實現排序功能。經常使用命令:zadd/zrange/zrem/zcard,
6、redis的缺點
實際上是緩存都有下面四個問題,通常的企業,說實話,緩存雪崩、緩存擊穿很能遇到。
一、緩存和數據庫雙寫一致性問題
二、緩存雪崩問題: 緩存同一時間大面積的失效,這個時候又來了一波請求,結果請求都懟到數據庫上,從而致使數據庫鏈接異常。
解決方案:
a、給緩存的失效時間,加上一個隨機值,避免集體失效。
b、使用互斥鎖,可是該方案吞吐量明顯降低了。
c、雙緩存。咱們有兩個緩存,緩存A和緩存B。緩存A的失效時間爲20分鐘,緩存B不設失效時間。本身作緩存預熱操做。而後細分如下幾個小點
I 從緩存A讀數據庫,有則直接返回
II A沒有數據,直接從B讀數據,直接返回,而且異步啓動一個更新線程。
III 更新線程同時更新緩存A和緩存B。
三、緩存擊穿問題: 請求緩存中不存在的數據,致使全部的請求都懟到數據庫上,從而數據庫鏈接異常。
解決方案:
a、利用互斥鎖,緩存失效的時候,先去得到鎖,獲得鎖了,再去請求數據庫。沒獲得鎖,則休眠一段時間重試
b、採用異步更新策略,不管key是否取到值,都直接返回。value值中維護一個緩存失效時間,緩存若是過時,異步起一個線程去讀數據庫,更新緩存。須要作緩存預熱(項目啓動前,先加載緩存)操做。
c、提供一個能迅速判斷請求是否有效的攔截機制,好比,利用布隆過濾器,內部維護一系列合法有效的key。迅速判斷出,請求所攜帶的Key是否合法有效。若是不合法,則直接返回。
四、緩存的併發競爭問題
7、redis的持久化
redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。其實RDB和AOF兩種方式也能夠同時使用,在這種狀況下,若是redis重啓的話,則會優先採用AOF方式來進行數據恢復,這是由於AOF方式的數據恢復完整度更高。若是你沒有數據持久化的需求,也徹底能夠關閉RDB和AOF方式,這樣的話,redis將變成一個純內存數據庫,就像memcache同樣。
一、RDB
RDB方式,是將redis某一時刻的數據持久化到磁盤中,是一種快照式的持久化方法。redis在進行數據持久化的過程當中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,纔會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓咱們能夠隨時來進行備份,由於快照文件老是完整可用的。對於RDB方式,redis會單首創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操做的,這樣就確保了redis極高的性能。若是須要進行大規模數據的恢復,且對於數據恢復的完整性不是很是敏感,那RDB方式要比AOF方式更加的高效。
雖然RDB有很多優勢,但它的缺點也是不容忽視的。若是你對數據的完整性很是敏感,那麼RDB方式就不太適合你,由於即便你每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的數據丟失。因此,redis還提供了另外一種持久化方式,那就是AOF。
二、AOF
AOF,英文是Append Only File,即只容許追加不容許改寫的文件。如前面介紹的,AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照從前到後的順序再將指令都執行一遍,就這麼簡單。咱們經過配置redis.conf中的appendonly yes就能夠打開AOF功能。若是有寫操做(如SET等),redis就會被追加到AOF文件的末尾。默認的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),由於在這種狀況下,redis仍然能夠保持很好的處理性能,即便redis故障,也只會丟失最近1秒鐘的數據。若是在追加日誌時,剛好遇到磁盤空間滿、inode滿或斷電等狀況致使日誌寫入不完整,也沒有關係,redis提供了redis-check-aof工具,能夠用來進行日誌修復。由於採用了追加方式,若是不作任何處理的話,AOF文件會變得愈來愈大,爲此,redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,redis就會啓動AOF文件的內容壓縮,只保留能夠恢復數據的最小指令集。舉個例子或許更形象,假如咱們調用了100次INCR指令,在AOF文件中就要存儲100條指令,但這明顯是很低效的,徹底能夠把這100條指令合併成一條SET指令,這就是重寫機制的原理。在進行AOF重寫時,仍然是採用先寫臨時文件,所有完成後再替換的流程,因此斷電、磁盤滿等問題都不會影響AOF文件的可用性,這點你們能夠放心。
AOF方式的另外一個好處,咱們經過一個「場景再現」來講明。某同窗在操做redis時,不當心執行了FLUSHALL,致使redis內存中的數據所有被清空了,這是很悲劇的事情。不過這也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件尚未被重寫(rewrite),咱們就能夠用最快的速度暫停redis並編輯AOF文件,將最後一行的FLUSHALL命令刪除,而後重啓redis,就能夠恢復redis的全部數據到FLUSHALL以前的狀態了。是否是很神奇,這就是AOF持久化方式的好處之一。可是若是AOF文件已經被重寫了,那就沒法經過這種方法來恢復數據了。
雖然優勢多多,但AOF方式也一樣存在缺陷,好比在一樣數據規模的狀況下,AOF文件要比RDB文件的體積大。並且,AOF方式的恢復速度也要慢於RDB方式。若是你直接執行BGREWRITEAOF命令,那麼redis會生成一個全新的AOF文件,其中便包括了能夠恢復現有數據的最少的命令集。若是運氣比較差,AOF文件出現了被寫壞的狀況,也沒必要過度擔心,redis並不會貿然加載這個有問題的AOF文件,而是報錯退出。這時能夠經過如下步驟來修復出錯的文件:
1).備份被寫壞的AOF文件
2).運行redis-check-aof –fix進行修復
3).用diff -u來看下兩個文件的差別,確認問題點
4).重啓redis,加載修復後的AOF文件
8、redis的主從複製
像MySQL同樣,redis是支持主從同步的,並且也支持一主多從以及多級從結構。主從結構,一是爲了純粹的冗餘備份,二是爲了提高讀性能,好比很消耗性能的SORT就能夠由從服務器來承擔。redis的主從同步是異步進行的,這意味着主從同步不會影響主邏輯,也不會下降redis的處理性能。主從架構中,能夠考慮關閉主服務器的數據持久化功能,只讓從服務器進行持久化,這樣能夠提升主服務器的處理性能。在主從架構中,從服務器一般被設置爲只讀模式,這樣能夠避免從服務器的數據被誤修改。可是從服務器仍然能夠接受CONFIG等指令,因此仍是不該該將從服務器直接暴露到不安全的網絡環境中。若是必須如此,那能夠考慮給重要指令進行重命名,來避免命令被外人誤執行。
主從複製的原理:從服務器會向主服務器發出SYNC指令,當主服務器接到此命令後,就會調用BGSAVE指令來建立一個子進程專門進行數據持久化工做,也就是將主服務器的數據寫入RDB文件中。在數據持久化期間,主服務器將執行的寫指令都緩存在內存中。在BGSAVE指令執行完成後,主服務器會將持久化好的RDB文件發送給從服務器,從服務器接到此文件後會將其存儲到磁盤上,而後再將其讀取到內存中。這個動做完成後,主服務器會將這段時間緩存的寫指令再以redis協議的格式發送給從服務器。另外,要說的一點是,即便有多個從服務器同時發來SYNC指令,主服務器也只會執行一次BGSAVE,而後把持久化好的RDB文件發給多個下游。在redis2.8版本以前,若是從服務器與主服務器因某些緣由斷開鏈接的話,都會進行一次主從之間的全量的數據同步;而在2.8版本以後,redis支持了效率更高的增量同步策略,這大大下降了鏈接斷開的恢復成本。
主服務器會在內存中維護一個緩衝區,緩衝區中存儲着將要發給從服務器的內容。從服務器在與主服務器出現網絡瞬斷以後,從服務器會嘗試再次與主服務器鏈接,一旦鏈接成功,從服務器就會把「但願同步的主服務器ID」和「但願請求的數據的偏移位置(replication offset)」發送出去。主服務器接收到這樣的同步請求後,首先會驗證主服務器ID是否和本身的ID匹配,其次會檢查「請求的偏移位置」是否存在於本身的緩衝區中,若是二者都知足的話,主服務器就會向從服務器發送增量內容。增量同步功能,須要服務器端支持全新的PSYNC指令。這個指令,只有在redis-2.8以後才具備。