資料匯總

Dubbo

1、Dubbo 簡介(主要應用場景、核心功能和核心組件)

Dubbo 是一款高性能、輕量級的開源 RPC 框架,提供服務自動注冊、自動發現等高效治理方案,可以和 Spring 框架無縫集成。
好處:
1、透明化的遠程方法調用
2、軟負載均衡及容錯機制
3、服務自動注冊與發現
4、提供了完善的服務接口管理與監控功能
使用場景:
1、RPC 分布式服務,拆分應用進行服務化,提高開發效率,調優性能,節省競爭資源
2、配置管理,解決服務的地址信息劇增,配置困難的問題
3、服務依賴,解決服務間依賴關系錯蹤復雜的問題
4、服務擴容,解決隨著訪問量的不斷增大,動態擴展服務提供方的機器的問題
核心功能:
1、Remoting:遠程通訊,提供對多種 NIO 框架抽象封裝,包括“同步轉異步”和“請求-響應”模式的信息交換方式。
2、Cluster:服務框架,提供基于接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。
3、Registry:服務注冊中心,服務自動發現: 基于注冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
核心組件:
1、Provider:服務的提供方
2、Consumer:調用遠程服務的服務消費方
3、Registry:服務注冊和發現的注冊中心
4、Monitor:統計服務調用次數和調用時間的監控中心
5、Container:服務運行容器

2、Dubbo 的整體架構設計分層

整體架構

圖中左邊淡藍背景的為服務消費方使用的接口,右邊淡綠色背景的為服務提供方使用的接口,位于中軸線上的為雙方都用到的接口。圖中從下至上分為十層,各層均為單向依賴,右邊的黑色箭頭代表層之間的依賴關系,每一層都可以剝離上層被復用,其中,Service 和 Config 層為 API,其它各層均為 SPI。圖中綠色小塊的為擴展接口,藍色小塊為實現類,圖中只顯示用于關聯各層的實現類。圖中藍色虛線為初始化過程,即啟動時組裝鏈,紅色實線為方法調用過程,即運行時調時鏈,紫色三角箭頭為繼承,可以把子類看作父類的同一個節點,線上的文字為調用的方法。
各層說明:
config 配置層:對外配置接口,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類,也可以通過 spring 解析配置生成配置類
proxy 服務代理層:服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton,以ServiceProxy 為中心,擴展接口為 ProxyFactory
registry 注冊中心層:封裝服務地址的注冊與發現,以服務 URL 為中心,擴展接口為RegistryFactory, Registry, RegistryService
cluster 路由層:封裝多個提供者的路由及負載均衡,并橋接注冊中心,以 Invoker 為中心,擴展接口為 Cluster, Directory, Router, LoadBalance
monitor 監控層:RPC 調用次數和調用時間監控,以 Statistics 為中心,擴展接口為MonitorFactory, Monitor, MonitorService
protocol 遠程調用層:封裝 RPC 調用,以 Invocation, Result 為中心,擴展接口為 Protocol, Invoker, Exporter
exchange 信息交換層:封裝請求響應模式,同步轉異步,以 Request, Response 為中心,擴展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
transport 網絡傳輸層:抽象 mina 和 netty 為統一接口,以 Message 為中心,擴展接口為 Channel, Transporter, Client, Server, Codec
serialize 數據序列化層:可復用的一些工具,擴展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool

3、Dubbo 服務注冊與發現的流程

服務注冊與發現的流程

1、Provider(提供者)綁定指定端口并啟動服務
2、Provider連接注冊中心,并發本機 IP、端口、應用信息和提供服務信息發送至注冊中心存儲
3、Consumer(消費者),連接注冊中心 ,并發送應用信息、所求服務信息至注冊中心
4、注冊中心根據消費者所求服務信息匹配對應的提供者列表發送至Consumer 應用緩存。
5、Consumer 在發起遠程調用時基于緩存的消費者列表擇其一發起調用。
6、Provider 狀態變更會實時通知注冊中心、在由注冊中心實時推送至Consumer設計的原因:
Consumer 與 Provider 解偶,雙方都可以橫向增減節點數。注冊中心對本身可做對等集群,可動態增減節點,并且任意一臺宕掉后,將自動切換到另一臺
7、去中心化,雙方不直接依懶注冊中心,即使注冊中心全部宕機短時間內也不會影響服務的調用
8、服務提供者無狀態,任意一臺宕掉后,不影響使用

4、Dubbo 的服務調用流程

調用流程

1、Cluster 將 Directory 中的多個 Invoker 偽裝成一個Invoker,對上層透明,偽裝過程包含了容錯邏輯
2、Router 負責從多個 Invoker 中按路由規則選出子集,比如讀寫分離,應用隔離等
3、LoadBalance 負責從多個 Invoker 中選出具體的一個用于本次調用,選的過程包含了負載均衡算法

5、Dubbo 的通信框架

Dubbo 默認使用 Netty 框架,也是推薦的選擇,另外還集成有Mina、Grizzly

6、Dubbo 的注冊中心

Dubbo目前支持4種注冊中心(multicast,zookeeper,redis,simple),推薦使用Zookeeper

7、Dubbo 的支持協議

1、Dubbo 協議(官方推薦協議)
優點:采用NIO復用單一長連接,并使用線程池并發處理請求,減少握手和加大并發效率,性能較好(推薦使用)
缺點:大文件上傳時,可能出現問題(不使用 Dubbo 文件上傳)
2、RMI(Remote Method Invocation)協議
優點:JDK 自帶的能力。可與原生 RMI 互操作,基于 TCP 協議
缺點:偶爾連接失敗.
3、Hessian協議
優點:可與原生 Hessian 互操作,基于 HTTP 協議
缺點:需 hessian.jar 支持,http 短連接的*開銷大8

8、Dubbo 的序列化框架

Hessian 序列化:是修改過的 hessian lite,默認啟用
json 序列化:使用 FastJson 庫
java 序列化:JDK 提供的序列化,性能不理想
dubbo 序列化:未成熟的高效 java 序列化實現,不建議在生產環境使用

9、Dubbo 的負載均衡策略

1、Random LoadBalance,隨機(默認的負載均衡策略)
RandomLoadBalance 是加權隨機算法的具體實現,可以完全隨機,也可以按權重設置隨機概率。
2、RoundRobin LoadBalance,輪循
可以輪詢和加權輪詢。存在響應慢的提供者會累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。
3、LeastActive LoadBalance,最少活躍調用數
活躍調用數越小,表明該服務提供者效率越高,單位時間內可處理更多的請求。此時應優先將請求分配給該服務提供者。
4、ConsistentHash LoadBalance,一致性 Hash
一致性 Hash 算法,相同參數的請求一定分發到一個 provider 上去。provider 掛掉的時候,會基于虛擬節點均勻分配剩余的流量,抖動不會太大。

10、 Dubbo 的集群容錯策略

Dubbo 官網提出總共有六種容錯策略
1、Failover Cluster:失敗自動切換,當出現失敗,重試其它服務器。(默認)
2、Failfast Cluster:快速失敗,只發起一次調用,失敗立即報錯。通常用于非冪等性的寫操作,比如新增記錄。
3、Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用于寫入審計日志等操作。
4、Failback Cluster:失敗自動恢復,后臺記錄失敗請求,定時重發。通常用于消息通知操作。
5、Forking Cluster:并行調用多個服務器,只要一個成功即返回。通常用于實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks=”2”來設置最大并行數。
6、Broadcast Cluster:廣播調用所有提供者,逐個調用,任意一臺報錯則報錯。(2.1.0 開始支持) 通常用于通知所有提供者更新緩存或日志等本地資源信息。
總結:在實際應用中查詢語句容錯策略建議使用默認 Failover Cluster,而增刪改建議使用 Failfast Cluster 或者使用 Failover Cluster(retries=”0”)策略,防止出現數據重復添加等等其它問題!建議在設計接口時候把查詢接口方法單獨做一個接口提供查詢。

ZooKeeper

1、ZooKeeper 是什么

ZooKeeper 是一個開放源碼的分布式協調服務,它是集群的管理者,監視著集群中各個節點的狀態根據節點提交的反饋進行下一步合理操作。最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。

2、ZooKeeper 提供了什么

  1. 文件系統
  2. 通知機制

3、ZooKeeper 工作機制

ZooKeeper 從設計模式角度來理解:就是一個基于觀察者模式設計的分布式服務管理框架,它負責存儲和管理大家都關心的數據,然后接受觀察者的注冊,一旦這些數據的狀態發生變化,ZK 就將負責通知已經在 ZK 上注冊的那些觀察者做出相應的反應,從而實現集群中類似 Master/Slave 管理模式。


工作機制

4、ZooKeeper 特性

特性
  • ZooKeeper:一個領導者(leader),多個跟隨者(follower)組成的集群。
  • Leader 負責進行投票的發起和決議,更新系統狀態。
  • Follower 用于接收客戶請求并向客戶端返回結果,在選舉 Leader 過程中參與投票。
  • 集群中只要有半數以上節點存活,Zookeeper 集群就能正常服務。
  • 全局數據一致(單一視圖):每個 Server 保存一份相同的數據副本,Client 無論連接到哪個 Server,數據都是一致的。
  • 順序一致性: 從同一客戶端發起的事務請求,最終將會嚴格地按照順序被應用到 ZooKeeper 中去。
  • 原子性: 所有事務請求的處理結果在整個集群中所有機器上的應用情況是一致的,也就是說,要么整個集群中所有的機器都成功應用了某一個事務,要么都沒有應用。
  • 實時性,在一定時間范圍內,client 能讀到最新數據。
  • 可靠性: 一旦一次更改請求被應用,更改的結果就會被持久化,直到被下一次更改覆蓋。

5、Zookeeper 設計目標

簡單的數據結構 :Zookeeper 使得分布式程序能夠通過一個共享的樹形結構的名字空間來進行相互協調,即Zookeeper 服務器內存中的數據模型由一系列被稱為ZNode的數據節點組成,Zookeeper 將全量的數據存儲在內存中,以此來提高服務器吞吐、減少延遲的目的。
可以構建集群 :Zookeeper 集群通常由一組機器構成,組成 Zookeeper 集群的每臺機器都會在內存中維護當前服務器狀態,并且每臺機器之間都相互通信。
順序訪問 :對于來自客戶端的每個更新請求,Zookeeper 都會分配一個全局唯一的遞增編號,這個編號反映了所有事務操作的先后順序。
高性能 :Zookeeper 和 Redis 一樣全量數據存儲在內存中,100% 讀請求壓測 QPS 12-13W

6、Zookeeper 文件系統

Zookeeper 提供一個多層級的節點命名空間(節點稱為 znode)。與文件系統不同的是,這些節點都可以設置關聯的數據,而文件系統中只有文件節點可以存放數據而目錄節點不行。
Zookeeper 為了保證高吞吐和低延遲,在內存中維護了這個樹狀的目錄結構,這種特性使得 Zookeeper 不能用于存放大量的數據,每個節點的存放數據上限為1M。

7、四種類型的數據節點 Znode

  • PERSISTENT-持久節點
    除非手動刪除,否則節點一直存在于 Zookeeper 上
  • EPHEMERAL-臨時節點
    臨時節點的生命周期與客戶端會話綁定,一旦客戶端會話失效(客戶端與zookeeper 連接斷開不一定會話失效),那么這個客戶端創建的所有臨時節點都會被移除。
  • PERSISTENT_SEQUENTIAL-持久順序節點
    基本特性同持久節點,只是增加了順序屬性,節點名后邊會追加一個由父節點維護的自增整型數字。
  • EPHEMERAL_SEQUENTIAL-臨時順序節點
    基本特性同臨時節點,增加了順序屬性,節點名后邊會追加一個由父節點維護的自增整型數字。

8、ZAB 協議?

ZAB 協議是為分布式協調服務 Zookeeper 專門設計的一種支持崩潰恢復的原子廣播協議。
ZAB 協議包括兩種基本的模式:崩潰恢復和消息廣播。
當整個 zookeeper 集群剛剛啟動或者 Leader 服務器宕機、重啟或者網絡故障導致不存在過半的服務器與 Leader 服務器保持正常通信時,所有進程(服務器)進入崩潰恢復模式,首先選舉產生新的 Leader 服務器,然后集群中 Follower 服務器開始與新的 Leader 服務器進行數據同步,當集群中超過半數機器與該 Leader服務器完成數據同步之后,退出恢復模式進入消息廣播模式,Leader 服務器開始接收客戶端的事務請求生成事物提案來進行事務請求處理。

9、Zookeeper 的典型應用場景

ZooKeeper 是一個典型的分布式數據一致性解決方案,分布式應用程序可以基于 ZooKeeper 實現諸如數據發布/訂閱、負載均衡、命名服務、分布式協調/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能

10、核心概念

  • ZooKeeper 本身就是一個分布式程序(只要半數以上節點存活,ZooKeeper 就能正常服務)。
  • 為了保證高可用,最好是以集群形態來部署 ZooKeeper,這樣只要集群中大部分機器是可用的(能夠容忍一定的機器故障),那么 ZooKeeper 本身仍然是可用的。
  • ZooKeeper 將數據保存在內存中,這也就保證了高吞吐量和低延遲(但是內存限制了能夠存儲的容量不太大,此限制也是保持 znode 中存儲的數據量較小的進一步原因)。
  • ZooKeeper 是高性能的。在“讀”多于“寫”的應用程序中尤其的高性能,因為“寫”會導致所有的服務器間同步狀態。(“讀”多于“寫”是協調服務的典型場景。)
  • ZooKeeper 底層其實只提供了兩個功能:管理(存儲、讀取)用戶程序提交的數據和為用戶程序提交數據節點監聽服務

11、Zookeeper Watcher 機制

Zookeeper 允許用戶在指定節點上注冊一些 Watcher,當 Znode 發生變化時,將觸發并刪除一個 watch。當 watch 被觸發時客戶端會收到一個數據包,指示 znode 已經被修改。如果客戶端和 ZooKeeper 服務器之間的連接中斷,客戶端將收到本地通知。該機制是 Zookeeper 實現分布式協調服務的重要特性。
3.6.0中的新增功能:客戶端還可以在 znode 上設置永久性的遞歸監視,這些監視在觸發時不會刪除,并且會以遞歸方式觸發已注冊 znode 以及所有子 znode 的更改。
ZooKeeper 客戶端(Client)會在指定的節點(/Configuration/B)上注冊一個 Watcher,ZNode 上的 B 被更新的時候,服務端就會通知 Client1 和 Client2。


watch 機制

12、Zookeeper 的會話(Session)

Session 指的是 ZooKeeper 服務器與客戶端會話。
在 ZooKeeper 中,一個客戶端連接是指客戶端和服務器之間的一個 TCP 長連接。客戶端啟動的時候,首先會與服務器建立一個 TCP 連接,從第一次連接建立開始,客戶端會話的生命周期也開始了。通過這個連接,客戶端能夠通過心跳檢測與服務器保持有效的會話,也能夠向 Zookeeper 服務器發送請求并接受響應,同時還能夠通過該連接接收來自服務器的 Watch 事件通知。
Session 作為會話實體,用來代表客戶端會話,其包括 4 個屬性:

  • SessionID,用來全局唯一識別會話;
  • TimeOut,會話超時事件。客戶端在創造 Session 實例的時候,會設置一個會話超時的時間。當由于服務器壓力太大、網絡故障或是客戶端主動斷開連接等各種原因導致客戶端連接斷開時,只要在 sessionTimeout 規定的時間內能夠重新連接上集群中任意一臺服務器,那么之前創建的會話仍然有效;
  • TickTime,下次會話超時時間點;
  • isClosing,當服務端如果檢測到會話超時失效了,會通過設置這個屬性將會話關閉。

13、Zookeeper 的ACL

Zookeeper 采用 ACL(Access Control Lists)策略來進行權限控制,類似于 UNIX 文件系統的權限控制。Zookeeper 定義了如下 5 種權限:

  • CREATE: 創建子節點的權限
  • READ: 獲取節點數據和子節點列表的權限
  • WRITE: 更新節點數據的權限
  • DELETE: 刪除子節點的權限
  • ADMIN: 設置節點ACL的權限
    其中尤其需要注意的是,CREATE 和 DELETE 這兩種權限都是針對子節點的權限控制。

14、Zookeeper 的集群角色

最典型集群模式:Master/Slave 模式(主備模式)。在這種模式中,通常 Master 服務器作為主服務器提供寫服務,其他的 Slave 從服務器通過異步復制的方式獲取 Master 服務器最新的數據提供讀服務。
但是,在 ZooKeeper 中沒有選擇傳統的 Master/Slave 概念,而是引入了Leader、Follower 和 Observer 三種角色。

  • Leader:為客戶端提供讀和寫的服務,負責投票的發起和決議,更新系統狀態
  • Follower:為客戶端提供讀服務,如果是寫服務則轉發給 Leader。在選舉過程中參與投票
  • Observer:為客戶端提供讀服務器,如果是寫服務則轉發給 Leader。不參與選舉過程中的投票,也不參與“過半寫成功”策略。在不影響寫性能的情況下提升集群的讀性能。此角色是在 zookeeper3.3 系列新增的角色。

server 狀態:

  • LOOKING:尋找Leader狀態
  • LEADING:領導者狀態,表明當前服務器角色是 Leader
  • FOLLOWING:跟隨者狀態,表明當前服務器角色是 Follower
  • OBSERVING:觀察者狀態,表明當前服務器角色是 Observer

15、Zookeeper 的選舉機制

選舉機制
  • 服務器1啟動,此時只有它一臺服務器啟動了,它發出去的報文沒有任何響應,所以它的選舉狀態一直是LOOKING 狀態。
  • 服務器2啟動,它與最開始啟動的服務器1進行通信,互相交換自己的選舉結果,由于兩者都沒有歷史數據,所以 id 值較大的服務器2勝出,但是由于沒有達到超過半數以上的服務器都同意選舉它(這個例子中的半數以上是3),所以服務器1、2還是繼續保持 LOOKING 狀態。
  • 服務器3啟動,根據前面的理論分析,服務器3成為服務器1、2、3中的老大,而與上面不同的是,此時有三臺服務器選舉了它,所以它成為了這次選舉的Leader。
  • 服務器4啟動,根據前面的分析,理論上服務器4應該是服務器1、2、3、4中最大的,但是由于前面已經有半數以上的服務器選舉了服務器3,所以它只能接受當小弟的命了。
  • 服務器5啟動,同4一樣當小弟。

Kafka

1、為什么要使用 Kafka ?

緩沖和削峰:上游數據時有突發流量,下游可能扛不住,或者下游沒有足夠多的機器來保證冗余,kafka 在中間可以起到一個緩沖的作用,把消息暫存在 kafka 中,下游服務就可以按照自己的節奏進行慢慢處理。
解耦和擴展性:項目開始的時候,并不能確定具體需求。消息隊列可以作為一個接口層,解耦重要的業務流程。只需要遵守約定,針對數據編程即可獲取擴展能力。
冗余:可以采用一對多的方式,一個生產者發布消息,可以被多個訂閱 topic 的服務消費到,供多個毫無關聯的業務使用。健壯性: 消息隊列可以堆積請求,所以消費端業務即使短時間死掉,也不會影響主要業務的正常進行。
異步通信:很多時候,用戶不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許用戶把一個消息放入隊列,但并不立即處理它。想向隊列中放入多少消息就放多少,然后在需要的時候再去處理它們 。

2、 Kafka 消費過的消息如何再消費?

kafka 消費消息的 offset 是定義在 zookeeper 中的, 如果想重復消費 kafka 的消息, 可以在 redis 中自己記錄 offset 的 checkpoint 點(n 個),當想重復消費消息時,通過讀取 redis 中的 checkpoint 點進行 zookeeper 的 offset 重設,這樣就可以達到重復消費消息的目的了 。

3、Kafka 的數據是放在磁盤上還是內存上,為什么速度會快

kafka 使用的是磁盤存儲,速度快的原因如下。
順序寫入:因為硬盤是機械結構,每次讀寫都會尋址->寫入,其中尋址是一個“機械動作”,它是耗時的。所以硬盤 “討厭”隨機 I/O, 喜歡順序 I/O。為了提高讀寫硬盤的速度,Kafka 就是使用順序 I/O。
Memory Mapped Files(內存映射文件):64 位操作系統中一般可以表示 20G 的數據文件,它的工作原理是直接利用操作系統的 Page 來實現文件到物理內存的直接映射。完成映射之后你對物理內存的操作會被同步到硬盤上。
Kafka 高效文件存儲設計:Kafka 把 topic 中一個 parition 大文件分成多個小文件段,通過多個小文件段,就容易定期清除或刪除已經消費完文件,減少磁盤占用。通過索引信息可以快速定位 message 和確定 response 的 大 小。通過 index 元數據全部映射到 memory(內存映射文件),可以避免 segment file 的 IO 磁盤操作。通過索引文件稀疏存儲,可以大幅降低 index 文件元數據占用空間大小。

4、Kafka 數據怎么保障不丟失?

這里需要分成三個點說,一個是生產者端,一個消費者端,一個 broker 端 。
生產者數據不丟失
kafka 的 ack 機制:在 kafka 發送數據的時候,每次發送消息都會有一個確認反饋機制,確保消息正常的能夠被收到,其中狀態有 0,1,-1。
如果是同步模式:ack 設置為 0,風險很大,一般不建議設置為 0。即使設置為 1,也會隨著 leader 宕機丟失數據。所以如果要嚴格保證生產端數據不丟失,可設置為-1 。
如果是異步模式:也會考慮 ack 的狀態,除此之外,異步模式下的有個 buffer,通過 buffer 來進行控制數據的發送,有兩個值來進行控制,時間閾值與消息的數量閾值,如果 buffer 滿了數據還沒有發送出去,有個選項是配置是否立即清空 buffer。可以設置為-1,永久阻塞, 也就數據不再生產。異步模式下,即使設置為-1。也可能因為程序員的不科學操作,操作數據丟失,比如 kill -9,但這是特別的例外情況。
注:ack=0:producer 不等待 broker 同步完成的確認,繼續發送下一條(批)信息。ack=1(默認):producer 要等待 leader 成功收到數據并得到確認,才發送下一條 message。ack=-1:producer 得到 follwer 確認,才發送下一條數據。
消費者數據不丟失
通過 offset commit 來保證數據的不丟失,kafka 自己記錄了每次消費的 offset 數值, 下次繼續消費的時候,會接著上次的 offset 進行消費。而 offset 的信息在 kafka0.8 版本之前保存在 zookeeper 中,在 0.8 版本之后保存到 topic 中,即使消費者在運行過程中掛掉了,再次啟動的時候會找到 offset 的值,找到之前消費消息的位置,接著消費,由于 offset 的信息寫入的時候并不是每條消息消費完成后都寫入的,所以這種情況有可能會造成重復消費,但是不會丟失消息 。唯一例外的情況是,我們在程序中給原本做不同功能的兩個 consumer 組設置。KafkaSpoutConfig.bulider.setGroupid 的時候設置成了一樣的 groupid,這種情況會導致這兩個組共享同一份數據,就會產生組 A 消費 partition1,partition2 中的消息,組 B 消費 partition3 的消息,這樣每個組消費的消息都會丟失,都是不完整的。為了保證每個組都獨享一份消息數據,groupid 一定不要重復才行。
kafka 集群中的 broker 的數據不丟失
每個 broker 中的 partition 我們一般都會設置有 replication(副本)的個數,生產者寫入的時候首先根據分發策略(有 partition 按 partition,有 key 按 key,都沒有輪詢)寫入到 leader 中,follower(副本)再跟 leader 同步數據,這樣有了備份,也可以保證消息數據的不丟失 。

5、Kafka 數據分區和消費者的關系?

每個分區只能由同一個消費組內的一個消費者(consumer)來消費,可以由不同的消費組的消費者來消費,同組的消費者則起到并發的效果

6、采集數據為什么選擇 Kafka?

在采集層,主要可以使用 Flume, Kafka 等技術 。
Flume:Flume 是管道流方式,提供了很多的默認實現,讓用戶通過參數部署,及擴展 API 。
Kafka:Kafka 是一個可持久化的分布式的消息隊列。 Kafka 是一個非常通用的系統。你可以有許多生產者和很多的消費者共享多個主題 Topics 。
相比之下,Flume 是一個專用工具被設計為旨在往 HDFS,HBase 發送數據。它對 HDFS 有特殊的優化,并且集成了 Hadoop 的安全特性。所以,Cloudera 建議如果數據被多個系統消費的話,使用 kafka;如果數據被設計給 Hadoop 使用,使用 Flume

7、Kafka 的數據 offset 讀取流程?

連接 ZK 集群,從 ZK 中拿到對應 topic 的 partition 信息和 partition 的 Leader 的相關信息連接到對應 Leader 對應的 brokerconsumer 將自己保存的 offset 發送給 LeaderLeader 根據 offset 等信息定位到 segment(索引文件和日志文件)根據索引文件中的內容,定位到日志文件中該偏移量對應的開始位置讀取相應長度的數據并返回給 consumer 。

8、Kafka 重啟是否會導致數據丟失?

kafka 是將數據寫到磁盤的,一般數據不會丟失。但是在重啟 kafka 過程中,如果有消費者消費消息,那么 kafka 如果來不及提交 offset,可能會造成數據的不準確(丟失或者重復消費)

9、Kafka 宕機了如何解決?

先考慮業務是否受到影響:
kafka 宕機了,首先我們考慮的問題應該是所提供的服務是否因為宕機的機器而受到影響,如果服務提供沒問題,如果實現做好了集群的容災機制,那么這塊就不用擔心了。
節點排錯與恢復:
想要恢復集群的節點,主要的步驟就是通過日志分析來查看節點宕機的原因,從而解決,重新恢復節點 。

10、為什么 Kafka 不支持讀寫分離?

在 Kafka 中,生產者寫入消息、消費者讀取消息的操作都是與 leader 副本進行交互的,從 而實現的是一種主寫主讀的生產消費模型。
Kafka 并不支持主寫從讀,因為主寫從讀有 2 個很明顯的缺點 :
數據一致性問題:
數據從主節點轉到從節點必然會有一個延時的時間窗口,這個時間窗口會導致主從節點之間的數據不一致。某一時刻,在主節點和從節點中 A 數據的值都為 X, 之后將主節點中 A 的值修改為 Y,那么在這個變更通知到從節點之前,應用讀取從節點中的 A 數據的值并不為最新的 Y,由此便產生了數據不一致的問題 。
延時問題:
類似 Redis 這種組件,數據從寫入主節點到同步至從節點中的過程需要經歷 網絡→主節點內存→網絡→從節點內存 這幾個階段,整個過程會耗費一定的時間。而在 Kafka 中,主從同步會比 Redis 更加耗時,它需要經歷 網絡→主節點內存→主節點磁盤→網絡→從節點內存→從節點磁盤 這幾個階段 。對延時敏感的應用而言,主寫從讀的功能并不太適用 。
而 kafka 的主寫主讀的優點就很多了:
可以簡化代碼的實現邏輯,減少出錯的可能; 將負載粒度細化均攤,與主寫從讀相比, 不僅負載效能更好,而且對用戶可控 ; 沒有延時的影響 ; 在副本穩定的情況下,不會出現數據不一致的情況 。

11、Kafka 消息數據積壓,Kafka 消費能力不足怎么處理?

如果是 Kafka 消費能力不足,則可以考慮增加 Topic 的分區數,并且同時提升消費組的消費者數量,消費者數=分區數。(兩者缺一不可)
如果是下游的數據處理不及時: 提高每批次拉取的數量。批次拉取數據過少(拉取數據/處理時間<生產速度),使處理的數據小于生產的數據,也會造成數據積壓 。

12、Kafka 單條日志傳輸大小?

kafka 對于消息體的大小默認為單條最大值是 1M 但是在我們應用場景中, 常常會出現一條消息大于 1M,如果不對 kafka 進行配置。則會出現生產者無法將消息推送到 kafka 或消費者無法去消費 kafka 里面的數據, 這時我們就要對 kafka 進行配置

13、Kafka 內部如何保證順序,結合外部組件如何保證消費者的順序?

kafka 只能保證 partition 內是有序的,但是 partition 間的有序是沒辦法的。我們常用的做法,是從業務上把需要有序的打到同一個 partition

Redis

1、Redis為什么快

  • 完全基于內存操作
  • 使?單線程,避免了線程切換和競態產生的消耗
  • 基于?阻塞的IO多路復?機制
  • C語?實現,優化過的數據結構,基于?種基礎的數據結構,redis做了?量的優化,性能極?

2、Redis 的數據類型

Redis 支持五種數據類型:string(字符串),hash(哈希),list( 列表),set(集合) 及sorted set(有序集合)

3、Redis的持久化

Redis持久化?案分為RDB和AOF兩種。

  • RDB持久化是把當前進程數據生成快照保存到硬盤的過程,觸發RDB持久化過程分為手動觸發和自動觸發
  • AOF(append only file)持久化:以獨立日志的方式記錄每次寫命令, 重啟時再重新執行AOF文件中的命令達到恢復數據的目的。AOF的主要作用是解決了數據持久化的實時性,目前已經是Redis持久化的主流方式
    RDB恢復速度快,AOF實時性好,數據一致性強
  • 一般來說, 如果想達到足以媲美數據庫的數據安全性,應該同時使用兩種持久化功能。在這種情況下,當 Redis 重啟的時候會優先載入 AOF 文件來恢復原始的數據,因為在通常情況下 AOF 文件保存的數據集要比 RDB 文件保存的數據集要完整。
  • 如果可以接受數分鐘以內的數據丟失,那么可以只使用 RDB 持久化。

4、緩存穿透、緩存擊穿、緩存雪崩的區別和解決方案

緩存穿透:訪問一個不存在的key,緩存不起作用,請求會穿透到DB,流量大時DB會掛掉。
解決方案:

  • 采用布隆過濾器,使用一個足夠大的bitmap,用于存儲可能訪問的key,不存在的key直接被過濾;
  • 攔截器,接?層增加校驗,如給id做校驗,id<=0的直接攔截。
  • 從cache和db都取不到,可以將key-value寫為key-null,設置較短過期時間,如30秒(設置太長會導致正常情況也沒法使用)。這樣可以防止攻擊用戶反復用同一個id暴力攻擊。
    緩存擊穿:一個存在的key,在緩存過期的一刻,同時有大量的請求,這些請求都會擊穿到DB,造成瞬時DB請求量大、壓力驟增。
    解決方案:
  • 設置熱點數據永遠不過期。
  • 加互斥鎖。
    緩存雪崩:大量的key設置了相同的過期時間,導致在緩存在同一時刻全部失效,造成瞬時DB請求量大、壓力驟增,引起雪崩。
    解決方案:
  • 緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。
  • 如果緩存數據庫是分布式部署,將熱點數據均勻分布在不同的緩存數據庫中。
  • 設置熱點數據永遠不過期。

5、Redis過期鍵的刪除策略

Redis采用的是定期刪除+惰性刪除策略

  • 為什么不用定時刪除策略?
    定時刪除,用一個定時器來負責監視key,過期則自動刪除。雖然內存及時釋放,但是十分消耗CPU資源。在大并發請求下,CPU要將時間應用在處理請求,而不是刪除key,因此沒有采用這一策略.
  • 定期刪除+惰性刪除是如何工作的呢?
    定期刪除,redis默認每個100ms檢查,是否有過期的key,有過期key則刪除。需要說明的是,redis不是每個100ms將所有的key檢查一次,而是隨機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis豈不是卡死)。因此,如果只采用定期刪除策略,會導致很多key到時間沒有刪除。
    于是,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key如果設置了過期時間那么是否過期了?如果過期了此時就會刪除。
  • 采用定期刪除+惰性刪除就沒其他問題了么?
    不是的,如果定期刪除沒刪除key。然后你也沒即時去請求key,也就是說惰性刪除也沒生效。這樣,redis的內存會越來越高。那么就應該采用內存淘汰機制。

6、Redis內存淘汰策略

內存淘汰策略

注意這里的6種機制,volatile 和allkeys 規定了是對已設置過期時間的數據集淘汰數據還是從全部數據集淘汰數據, 后面的lru、ttl 以及random 是三種不同的淘汰策略,再加上一種no-enviction 永不回收的策略。

7、數據不一致問題及其解決方案

問題:先操作緩存,在寫數據庫成功之前,如果有讀請求發生,可能導致舊數據入緩存,引發數據不一致。
解決方案
方案1:Redis設置key的過期時間。
方案2:采用延時雙刪策略。

  • 先淘汰緩存
  • 再寫數據庫(這兩步和原來一樣)
  • 休眠n毫秒,再次淘汰緩存
    這么做,可以將n毫秒內所造成的緩存臟數據,再次刪除。(為何是n毫秒?需要評估自己的項目的讀數據業務邏輯的耗時。這么做的目的,就是確保讀請求結束,寫請求可以刪除讀請求造成的緩存臟數據。當然這種策略還要考慮redis和數據庫主從同步的耗時。)

8、如何處理熱key?

對熱key的處理,最關鍵的是對熱點key的監控,可以從這些端來監控熱點key:

  • 客戶端 客戶端其實是距離key“最近”的地方,因為Redis命令就是從客戶端發出的,例如在客戶端設置全局字典(key和調用次數),每次調用Redis命令時,使用這個字典進行記錄。
  • 代理端 像Twemproxy、Codis這些基于代理的Redis分布式架構,所有客戶端的請求都是通過代理端完成的,可以在代理端進行收集統計。
  • Redis服務端 使用monitor命令統計熱點key是很多開發和運維人員首先想到,monitor命令可以監控到Redis執行的所有命令。
    只要監控到了熱key,對熱key的處理就簡單了:
  • 把熱key打散到不同的服務器,降低壓?
  • 加??級緩存,提前加載熱key數據到內存中,如果redis宕機,?內存查詢

9、Redis應用:分布式鎖

setnx命令 + 鎖超時釋放,Redis 2.8 版本中加入了 set 指令的擴展參數,使得 setnx 和expire 指令可以一起執行

10、Redis的高可用

Redis保證高可用主要有三種方式:主從、哨兵、集群
主從復制,是指將一臺 Redis 服務器的數據,復制到其他的 Redis 服務器。前者稱為 主節點(master),后者稱為 從節點(slave)。且數據的復制是 單向 的,只能由主節點到從節點。Redis 主從復制支持 主從同步 和 從從同步 兩種,后者是 Redis 后續版本新增的功能,以減輕主節點的同步負擔。

Redis Sentinel ,它由兩部分組成,哨兵節點和數據節點:
哨兵節點: 哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的 Redis 節點,不存儲數據,對數據節點進行監控。
數據節點: 主節點和從節點都是數據節點;
在復制的基礎上,哨兵實現了 自動化的故障恢復 功能,下面是官方對于哨兵功能的描述:

  • 監控(Monitoring): 哨兵會不斷地檢查主節點和從節點是否運作正常。
  • 自動故障轉移(Automatic failover): 當 主節點 不能正常工作時,哨兵會開始 自動故障轉移操作,它會將失效主節點的其中一個 從節點升級為新的主節點,并讓其他從節點改為復制新的主節點。
  • 配置提供者(Configuration provider): 客戶端在初始化時,通過連接哨兵來獲得當前 Redis 服務的主節點地址。
  • 通知(Notification): 哨兵可以將故障轉移的結果發送給客戶端。
    其中,監控和自動故障轉移功能,使得哨兵可以及時發現主節點故障并完成轉移。而配置提供者和通知功能,則需要在與客戶端的交互中才能體現。

前面說到了主從存在高可用和分布式的問題,哨兵解決了高可用的問題,而集群就是終極方案,一舉解決高可用和分布式問題

  • 數據分區: 數據分區 (或稱數據分片) 是集群最核心的功能。集群將數據分散到多個節點,一方面 突破了 Redis 單機內存大小的限制,存儲容量大大增加;另一方面 每個主節點都可以對外提供讀服務和寫服務,大大提高了集群的響應能力。
  • 高可用: 集群支持主從復制和主節點的 自動故障轉移 (與哨兵類似),當任一節點發生故障時,集群仍然可以對外提供服務。

11、布隆過濾器

布隆過濾器,它是一個連續的數據結構,每個存儲位存儲都是一個bit,即0或者1, 來標識數據是否存在。存儲數據的時時候,使用K個不同的哈希函數將這個變量映射為bit列表的的K個點,把它們置為1。


布隆過濾器

我們判斷緩存key是否存在,同樣,K個哈希函數,映射到bit列表上的K個點,判斷是不是1:如果全不是1,那么key不存在;如果都是1,也只是表示key可能存在。
布隆過濾器也有一些缺點:
它在判斷元素是否在集合中時是有一定錯誤幾率,因為哈希算法有一定的碰撞的概率,不支持刪除元素。

12、一致性Hash算法

將整個 Hash 值空間組織成一個虛擬的圓環,然后將緩存節點的 IP 地址或者主機名做 Hash 取值后,放置在這個圓環上。當我們需要確定某一個 Key 需 要存取到哪個節點上的時候,先對這個 Key 做同樣的 Hash 取值,確定在環上的位置,然后按照順時針方向在環上“行走”,遇到的第一個緩存節點就是要訪問的節點


一致性Hash算法
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容