① 如何查詢redis的緩存文件路徑
1、首先找到redis的安裝目錄,如下圖測試環境目錄,進入到/opt/install/redis-2.8.19/src,如下圖所示。
② redis做mysql的緩存
redis緩存其實就是把經常訪問的數據放到redis裡面,用戶查詢的時候先去redis查詢,沒有查到就執行sql語句查詢,同時把數據同步到redis裡面。redis只做讀操作,在內存中查詢速度快。
使用redis做緩存必須解決兩個問題,首先就是確定用何種數據結構存儲來自mysql的數據;確定數據結構之後就是需要確定用什麼標識來作為數據的key。
mysql是按照表存儲數據的,這些表是由若干行組成。每一次執行select查詢,mysql都會返回一個結果集,這個結果是由若干行組成的。redis有五種數據結構:列表list,哈希hash,字元串string,集合set,sorted set(有序集合),對比幾種數據結構,string和hash是比較適合存儲行的數據結構,可以把數據轉成json字元串存入redis。
全量遍歷鍵: keys pattern keys *
有人說 KEYS 相當於關系性數據的庫的 select * ,在生產環境幾乎是要禁用的
不管上面說的對不對, keys 肯定是有風險的。那我們就換一種方案,在存數據的時候。把數據的鍵存一下,也存到redis裡面選hash類型,那麼取的時候就可以直接通過這個hash獲取所有的值,自我感覺非常好用!
③ Redis緩存過期機制
一、針對與設置了過期時間的key值
1.(主動)定期刪除:定時隨機的檢查過期的key,如果過期則清理刪除
redis.conf(每秒檢查的次數1-500)配置: hz 10
2.(被動)惰性刪除:當客戶端請求到一個已經過期的key時,redis會檢查是否過期並刪除
所以,雖然key過期了,但是沒被清理的話,還是會占內存的。
二、內存淘汰管理機制Memory Management
當內存占滿之後,redis提供緩存淘汰機制。
redis.conf: maxmemory <bytes>
* noeviction:舊緩存永不過期,新緩存設置不了,返回錯誤
* allkeys-lru:清除最少用的舊緩存,然後保存新的緩存(推薦使用)
* allkeys-random:在所有的緩存中隨機刪除(不推薦)
* volatile-lru:在那些設置了expire過期時間的緩存中,清除最少用的舊緩存,然後保存新的緩存
* volatile-random:在那些設置了expire過期時間的緩存中,隨機刪除緩存
* volatile-ttl:在那些設置了expire過期時間的緩存中,刪除即將過期的
④ redis緩存原理
1、Redis是一種內存高速cache,如果使用redis緩存,那經常被訪問的內容會被緩存在內存中,需要使用的時候直接從內存調取,不知道比硬碟調取快了多少倍,並且支持復雜的數據結構,應用於許多高並發的場景中。
2、Redis支持主從同步。數據可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹復制。存檔可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。zset是set的一個升級版本,他在set的基礎上增加了一個順序屬性,這一屬性在添加修改元素的時候可以指定,每次指定後,zset會自動重新按新的值調整順序。可以理解了有兩列的mysql表,一列存value,一列存順序。操作中key理解為zset的名字。
更多關於redis緩存原理,進入:https://www.abcgonglue.com/ask/66eab61616100681.html?zd查看更多內容
⑤ 緩存-redis 三種模式搭建和運行原理
標簽: redis 緩存 主從 哨兵 集群
本文簡單的介紹redis三種模式在linux的安裝部署和數據存儲的總結,希望可以相互交流相互提升。
對於Centos7在安裝redis之前需要進行一些常用工具的安裝:
關閉防火牆
正式安裝redis
在redis進行maketest時候會出現一系列的異常,有如下解決方案:
用redis-server啟動一下redis,做一些實驗沒什麼意義。
要把redis作為一個系統的daemon進程去運行的,每次系統啟動,redis進程一起啟動,操作不走如下:
RDB和AOF是redis的一種數據持久化的機制。 持久化 是為了避免系統在發生災難性的系統故障時導致的系統數據丟失。我們一般會將數據存放在本地磁碟,還會定期的將數據上傳到雲伺服器。
RDB 是redis的snapshotting,通過redis.conf中的save配置進行設置,如 save 60 1000:
AOF 是以appendonly方式進行數據的儲存的,開啟AOF模式後,所有存進redis內存的數據都會進入os cache中,然後默認1秒執行一次fsync寫入追加到appendonly.aof文件中。一般我們配置redis.conf中的一下指令:
AOF和RDB模式我們一般在生產環境都會打開,一般而言,redis服務掛掉後進行重啟會優先家在aof中的文件。
當啟動一個slave node的時候,它會發送一個PSYNC命令給master node,如果這是slave node重新連接master node,那麼master node僅僅會復制給slave部分缺少的數據;否則如果是slave node第一次連接master node,那麼會觸發一次full resynchronization;
開始full resynchronization的時候,master會啟動一個後台線程,開始生成一份RDB快照文件,同時還會將從客戶端收到的所有寫命令緩存在內存中。RDB文件生成完畢之後,master會將這個RDB發送給slave,slave會先寫入本地磁碟,然後再從本地磁碟載入到內存中。然後master會將內存中緩存的寫命令發送給slave,slave也會同步這些數據。
slave node如果跟master node有網路故障,斷開了連接,會自動重連。master如果發現有多個slave node都來重新連接,僅僅會啟動一個rdb save操作,用一份數據服務所有slave node。
從redis 2.8開始,就支持主從復制的斷點續傳,如果主從復制過程中,網路連接斷掉了,那麼可以接著上次復制的地方,繼續復制下去,而不是從頭開始復制一份。
master node會在內存中常見一個backlog,master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。如果master和slave網路連接斷掉了,slave會讓master從上次的replica offset開始繼續復制,但是如果沒有找到對應的offset,那麼就會執行一次resynchronization。
master在內存中直接創建rdb,然後發送給slave,不會在自己本地落地磁碟了,可以有如下配置:
slave不會過期key,只會等待master過期key。如果master過期了一個key,或者通過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。
在redis.conf配置文件中,上面的參數代表至少需要3個slaves節點與master節點進行連接,並且master和每個slave的數據同步延遲不能超過10秒。一旦上面的設定沒有匹配上,則master不在提供相應的服務。
sdown達成的條件很簡單,如果一個哨兵ping一個master,超過了 is-master-down-after-milliseconds 指定的毫秒數之後,就主觀認為master宕機
sdown到odown轉換的條件很簡單,如果一個哨兵在指定時間內,收到了 quorum 指定數量的其他哨兵也認為那個master是sdown了,那麼就認為是odown了,客觀認為master宕機
如果一個slave跟master斷開連接已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那麼slave就被認為不適合選舉為master
(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
每次一個哨兵要做主備切換,首先需要quorum數量的哨兵認為odown,然後選舉出一個slave來做切換,這個slave還得得到majority哨兵的授權,才能正式執行切換;
(2)SENTINEL RESET *,在所有sentinal上執行,清理所有的master狀態
(3)SENTINEL MASTER mastername,在所有sentinal上執行,查看所有sentinal對數量是否達成了一致
4.3.2 slave的永久下線
讓master摘除某個已經下線的slave:SENTINEL RESET mastername,在所有的哨兵上面執行.
redis的集群模式為了解決系統的橫向擴展以及海量數據的存儲問題,如果你的數據量很大,那麼就可以用redis cluster。
redis cluster可以支撐N個redis master,一個master上面可以掛載多個slave,一般情況我門掛載一個到兩個slave,master在掛掉以後會主動切換到slave上面,或者當一個master上面的slave都掛掉後,集群會從其他master上面找到冗餘的slave掛載到這個master上面,達到了系統的高可用性。
2.1 redis cluster的重要配置
2.2 在三台機器上啟動6個redis實例
將上面的配置文件,在/etc/redis下放6個,分別為: 7001.conf,7002.conf,7003.conf,7004.conf,7005.conf,7006.conf
每個啟動腳本內,都修改對應的埠號
2.3 創建集群
解決辦法是 先安裝rvm,再把ruby版本提升至2.3.3
使用redis-trib.rb命令創建集群
--replicas: 表示每個master有幾個slave
redis-trib.rb check 192.168.31.187:7001 查看狀體
3.1 加入新master
以上相同配置完成後,設置啟動腳本進行啟動;然後用如下命令進行node節點添加:
3.2 reshard一些數據過去
3.3 添加node作為slave
3.4 刪除node
⑥ Redis分布式緩存搭建
花了兩天時間整理了之前記錄的Redis單體與哨兵模式的搭建與使用,又補齊了集群模式的使用和搭建經驗,並對集群的一些個原理做了理解。
筆者安裝中遇到的一些問題:
如果make報錯,可能是沒裝gcc或者gcc++編輯器,安裝之 yum -y install gcc gcc-c++ kernel-devel ,有可能還是提示一些個c文件編譯不過,gcc -v查看下版本,如果不到5.3那麼升級一下gcc:
在 /etc/profile 追加一行 source /opt/rh/devtoolset-9/enable
scl enable devtoolset-9 bash
重新make clean, make
這回編譯通過了,提示讓你最好make test一下/
執行make test ,如果提示 You need tcl 8.5 or newer in order to run the Redis test
那就升級tcl, yum install tcl
重新make test,如果還有error就刪了目錄,重新tar包解壓重新make , make test
o/ All tests passed without errors! ,表示編譯成功。
然後make install即可。
直接運行命令: ./redis-server /usr/redis-6.0.3/redis.conf &
redis.conf 配置文件里 bind 0.0.0.0 設置外部訪問, requirepass xxxx 設置密碼。
redis高可用方案有兩種:
常用搭建方案為1主1從或1主2從+3哨兵監控主節點, 以及3主3從6節點集群。
(1)sentinel哨兵
/usr/redis-6.0.3/src/redis-sentinel /usr/redis-6.0.3/sentinel2.conf &
sentinel2.conf配置:
坑1:master節點也會在故障轉移後成為從節點,也需要配置masterauth
當kill master進程之後,經過sentinel選舉,slave成為了新的master,再次啟動原master,提示如下錯誤:
原因是此時的master再次啟動已經是slave了,需要向現在的新master輸入密碼,所以需要在master.conf
中配置:
坑2:哨兵配置文件要暴露客戶端可以訪問到的master地址
在 sentinel.conf 配置文件的 sentinel monitor mymaster 122.xx.xxx.xxx 6379 2 中,配置該哨兵對應的master名字、master地址和埠,以及達到多少個哨兵選舉通過認為master掛掉。其中master地址要站在redis訪問者(也就是客戶端)的角度、配置訪問者能訪問的地址,例如sentinel與master在一台伺服器(122.xx.xxx.xxx)上,那麼相對sentinel其master在本機也就是127.0.0.1上,這樣 sentinel monitor mymaster 127.0.0.1 6379 2 邏輯上沒有問題,但是如果另外伺服器上的springboot通過lettuce訪問這個redis哨兵,則得到的master地址為127.0.0.1,也就是springboot所在伺服器本機,這顯然就有問題了。
附springboot2.1 redis哨兵配置:
坑3:要注意配置文件.conf會被哨兵修改
redis-cli -h localhost -p 26379 ,可以登到sentinel上用info命令查看一下哨兵的信息。
曾經遇到過這樣一個問題,大致的信息如下
slaves莫名其妙多了一個,master的地址也明明改了真實對外的地址,這里又變成127.0.0.1 !
最後,把5個redis進程都停掉,逐個檢查配置文件,發現redis的配置文件在主從哨兵模式會被修改,master的配置文件最後邊莫名其妙多了一行replicaof 127.0.0.1 7001, 懷疑應該是之前配置錯誤的時候(見坑2)被哨兵動態加上去的! 總之,實踐中一定要多注意配置文件的變化。
(2)集群
當數據量大到一定程度,比如幾十上百G,哨兵模式不夠用了需要做水平拆分,早些年是使用codis,twemproxy這些第三方中間件來做分片的,即 客戶端 -> 中間件 -> Redis server 這樣的模式,中間件使用一致性Hash演算法來確定key在哪個分片上。後來Redis官方提供了方案,大家就都採用官方的Redis Cluster方案了。
Redis Cluster從邏輯上分16384個hash slot,分片演算法是 CRC16(key) mod 16384 得到key應該對應哪個slot,據此判斷這個slot屬於哪個節點。
每個節點可以設置1或多個從節點,常用的是3主節點3從節點的方案。
reshard,重新分片,可以指定從哪幾個節點移動一些hash槽到另一個節點去。重新分片的過程對客戶端透明,不影響線上業務。
搭建Redis cluster
redis.conf文件關鍵的幾個配置:
啟動6個集群節點
[root@VM_0_11_centos redis-6.0.3]# ps -ef|grep redis
root 5508 1 0 21:25 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7001 [cluster]
root 6903 1 0 21:32 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7002 [cluster]
root 6939 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7003 [cluster]
root 6966 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7004 [cluster]
root 6993 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7005 [cluster]
root 7015 1 0 21:33 ? 00:00:00 /usr/redis-6.0.3/src/redis-server 0.0.0.0:7006 [cluster]
這時候這6個節點還是獨立的,要把他們配置成集群:
說明: -a xxxx 是因為筆者在redis.conf中配置了requirepass xxxx密碼,然後 --cluster-replicas 1 中的1表示每個master節點有1個從節點。
上述命令執行完以後會有一個詢問: Can I set the above configuration? yes同意自動做好的分片即可。
最後 All 16384 slots covered. 表示集群中16384個slot中的每一個都有至少有1個master節點在處理,集群啟動成功。
查看集群狀態:
坑1:暴露給客戶端的節點地址不對
使用lettuce連接發現連不上,查看日誌 Connection refused: no further information: /127.0.0.1:7002 ,跟之前哨兵配置文件sentinel.conf里邊配置master地址犯的錯誤一樣,集群啟動的時候帶的地址應該是提供給客戶端訪問的地址。
我們要重建集群:先把6個redis進程停掉,然後刪除 nodes-7001.conf 這些節點配置文件,刪除持久化文件 mp.rdb 、 appendonly.aof ,重新啟動6個進程,在重新建立集群:
然後,還是連不上,這次報錯 connection timed out: /172.xx.0.xx:7004 ,發現連到企鵝雲伺服器的內網地址上了!
解決辦法,修改每個節點的redis.conf配置文件,找到如下說明:
所以增加配置:
然後再重新構建集群,停進程、改配置、刪除節點文件和持久化文件、啟動進程、配置集群。。。再來一套(累死了)
重新使用Lettuce測試,這次終於連上了!
坑2:Lettuce客戶端在master節點故障時沒有自動切換到從節點
name這個key在7002上,kill這個進程模擬master下線,然後Lettuce一直重連。我們期望的是應該能自動切換到其slave 7006上去,如下圖:
重新啟動7002進程,
7006已成為新master,7002成為它的slave,然後Lettuce也能連接上了。
解決辦法,修改Lettuce的配置:
筆者用的是springboot 2.1 spring-boot-starter-data-redis 默認的Lettuce客戶端,當使用Redis cluster集群模式時,需要配置一下 RedisConnectionFactory 開啟自適應刷新來做故障轉移時的自動切換從節點進行連接。
重新測試:停掉master 7006,這次Lettuce可以正常切換連到7002slave上去了。(仍然會不斷的在日誌里報連接錯誤,因為需要一直嘗試重連7006,但因為有7002從節點頂上了、所以應用是可以正常使用的)
Redis不保證數據的強一致性
Redis並不保證數據的強一致性,也就是取CAP定理中的AP
關於一致性Hash演算法,可以參考 一致性Hash演算法 - (jianshu.com)
Redis cluster使用的是hash slot演算法,跟一致性Hash演算法不太一樣,固定16384個hash槽,然後計算key落在哪個slot里邊(計算key的CRC16值再對16384取模),key找的是slot而不是節點,而slot與節點的對應關系可以通過reshard改變並通過gossip協議擴散到集群中的每一個節點、進而可以為客戶端獲知,這樣key的節點定址就跟具體的節點個數沒關系了。也同樣解決了普通hash取模演算法當節點個數發生變化時,大量key對應的定址都發生改動導致緩存失效的問題。
比如集群增加了1個節點,這時候如果不做任何操作,那麼新增加的這個節點上是沒有slot的,所有slot都在原來的節點上且對應關系不變、所以沒有因為節點個數變動而緩存失效,當reshard一部分slot到新節點後,客戶端獲取到新遷移的這部分slot與新節點的對應關系、定址到新節點,而沒遷移的slot仍然定址到原來的節點。
關於熱遷移,猜想,內部應該是先做復制遷移,等遷移完了,再切換slot與節點的對應關系,復制沒有完成之前仍按照原來的slot與節點對應關系去原節點訪問。復制結束之後,再刪除原節點上已經遷移的slot所對應的key。
與哨兵模式比較類似,當1個節點發現某個master節點故障了、會對這個故障節點進行pfail主觀宕機,然後會通過gossip協議通知到集群中的其他節點、其他節點也執行判斷pfail並gossip擴散廣播這一過程,當超過半數節點pfail時那麼故障節點就是fail客觀宕機。接下來所有的master節點會在故障節點的從節點中選出一個新的主節點,此時所有的master節點中超過半數的都投票選舉了故障節點的某個從節點,那麼這個從節點當選新的master節點。
所有節點都持有元數據,節點之間通過gossip這種二進制協議進行通信、發送自己的元數據信息給其他節點、故障檢測、集群配置更新、故障轉移授權等等。
這種去中心化的分布式節點之間內部協調,包括故障識別、故障轉移、選主等等,核心在於gossip擴散協議,能夠支撐這樣的廣播協議在於所有的節點都持有一份完整的集群元數據,即所有的節點都知悉當前集群全局的情況。
Redis高可用方案 - (jianshu.com)
面試題:Redis 集群模式的工作原理能說一下么 - 雲+社區 - 騰訊雲 (tencent.com)
深度圖解Redis Cluster原理 - detectiveHLH - 博客園 (cnblogs.com)
Redis學習筆記之集群重啟和遇到的坑-阿里雲開發者社區 (aliyun.com)
雲伺服器Redis集群部署及客戶端通過公網IP連接問題
⑦ redis源碼解讀:單線程的redis是如何實現高速緩存的
redis可能是最近幾年最火的緩存資料庫方案了,在各個高並發領域都有應用。
這篇文章,我們將從源代碼的角度來分析一下,為何如此一個高性能,高應用的緩存,會是單線程的方案,當然一個方案的高性能,高並發是多方面的綜合因素,其它的因素我們將在後續解讀。後續分析主要以LINUX操作系統為基礎,這也是redis應用最廣的平台。
單線程最大的受限是什麼?就是CPU,現在伺服器一般已經是多CPU,而單線程只能使用到其中的一個核。
redis作為一個網路內存緩存資料庫,在實現高性能時,主要有4個點。
1.網路高並發,高流量的數據處理。
一個非同步,高效,且對CPU要求不高的網路模型,這個模型主要是由OS來提供的,目前在LINUX最主流使用的是EPOLL,這個網上介紹很多,主要是基於事件驅動的一個非同步模型。
2.程序內部的合理構架,調用邏輯,內存管理。
redis在採用純C實現時,整體調用邏輯很短,但在內存方面,適當的合並了一些對象和對齊,比如sds等,在底層使用了內存池,在不同情況下使用的不太一樣。
但整體處理上沒有NGINX的內池設計巧妙,當然二者不太一樣,NGINX是基於請求釋放的邏輯來設計的,因此針對請求,可以一次申請大塊,分量使用,再最後統一釋放。
3.數據復制的代價,不管是讀取數據或是寫入數據,一般都是需要有數據復制的過程。
數據復制其實就是一次內存,真正的代價是在於存在大VALUE,當value值長度超過16KB時,性能會開始下降。因為單線程的原因,如果存在一個超大VALUE,比如20MB,則會因為這個請求卡住整個線程,導致後續的請求進不來,雖然後面的請求是能快速處理的小請求。
4.redis中數據結構中演算法的代價,有些結構在大數據量時,代價是很高的。
很多時間,大家忽略了演算法的運算代碼,因為像memcached等這類是完全的KV緩存,不存在什麼演算法,除了一個KEY的查找定位HASH演算法。
而redis不一樣,提供了不少高階的數據對象,這些對象具有上層的一些演算法能力,而這些能力是需要比如GEO模塊。
⑧ redis刪除某個目錄下的緩存
可以
1.首先進到redis的安裝目錄,進到src目錄下,找到redis-cli
2.首先用賬號密碼的方式進入到redis的服務端
./redis-cli -h 127.0.0.1 -p 6379 -a 1234
進去後會出現下面的界面ip:port>,你就可以操作啦
flushdb ——> 清空當前資料庫中的所有 key
flushall ——> 清空整個 Redis 伺服器的數據(刪除所有資料庫的所有 key )
到這里就清除完畢,不需要重啟,不過大家要注意,你們伺服器的緩存數據是否重要,是否可以清除,一定要確定清楚,否則不要輕易清除。
⑨ redis緩存原理
redis緩存原理是sql語句時key值,查詢結果resultSet是value,當同一個查詢語句訪問時(select * from t_proct),只要曾經查詢過,調用緩存直接返回resultSet,節省了資料庫讀取磁碟數據的時間。
redis的存儲分為內存存儲、磁碟存儲和log文件三部分,配置文件中有三個參數對其進行配置。
save seconds updates,save配置,指出在多長時間內,有多少次更新操作,就將數據同步到數據文件。這個可以多個條件配合,比如默認配置文件中的設置,就設置了三個條件。
appendonly yes/no ,appendonly配置,指出是否在每次更新操作後進行日誌記錄,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為redis本身同步數據文件是按上面的save條件來同步的,所以有的數據會在一段時間內只存在於內存中。
(9)reids緩存擴展閱讀
redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系資料庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。
Redis支持主從同步。數據可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹復制。
存檔可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。
redis的官網地址,redis.io。(域名後綴io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)
⑩ Redis緩存雪崩就這么簡單
在實際項目開發中,我們都知道Redis不可能把所有的數據都緩存起來( 內存昂貴且有限 ),所以Redis需要對數據設置過期時間,並採用的是惰性刪除+定期刪除兩種策略對過期鍵刪除。
如果緩存數據 設置的過期時間是相同 的,並且Redis恰好將這部分數據全部刪光了。這就會導致在這段時間內,這些緩存 同時失效 ,全部請求到資料庫中。
這就是緩存雪崩 :
緩存雪崩如果發生了,很可能就把我們的資料庫 搞垮 ,導致整個服務癱瘓,造成的後果很嚴重。
對緩存數據設置相同的過期時間,導致某段時間內緩存失效。」
對於「Redis掛掉了」,我們可以有以下的思路: