redis
1. 含義:
- 基於內存的高性能key-value數據庫
2. 安裝
docker run -d --name redis -p 6379:6379 redis:2.8
3. 鑑權登錄
修改redis.conf配置文件,然後重啓服務
requirepass 123 指定密碼123
4. 工具使用
redis-server
: 用於啓動redis服務端redis-cli
: redis 客戶端, 使用命令redis-cli -h 127.0.0.1 -p 6379
連接redis服務器redis-check-dump
: redis dump數據文件的修復工具,導入失敗,用於修復導入文件redis-check-aof
: redis aof日誌文件修復工具,重啓服務失敗時,用於修復日誌文件redis-sentinel
: 用於實現redis集羣高可用(自動切換master和服務發現)redis-benchmark
: redis性能檢測工具
5. 基本數據類型鍵操作命令
6. 訂閱發佈
7. 事務
- redis事務不支持回滾;
- redis事務是僞原子性的,要不全部執行,要不全部不執行,事務中可能會執行失敗,但是Redis事務不會回滾,而是繼續會執行餘下的命令.redis事務一旦開始,除非服務停止,否則不會回滾。
8. 性能優化
- 讀寫分離: redis支持主從模式。redis的Master會將數據同步到slave,而slave不會將數據同步到master。Slave啓動時會連接master來同步數據。因此Master寫內存快照,save命令調度rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫內存快照。
- slave開啓AOF備份數據,而非master。 Master AOF持久化,如果不重寫AOF文件,這個持久化方式對性能的影響是最小的,但是AOF文件會不斷增大,AOF文件過大會影響Master重啓的恢復速度。Master最好不要做任何持久化工作,推薦爲某個Slave開啓AOF備份數據,策略爲每秒同步一次。
- redis主從在同一個局域網內: Redis主從複製的性能問題,爲了主從複製的速度和連接的穩定性,Slave和Master最好在同一個局域網內
9. redis的優點
- 操作都是原子性,所謂原子性就是對數據的更改要麼全部執行,要不全部不執行。
- 訂閱發佈模式
- 可設置緩存過期時間
- 單線程,事件驅動,IO多路複用,利用redis隊列技術並將訪問變爲串行訪問,消除了傳統數據庫串行控制的開銷
- redis速度快,因爲數據存在內存中
- redis支持豐富的數據類型
- redis可持久化,
- 緩存以支持高併發
- 支持事務,所有的命令要麼都被一起處理,要麼全都沒有被處理。如果在事務中可能會執行失敗,但是Redis事務不會回滾,而是繼續會執行餘下的命令。如果操作執行一半中斷後,重啓服務後會Redis在重新啓動時會檢測這種情況,並報錯,然後退出。使用 redis-check-aof工具可以檢查AOF,並移除那不完整的事務,使服務可以再次啓動
10. redis相關問題
- 可擴展性,所以出現了codis(redis+zookeeper)
- 緩存預熱: 系統上線後,將相關的緩存數據直接加載到緩存系統。這樣避免用戶請求的時候,再去加載相關的數據
- 緩存雪崩問題: 緩存雪崩是指在某一個時間段,緩存集中過期失效,所有請求都去查詢數據庫,而對數據庫CPU和內存造成巨大壓力,嚴重的會造成數據庫宕機。如果是單個緩存出現這樣的問題一般問題不大,數據庫能扛得住這個壓力,如果必須單個點可以在緩存過期前重新set緩存,或者直接設置一個超長緩存或永久緩存;但如果某臺redis服務器掛掉,則會出現嚴重的緩存雪崩問題, 只能做好監控,然後快速的添加機器恢復緩存數據。
- 緩存擊穿問題: 緩存穿透是指用戶查詢數據,在數據庫沒有,自然在緩存中也不會有。這樣就導致用戶查詢的時候,在緩存中找不到,每次都要去數據庫再查詢一遍,然後返回空。這樣請求就繞過緩存直接查數據庫,這也是經常提的緩存命中率問題。解決的辦法就是:如果查詢數據庫也爲空,直接設置一個默認值存放到緩存,再次查詢就直接返回空了,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫。
- 緩存的併發競爭問題: 主要是併發寫問題, 即假設有某個key = "price", value值爲10,現在想把value值進行+10操作。正常邏輯下,就是先把數據key爲price的值讀回來,加上10,再把值給設置回去。如果只有一個連接的情況下,這種方式沒有問題,可以工作得很好,但如果有兩個連接時,兩個連接同時想對price進行+10操作,就可能會出現問題了。這種問題比較通用的解決方法是事務。
- redis機器master之間一致性問題(擴容縮容如何保持master一致性
- redis分佈式鎖:事務中實現;
11. redis爲什麼那麼快
- 在內存中操作
- 單線程,避免了頻繁的上下文切換;
- 非阻塞I/O多路複用: 很多個網絡I/O複用一個或少量的線程(TCP連接)來處理這些連接
12. redis的key回收策略
- redis的key回收機制:redis採用的是定期刪除+惰性刪除策略。如果採用定時刪除,則會耗CPU;故採用定期刪除+惰性刪除策略。
- 惰性淘汰機制: 在進行get或setnx等操作時,先檢查key是否過期,若過期,刪除key,然後執行相應操作; 若沒過期,直接執行相應操作;
- 定期刪除:是主動刪除機制, redis每隔一段時間隨機取一部分key進行過期判斷,如果過期則刪除;服務端定時的去檢查失效的緩存,如果失效則進行相應的操作。【redis基於事件驅動的,一類是IO事件,一類是定時事件】
redis的key回收過程: 無論是惰性淘汰機制還是定期刪除機制,都是先從expires中查找key的過期時間,如果不存在說明對應key沒有設置過期時間,直接返回,如果是slave機器,則直接返回,因爲Redis爲了保證數據一致性且實現簡單,將緩存失效的主動權交給Master機器,slave機器沒有權限將key失效。如果當前是Master機器,且key過期,則master會做兩件重要的事情:1)將刪除命令寫入AOF文件。2)通知Slave當前key失效,可以刪除了。master從本地的字典中將key對於的值刪除;
- redis的key回收方式
配置文件裏redis.conf
的maxmemory_policy:noeviction
用以設置緩存到期後的數據淘汰機制,默認爲noeviction- volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
- volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰
- volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰
- allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
- allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
- noeviction(驅逐):禁止驅逐數據
13. redis的兩種數據持久化方案
redis允許採用RDB和AOF兩種方案提供了將數據定期自動持久化至硬盤的能力,兩者的區別在於RDB同步的是數據,AOF同步的是操作。
1. RDB
- 說明: Redis會定期保存數據快照至一個rbd文件中,並在啓動時自動加載rdb文件,恢復之前保存的數據
配置
# 時間策略 save 900 1 # 如果900s內有1條寫入命令,就觸發產生一次快照,進行一次備份; save 300 10 save 60 10000 # save "" # 如果設置成""則禁用RDB # 當備份進程出錯時,主進程就停止接受新的寫入操作,是爲了保護持久化的數據一致性 stop-writes-on-bgsave-error yes # 是否壓縮 rdbcompression yes # 導入時是否檢查 rdbchecksum yes # 文件名 dbfilename dump.rdb # 文件會被寫到dir裏 dir
- 優點
- 對性能影響最小。如前文所述,Redis在保存RDB快照時會fork出子進程進行,幾乎不影響Redis處理客戶端請求的效率。
- 每次快照會生成一個完整的數據快照文件,所以可以輔以其他手段保存多個時間點的快照
- 使用RDB文件進行數據恢復比使用AOF要快很多。
- 缺點
- 快照是定期生成的,所以在Redis crash時或多或少會丟失一部分數據
- 如果數據集非常大且CPU不夠強(比如單核CPU),Redis在fork子進程時可能會消耗相對較長的時間,影響Redis對外提供服務的能力。
2. AOF
- 說明: AOF持久方式時,Redis會把每一個寫請求都記錄在一個日誌文件裏。在Redis重啓時,會把AOF文件中記錄的所有寫操作順序執行一遍,確保數據恢復到最新
-
# 開啓AOF模式 appendonly: yes # AOF文件名 appendfilename "appendonly.aof" # 三種文件同步策略, no,不設置同步策略,由系統決定; everysec,後臺線程每秒同步一次; always:每寫入一條日誌同步一次,數據安全性最高,速度最慢; appendfsync everysec # AOF自動重寫機制 # 在重寫階段是否允許同步 no-appendfsync-on-rewrite no # redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小比基礎大小大制定的百分比, 或者如果現在的大小比基礎大小大制定的百分比,是上次rewrite後大小的一倍且文件大於64M時觸發。默認64M。 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # redis在恢復時,會忽略最後一條可能存在問題的指令 aof-load-truncated yes
- 優點
- 同步所有寫操作,安全性高
- 缺點
- 相同數據集的數據而言aof文件要遠大於rdb文件,恢復速度慢於rdb
3. redis的導入導出
- 使用redis-dump
- aof導入方式
redis.conf
裏配置appendonly yes
,- cp appendonly.aof 到redis的數據庫目錄也就是配置文件裏面的dir關鍵字
- 重啓服務
- rdb導入方式
redis.conf
裏配置appendonly no
,- cp dump.rdb 到redis的數據庫目錄也就是配置文件裏面的dir關鍵字
- 重啓服務
14. redis和mencache相比的優缺點
- memcache所有的值均是簡單的字符串,redis支持更爲豐富的數據類型;
- redis速度比memcached快很多
- redis可以持久化
- redis最大可以達到1GB,而memcache只有1MB
- redis原生支持集羣模式
- redis 只使用單核,而 memcached 可以使用多核,所以平均每一個核上 redis 在存儲小數據時比 memcached 性能更高。而在 100k 以上的數據中,memcached 性能要高於 redis,雖然 redis 最近也在存儲大數據的性能上進行優化,但是比起 memcached,還是稍有遜色。
15. redis應用場景
- 會話緩存(session)
- 數據或頁面緩存
- 隊列(list)
- 訂閱發佈模式(subscribe)
- 排行榜(有序集合,zadd,zrange)
- 計數器(字符串 + incr)