利用下班時間,我兩星期完成了redis入門與進階

過去的兩週,小松陸陸續續看完了一門長達十幾個小時的課程 redis入門與精通。

當然,僅僅課程是不足以精通redis的,不過用來入門和窺見redis的全貌大有幫助,今天,小松就記錄一下過去兩週在redis上的學習心得。

基礎

五大基本類型

key 這是最基礎的,Redis是典型的鍵值對數據庫,key可以通過runoobkey設置,如果設置成功就會返回OK,刪除返回1。

<code>redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> DEL runoobkey
(integer) 1
複製代碼/<code>

String 這是最基礎的類型,相比起來,mysql的類型是真的多,光一個int都要好幾種。 而redis由於是key-value結構,他的key基本都是使用的String,而value也大量使用,所以String使用非常頻繁。 最簡單的時候方式是set,get,當然,也支持各種對string的操作。

<code>redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> GET runoobkey
"redis"
複製代碼/<code>

list list大家都不陌生,和數據結構一樣,使用LPush命令在左邊插入數據,RPush在右邊插入數據。 類似的,有LPop,LTrim(截取),LRem(刪除),LRANGE(查看)等操作,redis中字母不區分大小寫。 這是在菜鳥教程中截取的例子。

<code>127.0.0.1:6379>LPUSH list1 "foo"
(integer) 1
127.0.0.1:6379> LPUSH list1 "bar"
(integer) 2
127.0.0.1:6379> LRANGE list1 0 -1
1) "bar"
2) "foo"
複製代碼/<code>

set set也很簡單,命令包括SAdd,SCard(查看元素個數),SRem,SUion(取並集),SInter(取交集)等。 比如b站裡面的共同關注就是通過SInter獲取。 一個賬號的粉絲存儲在一個Set中,兩個賬號就有兩個Set,只要將兩個Set進行SInter,就可以知道同時關注這兩個賬號的人了。

<code>redis 127.0.0.1:6379> SADD runoobkey redis
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mongodb
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 0
redis 127.0.0.1:6379> SMEMBERS runoobkey

1) "mysql"
2) "mongodb"
3) "redis"
複製代碼/<code>

hash 這就是java中的map或者python中的dict,在redis中,叫做hash,案例和上面類似,就不貼了,無外乎hset,hget,hmset(批量設置),hlen等。

進階

持久化

持久化分為兩種,持久化簡單說就是要長期保存數據庫,對於長期保存一樣東西,思路就是要麼保存過程,繼而推導出結果,要麼直接保存結果,所以這就是RDB和AOF。

RDB RDB的原理是,從父進程fork一個子進程,寫入臨時RDB,然後替換原來的快照,成為正式的RDB,在此期間,父進程,也就是原有的運行進程,正常運行


利用下班時間,我兩星期完成了redis入門與進階

所以他就是做了一個對結果的備份,放在一個後綴為rdb格式的文件中而已

當需要恢復的時候,將rdb放在redis的啟動目錄,這樣,啟動redis時,rdb同步寫入redis,就完成了恢復,他有以下特點

優點: 1. 適合大規模數據恢復。 2. 適合備份數據庫,作為後備兜底用途。 缺點: 1. 需要一定時間間隔進行操作,因為不能每時每刻都備份,比如每隔1小時備份,那麼一旦宕機,就會損失一小時的數據。 2. fork進程消耗資源。

AOF AOF相比起RDB,是更加常用的方式。


利用下班時間,我兩星期完成了redis入門與進階

原理是將所有的命令記錄下來,寫入一個叫做appendonly.aof的文件中,當手動開啟後,重啟redis就會出現,很簡單,而且由於保存的是步驟,而不是數據庫本身,所以安全性高,他有三種同步方式,每一次修改都同步,每秒同步,從不同步,有以下特點:

優點: 1. 如果設置每一次修改都同步,很方便,不會有損失。 2. 如果設置每秒同步,最多丟失一秒數據。 3. 每次重啟redis,優先載入aof恢復數據。

缺點: aof的體積大於Rdb文件,而且恢復也比較慢,這個好理解,記錄了那些步驟都要重新執行一遍,自然比rdb直接備份的要慢一些。

所以,根據他們的原理和優缺點,我們很容易判斷他們的使用範圍。 如果是數據比較重要,但是可以承受損失,比如微博評論啥的,就用rdb吧。 如果需要更加安全,不能有損失,就用aof。 當然,兩個都用於ok,aof用作平時的恢復,rdb用於緊急的兜底備份。

發佈訂閱

類似於微信公眾號,信息消費者(subscriber)和信息生產者(Publisher )通過中間的channel進行連接,需要subscriber先訂閱,然後Publisher 將信息推入到channel中,這裡的channel本質上是一個鍵。 redis會維護一個字典,每個channel都是鍵,對應的值是一個鏈表,包含了所有的subscriber,所以當信息被推入channel中,信息就知道了他要去的地方,是那個鏈表,然後逐一分發下去。


利用下班時間,我兩星期完成了redis入門與進階

主從複製

雞蛋不能放在一個籃子裡面,凡是涉及到數據庫的,都需要進行備份,只不過各家的方式不一樣。 redis使用主從複製,一個最簡單的模型是一主二從,使用三臺電腦。

利用下班時間,我兩星期完成了redis入門與進階

先思考一下,我們需要解決哪些問題? 基礎功能:

  1. 數據不能亂,讀寫要和一臺機器一樣。

方案:主機才有權力寫,而從機只能從主機複製內容。

  1. 如果主機掛了,就能夠及時變成主機。

方案:哨兵模式。

哨兵模式

我第一次接觸哨兵模式,是在學習計算機系統的時候,所謂哨兵,相當於中世紀的教皇,而主機,是國王。 國王需要接受教皇的冊封,才能成為真正的國王。

當主機掛掉的時候,哨兵將選擇一個從機,讓他成為主機,而且,即使原來的主機回來了,他也只能變成從機。 選擇的方式,是投票。 哨兵不只一個,是奇數個,對於三個服務器,一主二從,這裡三個哨兵比較合適,定時向主機發送消息監控,如果三個哨兵都無法收到主機的回包,大概率主機就掛掉了,此時哨兵進行投票,得票多的從機成為主機,如下圖 sentinel為哨兵,slave為從機。

利用下班時間,我兩星期完成了redis入門與進階


投票是一種算法,這裡不再深入。 而如何防止哨兵掛掉呢?這就是為什麼哨兵不只一個的原因,多個哨兵也相互監督。

這樣,這個模型如果不斷擴大,除非大面積斷電,不然即使有一些哨兵或者服務器掛掉了,也可以正常運行。

緩存雪崩

黑天鵝還是來了,大面積斷電了! 此時,就是緩存雪崩,因為斷電,Redis作為內存數據庫,作為訪問與數據庫之間的中間緩存,將會徹底失效,此時 緩存稱為雪崩。 方案在思路上沒啥神奇的辦法,只能異地容災,或者提前預熱,比如在11月10號模擬幾億訂單量衝擊淘寶系統,看看能不能抗住。

穿透

雪崩畢竟是天災,我們無法改變,但是緩存穿透我們可以有所作為 穿透,就是緩存沒起到作用,為什麼沒起到作用? 因為在緩存中沒找到數據,比如說,用戶找一個商品信息,但是緩存中找不到,所以會跳轉到數據庫中去找,而如果大量用戶都來發起訪問沒找到的數據,數據庫將會直接暴露,容易受到攻擊,比如下圖,如果一直是否,就會一直查詢DB

利用下班時間,我兩星期完成了redis入門與進階

主流解決方法是使用過濾器,比如著名的布隆過濾器,篩選出容易造成穿透的訪問信息,剔除掉即可,相當於給緩存打了一個補丁,除了過濾,還可以分流,降級等等,這些東西,和幾千年前的大禹治水的思路一樣,只是搬到了計算機上,畢竟,智慧,從古到今,都不會變,變的是使用場景。

擊穿

穿透是找不到,擊穿是受不了,假設緩存中有這個商品信息,但是由於訪問過於頻繁,使得緩存也受不了,就會崩掉,比如微博某明星談戀愛就崩了,這應該是屬於緩存擊穿案例。 方案也不難,可以使用臨界區,只要一部分在在訪問,其他的就無法訪問,這是一種互斥鎖的方案,雖然併發少了,但是至少不會崩。


分享到:


相關文章: