1. 程式人生 > 實用技巧 >Java8 新特性學習

Java8 新特性學習

String型別的底層資料結構、儲存方式、擴容方式?

  底層資料結構:SDS,簡單動態字串(Simple Dynamic String),它是一個帶有長度資訊的位元組陣列

  儲存方式:embstr和raw,當字串長度比較短的時候使用embstr,長度超過44位元組時使用raw方式儲存

  擴容方式:長度小於1MB時,擴容使用加倍策略,記憶體超過1MB時,每次多分配1MB的空間(字串最大長度為512MB)

 

Redis的持久化機制?有幾種方式?優缺點?

 redis 的持久化機制,會將資料寫入記憶體的同時,非同步的慢慢的將資料寫入磁碟檔案裡,進行持久化。

 有兩種方式:RDB 持久化機制,是對 redis 中的資料執行週期性的持久化。需要 fork 一個子程序,讓子程序執行磁碟 IO 操作來進行 RDB 持久化。

                       AOF 機制對每條寫入命令作為日誌,以 append-only 的模式寫入一個日誌檔案中,在 redis 重啟的時候,可以通過回放 AOF 日誌中的寫入指令來重新構建整個資料集。

 RDB的優缺點:

                     優點:對外依然提供讀寫服務,影響非常小,可以讓redis保持高效能。相對於AOF重啟和恢復redis程序速度更快。

                     缺點:會造成資料部分丟失(一般同步機制5分鐘一次,在這五分鐘內宕機會造成資料丟失),資料檔案很大,會造成服務延遲。

 AOF的優缺點:

                    優點:可以保證資料不丟失,效能高,不影響客戶端讀寫,可以對誤操作進行緊急修復。

                    缺點:支援的寫 QPS 會比 RDB 支援的寫 QPS 低,因為要實時進行資料同步

 解決方案:

                    用 AOF 來保證資料不丟失,作為資料恢復的第一選擇; 用 RDB 來做不同程度的冷備,在 AOF 檔案都丟失或損壞不可用的時候,還可以使用 RDB 來進行快速的資料恢復。

                

為什麼 redis 單執行緒模型也能效率這麼高?

  1.Redis是基於記憶體的,資料都存放在記憶體中,速度非常快

  2.Redis的IO模型是非阻塞IO

  3.Redis核心模組的單執行緒使得可以避免執行緒切換帶來的開銷(Redis6.0是支援多執行緒的)

 

對IO模型的瞭解,瞭解哪些IO模型?

  IO的過程主要包含了兩個階段:

       第一階段,等待資料準備好,

       第二階段,將資料從核心空間拷貝到應用程式地址空間

  第一個階段阻塞即為阻塞IO,不阻塞直接返回則為非阻塞IO

  第二個階段阻塞則為同步IO,不阻塞則為非同步IO

  多路複用IO其實是通過輪詢機制來負責多個socket

 

既然Redis是單執行緒的,那麼它如何利用多核呢?

可以通過開啟多個Redis例項來利用多核

 

redis 過期策略?

  定期刪除+惰性刪除。

  定期刪除:redis 預設是每隔 100ms 就隨機抽取一些設定了過期時間的 key,檢查其是否過期,如果過期就刪除。

  惰性刪除:在獲取某個key時,會檢測這個key是否設定了過期時間,如果已過期則進行刪除,不返回資料。

 

redis 記憶體淘汰機制?

  noeviction: 記憶體不足時寫入資料,直接報錯

  allkeys-lru:記憶體不足時寫入資料,移除最近最少使用的 key(最常用)

  allkeys-random:記憶體不足時寫入資料,隨機刪除某個key

  volatile-lru:記憶體不足時寫入資料,在設定過期時間的鍵空間中,移除最近最少使用的key

  volatile-random:記憶體不足時寫入資料,在設定過期時間的鍵空間中,隨機刪除某個key

  volatile-ttl:記憶體不足時寫入資料,在設定過期時間的鍵空間中,移除過期時間短的key

 

如何保證快取與資料庫的雙寫一致性?

  讀請求和寫請求序列化,串到一個記憶體佇列裡去。序列化可以保證一定不會出現不一致的情況,但是它也會導致系統的吞吐量大幅度降低,用比正常情況下多幾倍的機器去支撐線上的一個請求

 

快取雪崩?快取穿透?

   快取雪崩:

        在某一個時間點,快取資料集中失效,所有請求直接打到了資料上,導致服務崩潰。解決方案:設定快取失效的時間點儘量避免重疊,熱門資料時間長些,冷門資料時間短些

   快取穿透:

        先查詢快取,快取為null去查詢資料庫,資料庫也為null,不寫入快取,導致請求會一直請求資料庫。

        解決方案:資料庫也為null時,也寫入為“”的快取資料,過期時間儘量短些。互斥鎖:在第一個請求去查詢資料時加上互斥鎖,其餘請求都被阻塞,直到鎖被釋放

    Redis掛掉了怎麼辦?

      設定本地快取+限流(hystrix)。redis持久化,重啟後自動從磁碟上載入資料,快速恢復快取資料。

 

redis 叢集模式的工作原理?

自動將資料進行分片,每個 master 上放一部分資料提供內建的高可用支援。在 redis cluster 架構下,每個 redis 要放開兩個埠號,比如一個是 6379,另外一個就是 加1w 的埠號,比如 16379。
16379 埠號是用來進行節點間通訊的,也就是 cluster bus 的東西,cluster bus 的通訊,用來進行故障檢測、配置更新、故障轉移授權。

cluster bus 用了另外一種二進位制的協議,gossip 協議,用於節點間進行高效的資料交換,佔用更少的網路頻寬和處理時間。

 

分散式定址都有哪些演算法?瞭解一致性 hash 演算法嗎?

  hash 演算法(大量快取重建):

    根據key,首先計算 hash 值,然後對節點數取模,打在不同的 master 節點上。一旦某一個 master 節點宕機,所有請求過來,都會基於最新的剩餘 master 節點數去取模,嘗試去取資料。這會導致大部分的請求過來,全部無法拿到有效的快取,導致大量的流量湧入資料庫

 

  一致性 hash 演算法(自動快取遷移)+ 虛擬節點(自動負載均衡):    

   一致性 hash 演算法將整個 hash 值空間組織成一個虛擬的圓環,整個空間按順時針方向組織,下一步將各個 master 節點(使用伺服器的 ip 或主機名)進行 hash。這樣就能確定每個節點在其雜湊環上的位置。

   來了一個 key,首先計算 hash 值,並確定此資料在環上的位置,從此位置沿環順時針“行走”,遇到的第一個 master 節點就是 key 所在位置。

   在一致性雜湊演算法中,如果一個節點掛了,受影響的資料僅僅是此節點到環空間前一個節點(沿著逆時針方向行走遇到的第一個節點)之間的資料,其它不受影響。增加一個節點也同理。