1. 程式人生 > 其它 >vue+flvjs實現flv格式視訊流線上播放

vue+flvjs實現flv格式視訊流線上播放

一:基礎的資料結構
字串型別、雜湊型別、列表型別、集合型別、有序集合型別。

二:刪除策略
  • 被動刪除:當讀/寫一個已經過期的key時,會觸發惰性刪除策略,直接刪除掉這個過期key
  • 主動刪除:由於惰性刪除策略無法保證冷資料被及時刪掉,所以Redis會定期主動淘汰一批已過期的key
  • 當前已用記憶體超過maxmemory限定時,觸發主動清理策略
    1. volatile-lru(least recently used):最近最少使用演算法,從設定了過期時間的鍵中選擇空轉時間最長的鍵值對清除掉;
    2. volatile-lfu(least frequently used):最近最不經常使用演算法,從設定了過期時間的鍵中選擇某段時間之內使用頻次最小的鍵值對清除掉;
    3. volatile-ttl:從設定了過期時間的鍵中選擇過期時間最早的鍵值對清除;
    4. volatile-random:從設定了過期時間的鍵中,隨機選擇鍵進行清除;
    5. allkeys-lru:最近最少使用演算法,從所有的鍵中選擇空轉時間最長的鍵值對清除;
    6. allkeys-lfu:最近最不經常使用演算法,從所有的鍵中選擇某段時間之內使用頻次最少的鍵值對清除;
    7. allkeys-random:所有的鍵中,隨機選擇鍵進行刪除;
    8. noeviction:不做任何的清理工作,在redis的記憶體超過限制之後,所有的寫入操作都會返回錯誤;但是讀操作都能正常的進行;
二:內部模型(reactor)
三:檔案事件和時間事件
  • 檔案事件:Redis伺服器通過套接字與客戶端進行連線,而檔案事件就是伺服器對套接字操作的抽象。普通伺服器與客戶端的通訊,會產生相應的檔案事件,伺服器需要監聽並能夠處理這些事件來完成網路通訊操作。
  • 時間事件:伺服器的某些操作需要進行定時操作,而時間事件就是對這類定時操作的抽象。
  • 一個時間事件由三部分組成:

(1)id:時間事件的全域性唯一的ID(標識號)
(2)when:毫秒級別的UNIX時間戳
(3)timeProc:時間事件處理器

    一個時間是定時事件還是週期性事件,取決於時間事件處理器的返回值,當返回一個ae.h/AE_NOMORE,該事件為定時事件,若為一個非AE_NOMORE值,則是一個週期性事件,同時通過這個返回 值,對時間事件的when屬性進行更新,讓該事件在該返回值對應的毫秒數後再繼續執行。
  • Redis伺服器會將所有的時間事件放入一個無序連結串列中,每當時間時間執行器執行時,會遍歷整個連結串列,找到已經到達時間的事件,並呼叫相應的事件處理器。
三:叢集(Sentinel)
   1.
主從切換:
    
每個 sentinel 節點通過定期監控 master 的健康狀況。

sentinel 叢集 發現 master 故障後,多個 sentinel 節點對主節點的故障達成一致,在 3 個 sentinel 節點中選擇一個作為 leader ,例如,選舉出 sentinel-0 節點作為 leader,來負責故障轉移。

leader sentinel 把一個 slave 節點提升為 master,並讓另一個 slave 從新的 master 複製資料,並告知客戶端新的 master 的資訊。

故障的舊 master 上線後,leader sentinel 讓它從新的 master 複製資料。

           

   2.sentinel 叢集的監控功能詳解

    每隔10秒,每個 sentinel 節點會向主節點和從節點發送 info 命令獲取 redis 主從架構的最新情況。例如,傳送info replication命令可以得到以下資訊:

    

每隔2秒,每個 sentinel 節點會向 redis 資料節點的__sentinel__:hello這個channel(頻道)傳送一條訊息

  <sentinelip><sentinelport><sentinelrunId><Sentinel配置版本><mastername><masterip><masterport><master配置版本>

   

每個 sentinel 節點會訂閱該 channel,來了解其他sentinel節點以及它們對主節點的判斷,所以這個定時任務可以完成以下兩個工作:

  發現新的 sentinel節點:通過訂閱主節點的__sentinel__:hello瞭解其他的 sentinel 節點資訊,

如果是新加入的 sentinel 節點,將該 sentinel 節點資訊儲存起來,並與該 sentinel 節點建立連線

sentinel 節點之間交換主節點的狀態,用於確認 master 下線和故障處理的 leader 選舉。

每隔1秒,每個 sentinel 節點會向主節點、從節點、其餘 sentinel 節點發送一條ping命令做一次心跳檢測,來確認這些節點是否可達。通過定時傳送ping命令,sentinel 節點對主節點、從 節點,其餘 sentinel 節點都建立起連線,實現了對每個節點的監控,這個定時任務是節點下線判定的重要依據。

   3. sdown(主觀下線) 和 odown(被動下線)

   主觀下線:每個 sentinel 節點每隔1秒對主節

點、從節點、其他 sentinel 節點發送 ping 命令做心跳檢測,當這些節點超過
down-after-milliseconds沒有進行有效回覆,sentinel節點就會認為該節點下線,這個行為叫做主觀下線。主觀下線是某個 sentinel 節點的判斷,並不是 sentinel 叢集的判斷, 所以存在誤判的可能。

客觀下線:當 sentinel 主觀下線的節點是主節點時,該 sentinel 節點會通過sentinel ismaster-down-by-addr命令向其他 sentinel 節點詢問對主節點的判斷,當超過

<quorum>個數(quorum可配置)的 sentinel 節點認為主節點確實有問題,這時該 sentinel 節點會做出客觀下線的決定,這樣客觀下線的含義是比較明顯了,也就是大部分是 sentine l節點都對主節點的下線做了同意的判定,那麼這個判定就是客觀的

      

4. 當 sentinel 叢集確認 master odown,需要選舉出一個 leader 節點來進行故障轉移,選舉過程如下:

每個線上的 sentinel 節點都有資格成為 leader,當它確認主節點客觀下線時候,會向其他 sentinel 節點發送sentinel is-master-down-by-addr命令,要求將自己設定為leader,比如 s entinel-0 節點首先發起請求成為 leader 的請求。

每個 sentinel 節點都只能投出一票,於是當 sentinel-0 節點發起成為 leader 的請求後,會得到 sentinel-1 和 sentinel-2 節點的投票,總共得到 2 票,得到的票數和以下公式計算的 值作比較:當得到的票數 >= max(quorum, num(sentinels) / 2 + 1) 的值,那麼該 sentinel 節點成為 leader,於是,sentinel-0 節點成為 leader。
     

比如下一個確認 master 客觀下線的 sentinel 節點為 sentinel-1,當它發起成為 leader 的請求後,由於 sentinel-2 節點已經給 sentinel-0 節點投過票了,於是它只能得到 sentinel -0節點投的一票,所以它不能成為 leader,而當 sentinel-2 發起請求成為 leader 的請求後,它一票都得不到。於是當已經選舉出 leader 後,就不會再繼續進行選舉流程了,因為是沒有意義 的。

如果一次選舉沒有選舉出 leader,那麼會進行下一次選舉。

總結:正常情況下,哪個 sentinel 節點最先確認 master 客觀下線,哪個 sentinel 節點就會成為執行故障轉移的 leader。

介紹一下sentinel is-master-down-by-addr命令: "sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>"

ip、port:詢問此 ip:port 的 redis 程序是否下線
current_epoch:當前配置版本
runid:如果為當前 sentinel 節點的 runid,則此命令用於申請自己成為故障處理的 leader,如果是*,則此命令用於向其他 sentinel 節點確認 master 是否下線。

此命令返回結果包括3個資訊:

down_state:目標 sentinel 節點對於主節點的下線判斷,1是下線,0是線上。

leader_runid:當leader_runid等於*時,代表返回結果是說明主節點是否不可達,當 leader_runid 等於具體的runid,代表目標節點同意該 runid sentinel 節點成為 leader。

leader_epoch:leader 版本。

 

   5. 要執行故障轉移,首先要從 slave 中選擇一個作為新的 master,選擇的準則如下:

不選擇不健康的 slave,以下狀態的 slave 是不健康的:

主觀下線的 slave

大於等於5秒沒有回覆過 sentinel 節點 ping 響應的 slave

與 master 失聯超過down-after-milliseconds * 10秒的 slave

對健康的 slave 進行排序

選擇 priority(從節點優先順序,可配置,預設100)最低的從節點,如果有優先順序相同的節點,進行下一步。注意如果這個值配置為0,則代表禁止該節點成為 master。

選擇複製偏移量最大的從節點(複製的最完整),如果有複製偏移量相等的節點,進行下一步。

選擇 runid 最小的從節點。

  6. 然後就是 leader 進行故障轉移的過程了:
leader 對選擇出來的要成為 new master 的 slave 執行 slaveof no one 命令讓其成為 new master。
leader 會向剩餘的 slave 傳送命令,讓它們成為 new master 的 slave。
leader 會將 old master 更新為 slave點,並保持著對其關注,當其恢復後命令它去複製 new master。
複製規則和parallel-syncs配置有關。該配置指定了在執行故障轉移時,最多可以有多少個 slave 同時對 new master 進行同步,這個數字越小,完成故障轉移所需的時間就越長。
如果從伺服器被設定為允許使用過期資料集(redis.conf 中slave-serve-stale-data配置) ,那麼你可能不希望所有 slave 都在同一時間向 new master 傳送同步請求,
因為儘管複製過程的絕大部分步驟都不會阻塞slave, 但 slave 在 load new master 發來的 RDB 檔案時, 仍然會造成其在一段時間內不能處理請求。如果全部 slave
一起對 new master 進行同步, 那麼就可能會造成所有 slave 在短時間內全部不可用的情況出現。你可以通過將這個值設為 1 來保證故障轉移後最多隻有一個 slave 處於不可用狀態。
但這樣的話,全部 slave 的資料同步就是序列的,這樣就會增加故障轉移整個過程的時間。
四:備份
  Rdb:
  Aof:
彩蛋(特殊命令)

  • rename oldkey newkey:對 key 重新命名,如果 newkey 存在則覆蓋。
  • renamenx oldkey newkey:對 key 重新命名,如果 newkey 存在則不覆蓋。
  • randomkey:隨即返回一個 key
  • move key db-index:將 key 移動到指定的資料庫中,如果 key 不存在或者已經在該資料庫中,則返回 0。成功則返回 1。
  • 根據 key 獲取該鍵所儲存的 redis 資料型別:TYPE key
  • 自減:DECR key。將指定 key 的值減少 1
  • DECRBY key increment 用來給指定 key 的值減 increment
  • 增加浮點數:INCRBYFLOAT key increment。
  • 向尾部追加:APPEND key value。如set test:key 123、append test:key 456、get test:key 就是 123456
  • 獲取長度:STRLEN key。
  • 同時給多個 key 賦值:MSET title 這是標題 description 這是描述 content 這是內容。
  • 同時獲取多個 key 的值:MGET title description content
  • 位操作之獲取:GETBIT key offset。如字元 a 在 redis 中的儲存為 01100001(ASCII為98),那麼 GETBIT key 2 就是 1,GET key 0 就是 0。
  • 位操作之設定:SETBIT key offset value。如字元 a 在 redis 中的儲存為 01100001(ASCII為98),那麼 SETBIT key 6 0,SETBIT key 5 1 那麼 get key 得到的是 b。因為取出的二進位制為 01100010。
  • 位操作之統計:BITCOUNT key [start] [end]:BITCOUNT key 用來獲取 key 的值中二進位制是 1 的個數。而 BITCOUNT key start end 則是用來統計key的值中在第 start 和 end 之間的子字串的二進位制是 1 的個數(好繞啊)。
  • 位操作之位運算:BITOP operation resultKey key1 key2。operation 是位運算的操作,有 AND,OR,XOR,NOT。resultKey 是把運算結構儲存在這個 key 中,key1 和 key2 是參與運算的 key,參與運算的 key 可以指定多個。
  • 欄位是否存在:HEXISTS key field。存在返回 1,不存在返回 0
  • 自增 N:HINCREBY key field increment。同字串的自增型別,不再闡述。
  • 獲取欄位數量:HLEN key。
  • 刪除列表中指定值:LREM key count value。刪除 key 這個列表中,所有值為 value 的元素,只刪除 count。如果有 count+1 個,那麼就保留最後一個。count 不存在或者為 0,則刪除所有的。如果 count 大於 0,則刪除從頭到尾的 count 個,如果 count 小於 0,則刪除從尾到頭的 count 個。
  • 保留片段,刪除其它:LTRIM key start end。保留 start 到 end 之間的所有元素,含 start 和 end。其他全部刪除。
  • 向列表插入元素:LINSERT key BEFORE/AFTER value1 value2。從列表頭開始遍歷,發現值為 value1 時停止,將 value2 插入,根據 BEFORE 或者 AFTER 插入到 value1 的前面還是後面。
  • 把一個列表的一個元素轉到另一個列表:RPOPLPUSH list1 list2。將列表 list1 的右邊元素刪除,並把該與元素插入到列表 list2 的左邊。原子操作。
  • 獲取指定集合的所有元素:SMEMBERS key。
  • 判斷某個元素是否存在:SISMEMBER key value。
  • 差集運算:SDIFF key1 key2...。對多個集合進行差集運算。
  • 交集運算:SINNER key1 key2...。對多個集合進行交集運算。
  • 並集運算:SUNION key1 key2...。對多個集合進行並集運算。
  • 獲取集合中元素個數:SCARD key。返回集合中元素的總個數。
  • 對差集、交集、並集運算的結果存放在一個指定的 key 中:SDIFFSTORE storekey key1 key2。對 key1 和 key2 求差集,結果存放在 key 為 storekey 的集合中。SINNERSTORE 和 SUNIONSTORE 類似。
  • 獲取集合中的隨即元素:SRANDMEMBER key [count]。引數 count 可選,如果 count 不存在,則隨即一個。count 大於 0,則是不重複的 count 個元素。count 小於 0,則是一共 |count|個 元素,可以重複。
  • 隨即彈出一個元素:SPOP key。隨即從集合中彈出一個元素並刪除,將該元素的值返回。
  • 獲取集合中元素的數量:ZCARD key。
  • 根據排名範圍刪除元素:ZREMRANGEBYRANK key start end。刪除排名在 start 和 end 中的元素。
  • 按照分數範圍刪除元素:ZREMRANGEBYSCORE key min max。
  • 獲得元素排名(正序):ZRANK key value。獲取 value 在該集合中的從小到大的排名。
  • 獲得元素排名(倒序):ZREVRANK key value。獲取 value 在該集合中從大到小的排名。
  • 有序集合的交集:ZINTERSTORE storekey key1 key2...[WEIGHTS weight [weight..]] [AGGREGATE SUM|MIN|MAX]。用來計算多個集合的交集,結果儲存在 storekey中。返回值是 storekey 的元素個數。AGGREGATE 為 SUM 則 storekey 集合的每個元素的分數是參與計算的集合分數和。MIN 是參與計算的分數最小值。MAX 是參與計算分數最大值。WEIGHTS 設定每個集合的權重,如 WEIGHTS 1 0.1。那麼集合A的每個元素分數 * 1,集合B的每個元素分數 * 0.1
  • 有序集合的並集:ZUNIONSTORE storekey key1 kye2...[WEIGHTS weight [weight..]] [AGGREGATE SUM|MIN|MAX]



轉載至:
https://redis.io/topics/sentinel

https://blog.csdn.net/weixin_44449616/article/details/113277120
https://blog.csdn.net/xiaoxiaole0313/article/details/103813759
https://www.cnblogs.com/mengchunchen/p/10059436.html

郵箱: [email protected]