1. 程式人生 > 其它 >使用 nvm 管理不同版本的 node 與 npm

使用 nvm 管理不同版本的 node 與 npm

redis

redis是單執行緒+多路IO複用技術實現 支援記憶體操作+持久化儲存,主要用於高併發海量資料讀寫 例如秒殺活動 簡訊驗證碼等 快取 訊息佇列。預設使用0號庫 有0-15個庫

1.redis快的原因

1.redis使用記憶體儲存,沒有磁碟IO開銷,讀寫速度快

2.redis是單執行緒,避免多執行緒之間執行緒切換和鎖競爭開銷

3.redis使用多路IO複用技術,委託核心監控事件,將資料庫操作轉為事件,不在網路IO上耗時

2.redis和MySQL對比

​ MySQL Redis

1.結構化:mysql資料都是藉助表儲存 非結構化:藉助key-value實現儲存

2.關聯性:mysql表和表之間可以藉助外來鍵聯絡 無關聯性

3.SQL查詢:有特定的查詢語句 select * from tmp; 沒有特定SQL

4.ACID事務一致性 無法全部滿足事務一致性

5.磁碟儲存 記憶體儲存

3.通用命令

1.keys pattern :檢視複合模板所有key

keys  *:匹配全部key
keys  a*:匹配以a開頭的

2.DEL key:刪除一個key/多個key

del name :刪除key為name
del v1 v2 v3 v4:刪除key為v1 v2 v3 v4

unlink key 根據key非阻塞刪除 首先將key從keys裡面刪除 但是真正資料刪除在後續操作

3.exists key :判斷key是否存在

exists name : 判斷name是否存在

4.expire key :給 key 設定一個有效期 首先你的key要存在

5.ttl key :檢視一個key剩餘有效期 有效期為-2 表示已經過期了被移除;有效期為-1 表示永久有效

4.常見資料型別

4.1 String型別

1.set:新增或者修改已經存在的string型別鍵值對

set key value

2.get:根據key獲取string型別value

get key

3.mset/mget:批量設定或者獲取

mset key1 v1 key2 v2 key3 v3
mget key1 key2 key3

4.incr讓一個整形key自增1 ;incrby key 6 讓一個整形key自增6 設定負值 即可自減

incr key
incrby key 6

5.setnx:新增一個string型別鍵值對 前提是這個key不存在 否則不執行;所以僅僅執行新增功能

setnx key value   等價於   set key value nx

6.setex: 新增一個string型別鍵值對 設定有效期

setex key seconds value   等價於   set key value ex seconds

string的資料結構為簡單動態字串。類似於切片一樣。當字串長度小於1M時,擴容都是加倍現有的空間,如果超過1M,擴容時一次只會多擴1M的空間。需要注意的是字串最大長度為512M。

4.2 Hash型別

hash型別也叫雜湊 ,其value是一個無序字典。hash結構可以將物件的每個欄位單獨進行修改而string型別是一個整體 不能單獨修改。

1.HSET key field value:新增或者修改hash型別key的field的值

hset heima:user:1 name ‘jq’

2.HGET key field:獲取一個hash型別key的field的值

hget heima:user:1 name

3.HMSET:批量新增多個hash型別key的field的值

hmset heima:user:2 name ‘hd’ age 20

4.HMGET:批量獲取多個hash型別key的field的值

hmget heima:user:2 name age

5.HGETALL:獲取一個hash型別的key中的所有的field和value

6.HKEYS:獲取一個hash型別的key中的所有的field

7.HVALS:獲取一個hash型別的key中的所有的value

8.HINCRBY:讓一個hash型別key的欄位值自增並指定步長

9.HSETNX:新增一個hash型別的key的field值,前提是這個field不存在,否則不執行

Hash型別對應的資料結構是兩種:ziplist(壓縮列表),hashtable(雜湊表)。當field-value長度較短且個數較少時,使用ziplist,否則使用hashtable。壓縮連結串列本質就是一個數組,一種線性的資料結構。

4.3 list型別

​ 雙向連結串列 可以支援正向檢索和反向檢索 值在鍵在 值光鍵亡。常常用來儲存有序資料 例如:朋友圈點贊 評論列表等。

1.有序 2.元素可以重複 3.插入和刪除快 4.查詢速度一般

1.LPUSH/RPUSH key element ... :向列表左/右側插入一個或多個元素

lpush list1 1 2 3    rpush list1 4 5 6

2.LPOP/RPOP key:移除並返回列表左/右側的第一個元素,沒有則返回nil

lpop list1      rpop list1

3.LRANGE key star end:返回一段角標範圍內的所有元素

lrange list1 1 3    //這裡式索引下標  左右都是閉區間

4.BLPOP和BRPOP:與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil

1.如何利用List結構模擬一個棧?

​ 入口和出口在同一邊

2.如何利用List結構模擬一個佇列?

​ 入口和出口在不同邊

3.如何利用List結構模擬一個阻塞佇列?

​ 入口和出口在不同邊;出隊時採用BLPOP或BRPOP

List的資料結構為快速連結串列quickList。首先在列表元素較少的情況下會使用一塊連續的記憶體儲存,這個結構是ziplist,也即是壓縮列表。它將所有的元素緊挨著一起儲存,分配的是一塊連續的記憶體。當資料量比較多的時候才會改成quicklist。因為普通的連結串列需要的附加指標空間太大,會比較浪費空間。比如這個列表裡存的只是int型別的資料,結構上還需要兩個額外的指標prev和next。Redis將連結串列和ziplist結合起來組成了quicklist。也就是將多個ziplist使用雙向指標串起來使用。這樣既滿足了快速的插入刪除效能,又不會出現太大的空間冗餘。

4.4 set型別

1.無序

2.元素不可重複

3.查詢快

4.支援交集、並集、差集等功能

1.SADD key member ... :向set中新增一個或多個元素

2.SREM key member ... : 移除set中的指定元素

3.SCARD key: 返回set中元素的個數

4.SISMEMBER key member:判斷一個元素是否存在於set中

5.SMEMBERS:獲取set中的所有元素

6.SINTER key1 key2 ... :求key1與key2的交集

7.SDIFF key1 key2 ... :求key1與key2的差集

8.SUNION key1 key2 ..:求key1和key2的並集

將下列資料用Redis的Set集合來儲存:

張三的好友有:李四、王五、趙六

李四的好友有:王五、麻子、二狗

建立set :

sadd zs ls ww zl     
sadd ls  ww mz eg

1.計算張三的好友有幾人

scard zs

2.計算張三和李四有哪些共同好友

sinter zs ls

3.查詢哪些人是張三的好友卻不是李四的好友

 sdiff zs ls

4.查詢張三和李四的好友總共有哪些人

sunion zs ls 

5.判斷李四是否是張三的好友

 sismember zs ls

6.判斷張三是否是李四的好友

sismember ls zs

7.將李四從張三的好友列表中移除

srem zs ls

Set資料結構是一個value為空的雜湊表。它的內部也使用hash結構,所有的value都指向同一個內部值。

4.5 SortedSet型別

SortedSet中的每一個元素都帶有一個score屬性,可以基於score屬性對元素排序,底層的實現是一個跳錶(SkipList)加 hash表。SortedSet具備下列特性:score可以重複但是member不能重複

1.可排序

2.元素不重複

3.查詢速度快

因為SortedSet的可排序特性,經常被用來實現排行榜這樣的功能

1 ZADD key score member:新增一個或多個元素到sorted set ,如果已經存在則更新其score值

2 ZREM key member:刪除sorted set中的一個指定元素

3 ZSCORE key member : 獲取sorted set中的指定元素的score值

4 ZRANK key member:獲取sorted set 中的指定元素的排名

5 ZCARD key:獲取sorted set中的元素個數

6 ZCOUNT key min max:統計score值在給定範圍內的所有元素的個數

7 ZINCRBY key increment member:讓sorted set中的指定元素自增,步長為指定的increment值

8 ZRANGE key min max:按照score排序後,獲取指定排名範圍內的元素

9 ZRANGEBYSCORE key min max:按照score排序後,獲取指定score範圍內的元素

10 ZDIFF、ZINTER、ZUNION:求差集、交集、並集

將班級的下列學生得分存入Redis的SortedSet中:

Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76

zadd key score membe [score member …]
zadd stu 85 jack 89 lucy 82 rose 95 tom 78 jerry 92 amy 76 miles

• 刪除Tom同學

zrem key member [member…]
zrem stu tom

• 獲取Amy同學的分數

zscore key member
zscore stu amy

• 獲取Rose同學的排名

zrank key member
zrank stu rose

•查詢80分以下有幾個學生

zcount key min max   //統計分數在min max之間個數
zcount stu 0 80 

• 給Amy同學加2分

zincrby key increment member
zincrby stu 2 amy  

• 查出成績前3名的同學

zrevrange key start stop
zrevrange stu 0 2

• 查出成績80分以下的所有同學

zrangebyscore stu 0 80

zset底層使用了兩個資料結構

(1)hash,hash的作用就是關聯元素value和權重score,保障元素value的唯一性,可以通過元素value找到相應的score值。

(2)跳躍表,根據score的範圍獲取元素列表。

skiplist:每個節點維持了多個指向其他節點的指標,從而達到快速訪問的目的

5.redis事務

​ 用來保證資料一致性和完整性 比如轉賬 只有我轉賬了 對方收到轉賬 才會提交事物 。Redis事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。Redis事務的主要作用就是串聯多個命令防止別的命令插隊。

比較:1.mysq事物要麼同時成功要麼同時失敗,而redis可以不是2.mysql事物支援acid,而redis並不是完全滿足(有一致性,隔離性和原子性,沒有永續性)

為什麼redis不支援回滾?

​ redis發生語法錯誤(對key賦值一個錯誤型別),在組隊時候無法檢測出來,執行時候報錯,這屬於程式性錯誤,開發時候就能發現,所以不會出現在生產環境。由於不需要回滾,使得redis內部更加簡單,執行效率更快。從輸入Multi命令開始,輸入的命令都會依次進入命令佇列中,但不會執行,直到輸入Exec後,Redis會將之前的命令佇列中的命令依次執行。

組隊的過程中可以通過discard來放棄組隊。

1.如果組隊時候某個命令錯誤,執行時候所有佇列都會被取消

2.如果執行時候某個命令錯誤,則只有報錯命令不執行 其餘命令正常執行

樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量。Redis就是利用這種check-and-set機制實現事務的

6.持久化儲存

6.1 RDB:

​ redis database 在指定的時間間隔內將記憶體中的資料集快照寫入磁碟, 也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡。

1.RDB是如何進行備份的?過程使用寫時複製技術

​ Redis會單獨建立一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換硬碟中持久化的檔案(dump.rdb)。 整個過程中,主程序是不進行任何IO操作的,這就確保了極高的效能。如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺點是最後一次持久化後的資料可能丟失。(原因與配置中save規則有關,比如20s內右3個key變化才進行持久化)

​ 為什麼不直接同步到持久化檔案:可以避免伺服器掛了,資料持久化一半,造成資料缺少。所以使用臨時檔案可以保證資料完整性一致性

優點:

​ 1.適合大規模的資料恢復 2.對資料完整性和一致性要求不高更適合使用

​ 3.節省磁碟空間 4.回覆速度快

缺點:

​ 1.fork時候,記憶體中的資料被複制了一份,所以需要考慮2倍記憶體容量

​ 2.在備份週期一定時間間隔做一次備份,如果redisdown掉了,就會丟失最後一次快照內容

6.2 AOF:

​ append only file 以日誌的形式來記錄每個資料和寫操作(增量儲存),只許追加檔案但不可以修改檔案將Redis執行過的所有寫指令記錄下來(讀操作不記錄),,redis啟動之初會讀取該檔案重新構建資料,換言之,redis
重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

AOF 和RDB同時開啟的話,redis以AOF資料為準

(1)客戶端的請求寫命令會被append追加到AOF緩衝區內;

(2)AOF緩衝區根據持久化策略[always,everysec,no]將操作sync同步到磁碟的AOF檔案中;

(3)AOF檔案大小超過重寫策略或手動重寫時,會對AOF檔案rewrite重寫,壓縮AOF檔案容量;

(4)Redis服務重啟時,會重新load載入AOF檔案中的寫操作達到資料恢復的目的;

優點:資料同步更新更快,丟失資料概率更低

​ AOF檔案可以看得懂 通過redis-check-aof來修復AOF檔案 可以處理誤操作

缺點:

比RDB佔用更多儲存空間(因為不僅要儲存資料還要儲存寫操作)

回覆備份速度慢  跟上面個原因差不多

每次讀寫都同步的話 會有一定效能壓力

7.三種叢集模式

7.1 主從複製

​ 主機資料更新後,會根據配置和策略自動同步到從機中去。主機以寫為主,從機以讀為住。

​ 主從複製的優點:讀寫分離,效能擴充套件性強(如果讀寫都在同一臺伺服器,該伺服器壓力就會很大) 容災快速回復(這個從機掛了 還有其他從機可以使用)

主從複製原理:

​ 1.當從伺服器連線上主伺服器之後,從伺服器會向主伺服器傳送資料同步的訊息。

​ 2.主伺服器接到同步訊息後,主伺服器會先將資料持久化,比如通過快照寫入到rdb檔案中,將rdb檔案傳送給從伺服器,從伺服器將rdb檔案讀取,最終完成資料同步過程。

​ 3.每次主伺服器進行寫操作後,會和從伺服器進行資料同步 (每次同步都是主伺服器主動,除了第一次申請申請同步是從伺服器主動)

1.一主多從:

​ 1.當主伺服器掛掉了:當主伺服器掛掉了,從伺服器不會上位,當主伺服器再次連線,主伺服器任然還是主伺服器

​ 2.當從伺服器掛掉了:當從伺服器掛掉了再次連線起來不再是原來主伺服器的slave,而自己成為master了。對這個伺服器再加slaveof 又變成原來主伺服器的從伺服器,同時原來資料都存在(即使是從伺服器掛掉期間寫資料任然存在)

2.薪火相傳:

​ 上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他 slaves的連線和同步請求,那麼該slave作為了鏈條中下一個的master, 可以有效減輕master的寫壓力,去中心化降低風險。

從伺服器從主伺服器同步資料 又將資料同步給自己下面的從伺服器

缺點就是當我中間從伺服器掛掉了 我主伺服器沒辦法給從伺服器下的從伺服器同步資料

3.反客為主:

​ 當我的主機掛掉了 在從機輸入slaveof no one 當前從機變成新主機。如果自動完成需要哨兵模式

7.2 哨兵模式

反客為主的自動版。當主機掛掉了,根據選舉決定哪個從機晉升為新主機

原理:

​ 一個哨兵後臺持續監視主伺服器,當主伺服器掛掉了,哨兵會立即通知從伺服器,從伺服器根據選舉進行上位。原來主伺服器就變成從伺服器。

從伺服器選舉規則:

​ 1.選擇優先順序靠前的 值越小優先順序越高

​ 2.和主伺服器資料同步最接近的

​ 3.runid最小的的優先 runid是隨機生成的

redis記憶體滿了怎麼辦?

​ 1.使用記憶體淘汰策略:

​ 通過配置redis的maxmemory-policy引數。預設值是noeviction,就是不進行刪除,如果滿了再向記憶體裡面寫入就報錯。刪除最近使用較少的key。刪除ttl最小的key,就是臨近過期的key。隨機刪除key

​ 2.建立叢集,利用叢集來分擔壓力

7.3 Cluster叢集模式

中心化叢集的方式:任意一個主節點都可以當作節點的入口

一個redis叢集有很多插槽,當你建立資料時候,叢集會根據公式進行計算key屬於哪個插槽。叢集的每個主節點負責一部分插槽,當你建立的key計算出來的數值位於哪一個主節點插槽部分,就分配到哪個主機點

一個 Redis 叢集包含 16384 個插槽(hash slot), 資料庫中的每個鍵都屬於這 16384 個插槽的其中一個

​ 節點 A 負責處理 0 號至 5460 號插槽。

​ 節點 B 負責處理 5461 號至 10922 號插槽。

​ 節點 C 負責處理 10923 號至 16383 號插槽。

比如你建立的key通過計算的數值為1234 就會被分配到A節點上

8.Redis應用問題

8.1 快取穿透

1.現象:

​ 1.應用伺服器壓力變大 2.redis的命中率降低 3.伺服器一直會去查詢資料庫,導致資料庫壓力過大崩潰。

2.產生原因:

​ 1.可能由於redis快取不進去資料,導致redis命中率低 可能性較小

​ 2.出現很多非正常的url訪問,導致redis命中率低,所以資料庫壓力過大

​ 最可能的是網站遭受了惡意攻擊

3.解決方法:

​ 1.對空值做快取:即使在redis查詢不到資料,也做空值快取,可以設定較短的過期時間。

  2.設定訪問的白名單:使用bitmaps型別定義一個白名單,將id作為value,每次訪問和bitmap中id比較,如果id不存在,就不允許訪問。

  3.布隆過濾器:底層也就是bitmap實現

  4.進行實時監控:當發現redis命中率降低了,立即排查訪問物件,設定黑名單。

8.2 快取擊穿

1.現象:

1.資料庫訪問壓力瞬時增大 2.redis沒有出現大量key過期  3.redis正常執行

2.產生原因:

redis某個key過期了 大量請求訪問了這個key,最終訪問不到會不斷訪問資料庫  常見比如熱門訪問的詞

3.解決方式:

1.預先將熱門資料存入到redis中,加大這個熱門資料key的時長

2.實時調整:實時監控熱門資料  實時調整key的時長

 3.使用鎖:鎖雖然可以避免這種現象  但是訪問效率會降低

8.3 快取雪崩

現象:

 1.資料庫壓力變大 應用訪問就會變慢 造成大量訪問等待 伺服器崩潰 資料庫崩潰

產生原因:

在極短時間內 大量的key都過期了 大量請求訪問這些key 訪問不到 轉而訪問資料庫 造成資料庫壓力過大 伺服器壓力過大 最終導致伺服器資料庫崩潰

解決方法:

1.構建多級快取架構

2.使用鎖:讓訪問求請求不要同時來到  這種效率必然低下

3.設定過期標誌,更新快取:提前記錄快取資料是否過期,如果過期通知另外執行緒去後臺實時更新快取資料

 4.將快取失效時間分隔開:設定過期時間時,儘量不要讓key大量集中在某一個時間段 儘量分離開來。

分散式鎖:分散式系統分配在不同機器上,在這臺機器加鎖 對其他機器並沒有作用

1.實現:

 基於redis快取

基於zookeeper:好像是通過樹來實現的,

​ redis實現:利用setnx設定,如果我的key值存在,設定就失效 類似於鎖一樣 當我用del刪除key 別人才能設定值

2.問題:如果我設定了鎖 始終不釋放,後面無限期阻塞 解決辦法 setnx時候同時設定ex 設定過期時間

set key value nx ex 20 :設定鎖的同時 設定過期時間