由於它全部的數據都在內存中,全部的運算都是內存級別的運算,並且單線程避免了多線程的切換性能損耗問題。正由於 Redis 是單線程,因此要當心使用 Redis 指令,對於那些耗時的指令(好比keys),必定要謹慎使用,一不當心就可能會致使 Redis 卡頓。redis
官方提供的數據: 10萬+QPS(query per second,每秒內查詢次數)數據庫
徹底基於內存,絕大部分請求是純粹的內存操做,執行效率高緩存
數據結構簡單,對數據操做也簡單(它不使用表,它的數據庫不會預約義或者強制去要求用戶對redis的存儲進行關聯。存儲結構就是鍵值對,相似於hashMap,查找和操做時間的複雜度都是低的)安全
採用單線程,單線程也能處理高併發請求,想多核也能夠啓動多個實例。(redis的主線程是單線程的,主線程負責io事件的處理以及io對應的相關請求的事件處理,還負責過時鍵的處理,賦值協調,集羣協調等等。這些除了io事件的邏輯會被封裝成周期性的任務,由主線程週期性處理。全部對於客戶端的全部讀寫請求都是由一個主線程的串行處理。所以多個客戶端對一個鍵進行寫操做的時候,不會有併發的問題。避免了頻繁的上下文切換和鎖競爭的問題。這效率更高。)服務器
使用多路I/O複用模型,非阻塞IO數據結構
Redis的IO多路複用:redis利用epoll來實現IO多路複用,將鏈接信息和事件放到隊列中,依次放到文件事件分派器,事件分派器將事件分發給事件處理器。多線程
Nginx也是採用IO多路複用原理解決C10K問題併發
在默認狀況下, Redis 將內存數據庫快照保存在名字爲 dump.rdb 的二進制文件中。保存某個時間點的全量數據快照。app
save 900 1 ==>900秒內有1條是更改(增刪改)指令,就產生一次快照,進行了一次備份 save 300 10 ==>300秒內有10條是更改(增刪改)指令,就產生一次快照,進行了一次備份,若是300秒內沒有到達10條寫入,就要等待900秒。 save 60 10000 ==>60秒內有10000條是更改(增刪改)指令,就產生一次快照,進行了一次備份,若是60秒內沒有到達10000條寫入,就要等待300秒。高併發
stop-writes-on-bgsave-error yes ==>yes:當備份進程出錯的時候,主進程就中止接受新的寫入操做,保護持久化的數據一致性的問題。
rdbcompression yes ==>在備份的時候,須要將rdb文件進行壓縮後採起保存。這邊通常不開啓,設置爲no,由於redis自己屬於cpu密集型服務器,在開啓壓縮會帶來更多的cpu消耗,相比硬盤成本,cpu更值錢。
dbfilename dump.rdb ===>建立備份文件名
dir ./ ===>備份文件的路徑
在save的最後配置 : save "" ===>此時將RDB的配置開啓了
RDB文件在: src/dump.rdb。此文件是一個二進制文件
SAVE:阻塞Redis的服務進程,直到RDB文件被建立完成
BGSAVE:Fork出一個子進程來傳解RDB文件,不阻塞服務器進程。
舉例: 先刪除dump.rdb,開啓一個客戶端:save ===>此時服務器卡頓,直到dump.rdb建立出來。
lastsave ===>返回一個相似時間戳的數字,記錄上次執行save的時間。
bgsave ===>保存數據,而且服務器不卡頓,通常在設計的時候按照:mv dump.rdb dumpxxxx.rdb,以這種時間戳的方式記錄某個時間點的備份。
自定觸發RDB持久化
根據redis.conf配置裏的SAVE m n定時觸發(用的是BGSAVE)
主從複製時,主節點自定觸發
直到Debug Reload
執行Shutdown且沒有開啓AOF持久化
系統調用fork():建立進程,實現Copy- on -write
RDB持久化缺點:
內存數據的全量同步,數據量大會因爲I/O而嚴重影響性能
可能會由於Redis掛掉而丟失從當前最忌一次快照期間的數據
查看rdb: src/redis-check-rdb dump.rdb
快照功能並非很是耐久(durable): 若是 Redis 由於某些緣由而形成故障停機, 那麼服務器將丟失最近寫入、且仍未保存到快照中的那些數據.
AOF(Append-Only-File)持久化:保存寫狀態 ===>redis默認是關閉的
記錄下除了查詢之外的全部變動數據庫狀態的指令
以append的形式追加保存到AOP文件中(增量)
配置文件redis.conf:
appendonly no ==>修改成yes,開啓aof持久化,默認生成文件的路徑redis/src/appendonly.aof
appendfilename "appendonly.aof" ===>aof格式持久化文件名
appendfsync everysec ==>配置aof文件寫入的方式:
always:一旦緩存區的數據發生變化,就老是及時將緩存區的內容寫入到AOF中
everysec:將緩存區的內容每隔1秒寫入AOF文件中 ===>經常使用的方式
no:將緩存區數據寫入AOF文件的操做交給操做系統來決定。
推薦(而且也是默認)的措施爲每秒 fsync 一次, 這種 fsync 策略能夠兼顧速度和安全性。
第一次啓動要開啓AOF操做,生成文件,客戶端命令:config set appendonly yes
日誌重寫解決AOF文件大小不斷增大的問題,原理以下:
調用fork(),建立一個子進程
子進程把新的AOF寫道一個臨時文件裏,不依賴原來的AOF文件
主進程持續將新的變更同時寫到內存和原來的AOF裏
主進程獲取子進程重寫AOF的完成信號,往新AOF同步增量變更
是用新的AOF文件替換調舊的AOF文件
RDB和AOF的比較:
RDB優勢:全量數據快照,文件小,恢復快
RDB缺點:沒法保存最忌一次快照以後的數據
AOF優勢:可讀性高,時候保存增量數據,數據不易丟失
AOF缺點:文件體積大,恢復時間長。
若是你很是關心你的數據, 但仍然能夠承受數分鐘之內的數據丟失, 那麼你能夠只使用 RDB 持久化。有不少用戶都只使用 AOF 持久化, 但咱們並不推薦這種方式: 由於定時生成 RDB 快照(snapshot)很是便於進行數據庫備份, 而且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快
重啓 Redis 時,咱們不多使用 rdb 來恢復內存狀態,由於會丟失大量數據。咱們一般使用 AOF 日誌重放,可是重放 AOF 日誌性能相對 rdb 來講要慢不少,這樣在 Redis 實例很大的狀況下,啓動須要花費很長的時間。 Redis 4.0 爲了解決這個問題,帶來了一個新的持久化選項——混合持久化。AOF在重寫(aof文件裏可能有太多沒用指令,因此aof會按期根據內存的最新數據生成aof文件)時將重寫這一刻以前的內存rdb快照文件的內容和增量的 AOF修改內存數據的命令日誌文件存在一塊兒,都寫入新的aof文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件纔會進行更名,原子的覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換;
AOF根據配置規則在後臺自動重寫,也能夠人爲執行命令bgrewriteaof重寫AOF。 因而在 Redis 重啓的時候,能夠先加載 rdb 的內容,而後再重放增量 AOF 日誌就能夠徹底替代以前的 AOF 全量文件重放,重啓效率所以大幅獲得提高。
開啓混合持久化:aof-use-rdb-preamble yes
混合持久化aof文件結構: appendonly.aof = RDB格式+ AOF格式
開啓混合持久化以後,set數據以後,查看生成的appendonly.aof文件:more appendonly.aof
此時生成的文集中包含RDB二進制快照數據+ AOF追加的命令數據
AOF重寫功能: 通常是redis後臺進程去作,能夠手動觸發命令: bgrewriteaof.
其實是把那些大規模的對同一個key全部的操做把它變成最終的一條set值的操做.
eg: incr requestlock
incr requestlock
incr requestlock
incr requestlock
=====>重寫以後的命令 : set requestlock 4
問題1: 混合重寫必需要aof和rdb同時設置爲yes麼 仍是混合的這個設爲yes就行?
aof和混合那個都要設爲yes,混合那個是基礎aof的
問題2: 手動重寫aof文件,若是文件很大,重寫 須要花很長時間,這個時候恰好又有新操做的數據怎麼辦?
新操做會存在內存裏,等到aof重寫完再最加到aof文件的末尾,aof重寫的數據就是重寫開始以前的內存數據
問題3: redis hash衝突後進行rehash 若是再衝突繼續rehash?到最後還會不會有衝突的結果?
不是hash衝突後立刻進行rehash,是redis擴容後以前的元素再作rehash從新定位,擴容是根據redis內部的擴容因子來計算的,跟hashmap擴容相似,衝突一直均可能有,只不過redis會盡可能經過擴容來減少衝突