Flume不會復制消息,因此即使使用可靠的文件渠道,當Flume進程宕機后,你就無法訪問這些消息了(當然Flume進程重啟,從磁盤上恢復之前狀態后,可以繼續對消息進行處理)。因此如果對 HA高可用性具有很高要求,我們建議Kafka;
Flume是一個海量日志采集、聚合和傳輸的系統,支持在日志系統中定制各類數據發送方,用於收集數據。同時,Flume提供對數據進行簡單處理,並寫到各種數據接受方的能力。Flume以流方式處理數據,可作為代理持續運行。當新的數據可用時,Flume能夠立即獲取數據並輸出至目標,這樣就可以在很大程度上解決實時性問題。
利用Flume采集關系數據庫表數據最大的優點是配置簡單,不用編程。相比tungsten-replicator的復雜性,Flume只要在flume.conf文件中配置source、channel及sink的相關屬性,已經沒什么難度了。
- 在源庫上執行了查詢,具有入侵性。
- 通過輪詢的方式實現增量,只能做到准實時,而且輪詢間隔越短,對源庫的影響越大。
- 只能識別新增數據,檢測不到刪除與更新。
- 要求源庫必須有用於表示增量的字段。
Canel,Databus,Puma等,這些都是需要部署server和client的。其中server端是由這些工具實現,配置了就可以讀binlog,而client端是需要我們動手編寫程序的,遠沒有達到我即插即用的期望和懶人的標准。
再來看看flume,只需要寫一個配置文件,就可以完成數據同步的操作。官網:http://flume.apache.org/FlumeUserGuide.html#flume-sources。它的數據源默認是沒有讀取binlog日志實現的,也沒有讀數據庫表的官方實現,只能用開源的自定義source:https://github.com/keedio/flume-ng-sql-source
flume需要考慮同步的格式,原插件flume-ng-sql-source只支持csv的格式
如果使用到大數據的技術,flume更好。Flume 和 Kafka 可以很好地結合起來使用。如果你的設計需要從 Kafka 到 Hadoop 的流數據,使用 Flume 代理並配置 Kafka 的 Source 讀取數據也是可行的:你沒有必要實現自己的消費者。你可以直接利用Flume 與HDFS 及HBase 的結合的所有好處。
Flume 采集日志是通過流的方式直接將日志收集到存儲層,而 kafka 是將緩存在 kafka集群,待后期可以采集到存儲層。
Flume 采集中間停了,可以采用文件的方式記錄之前的日志,而 kafka 是采用 offset 的方式記錄之前的日志。
數據怎么采集到 Kafka,實現方式?
使用官方提供的 flumeKafka 插件,插件的實現方式是自定義了 flume 的 sink,將數據從channle 中取出,通過 kafka 的producer 寫入到 kafka 中,可以自定義分區等。
Flume 采集數據會丟失嗎?
不會,因為 channel 可以存儲在 file 中,而且 flume 本身是有事務的。
可以做 sink 組,一個壞掉了,就用另一個。
flume 有哪些組件,flume 的 source、channel、sink 具體是做什么的?
1)source:用於采集數據,Source 是產生數據流的地方,同時 Source 會將產生的數據
流傳輸到 Channel,這個有點類似於 Java IO 部分的 Channel。
2)channel:用於橋接 Sources 和 Sinks,類似於一個隊列。
3)sink:從 Channel 收集數據,將數據寫到目標源(可以是下一個 Source,也可以是 HDFS或者 HBase)。
source :搜集數據
channel :數據緩存
sink :把數據發送到目的地
常用 source 類型 :
1、 監控文件 :exec
2、監控目錄 :spooldir
使用canal做數據備份而不用mysql自帶的主從備份的場景主要為:
跨數據庫的數據備份,例如mysql => oracle
數據異構,即對同一份數據做不同的分庫分表查詢。例如賣家和買家各自分庫索引
canal將自己偽裝成mysql的從庫,從主庫那里消費並解析binlog,通過日志來保持數據的一致性。
- canal 模擬 MySQL slave 的交互協議,偽裝自己為 MySQL slave ,向 MySQL master 發送dump 協議
- MySQL master 收到 dump 請求,開始推送 binary log 給 slave (即 canal )
- canal 解析 binary log 對象(原始為 byte 流)
增量同步和bai全量同步是數du據庫同步的兩zhi種方式。全量同步是一次dao性同步全部數據zhuan,增量同步則只shu同步兩個數據庫不同的部分。
1.Canal連接到A數據庫,模擬slave
2.canal-client與Canal建立連接,並訂閱對應的數據庫表
3.A數據庫發生變更寫入到binlog,Canal向數據庫發送dump請求,獲取binlog並解析,發送解析后的數據給canal-client
4.canal-client收到數據,將數據同步到新的數據庫
為了高可用和更高的性能,我們會創建多個canal-client構成一個集群,來進行解析並同步到新的數據庫。為了保證canal-client集群解析消費binlog的順序性,通常會選擇canal + kafka 的方案
我們配置了kafka的partitionHash,並且我們一個Topic就是一個表。這樣的效果就是,一個表的數據只會推到一個固定的partition中,然后再推給consumer進行消費處理,同步到新的數據庫。通過這種方式,解決了之前碰到的binlog日志順序處理的問題。這樣即使我們部署了多個kafka consumer端,構成一個集群,這樣consumer從一個partition消費消息,就是消費處理同一個表的數據。這樣對於一個表來說,犧牲掉了並行處理,不過個人覺得,憑借kafka的性能強大的處理架構,我們的業務在kafka這個節點產生瓶頸並不容易。並且我們的業務目的不是實時一致性,在一定延遲下,兩個數據庫保證最終一致性。
這篇文章大部分篇幅用於介紹其他中間件是怎么部署的,這個問題側面說明了Canal本身部署並不復雜,它的配置文件屬性項比較多,但是實際上需要自定義和改動的配置項是比較少的,也就是說明了它的運維成本和學習成本並不高。
數據落地
采集之后必然需要將數據落地,即存儲層,常見的有:
- MYSQL、Oracle
- Hive、Hdfs
- HBase
- Redis
- ElasticSearch
- MongoDB
需要說明的是,數據采集之后往往會先發送給Kafka這種消息隊列,然后才真正落地到各種存儲層中。
數據匯聚設計原則
從中台的角度來考慮,數據匯聚層的設計需要考慮幾個關鍵的因素:
- 設計之初就應該考慮支持各類數據源 ,支持不同來源、不同類型的數據源。數據匯聚層不是為某一種數據而生的,應該做到通用化。
- 需要支持不同時間窗口的數據采集,實時的、非實時的、歷史的。
- 操作友好簡單,即使是不懂技術的人,也可以方便的操作,進行數據同步;舉例mysql同步到hive,你不應該讓用戶去填寫復雜的sqoop任務參數,而是只需要選擇源表和目的表,其他事情都交給中台去完成。
- 合理選擇存儲層,不同數據源應存儲在不同的地方,比如日志數據肯定不適合mysql。
后端實時數據,實時接入mysql。為了不影響線上系統的正常使用,同時能夠將數據發送到大數據平台,本項目使用Canal來解析實時數據,Flume收集數據並數據發送到實時計算業務流程和離線計算兩個流程中。實時數據處理流程使用Canal+Flume+Kafka+SparkStreaming等技術。
一些文章
使用canal+Kafka進行數據庫同步實踐:https://zhuanlan.zhihu.com/p/154412917
基於Canal和Kafka實現MySQL的Binlog近實時同步:https://zhuanlan.zhihu.com/p/115586732
Canal+Kafka實現MySQL與Redis數據同步:https://zhuanlan.zhihu.com/p/186035586
大數據環境下該如何優雅地設計數據分層:https://zhuanlan.zhihu.com/p/27395332
日志采集系統flume和kafka有什么區別及聯系,它們分別在什么時候使用,什么時候又可以結合?:https://www.zhihu.com/question/36688175
canal入門到實戰及面試:https://www.cnblogs.com/huanghanyu/articles/12874376.html
canal動態監控Mysql,將binlog日志解析后,把采集到的數據發送到Kafka: https://segmentfault.com/a/1190000024443393
Flume+Kafka雙劍合璧玩轉大數據平台日志采集:https://zhuanlan.zhihu.com/p/52087481
Flume+Kafka+Storm+Redis構建大數據實時處理系統:https://zhuanlan.zhihu.com/p/50537056
Flume 日志采集、聚合和傳輸:https://juejin.cn/post/6844904199063339021
分布式日志收集框架 Flume:https://juejin.cn/post/6844903944141930510
為什么選擇Canal + Flume + Kafka 架構而不是Canal + Kafka架構?:https://blog.csdn.net/u012965373/article/details/96314562
flume+kafka的架構:
- 在數據處理方面:Flume能夠對數據進行簡單處理,並且具有寫道各種數據接受方的能力,這能實現我們項目中——需要支持更多類型的數據庫
- 在一系列博客中,我發現flume+kafka的架構更多用在大數據平台上,比如將數據同步到hadoop生態圈,hdfs,hive,hbase等。所以如果考慮到大數據的應用,可以選擇flume框架。
- 在配置方面:Flume采集關系數據庫表數據最大的優點是配置簡單,不用編程。
- flume只要在flume.conf文件中配置source、channel及sink的相關屬性,相比canal更簡單。
- 不過flume的數據源默認是沒有讀取binlog日志實現的,也沒有讀數據庫表的官方實現,只能用開源的自定義source:https://github.com/keedio/flume-ng-sql-source
- 和kafka的配合方面:
- Flume 采集日志是通過流的方式直接將日志收集到存儲層,而 kafka 是將緩存在 kafka集群,待后期可以采集到存儲層。
- Flume 采集中間停了,可以采用文件的方式記錄之前的日志,而 kafka 是采用 offset 的方式記錄之前的日志。
- 兩者可以形成和好的互補。
- flume和kafka的配合主要體現在他的sink組件
- sink:從 Channel 收集數據,將數據寫到目標源(可以是下一個 Source,也可以是 HDFS或者 HBase)。
- 使用官方提供的 flumeKafka 插件,插件的實現方式是自定義了 flume 的 sink,將數據從channle 中取出,通過 kafka 的producer 寫入到 kafka 中,可以自定義分區等。
- 缺點:
- 在源庫上執行了查詢,具有入侵性。
- 通過輪詢的方式實現增量,只能做到准實時,而且輪詢間隔越短,對源庫的影響越大。
- 只能識別新增數據,檢測不到刪除與更新。
- 要求源庫必須有用於表示增量的字段。
對於flume+kafka我的個人觀點:
- flume+kafka的架構我在博客中更多的看到是在大數據中的應用,因為flume本身是大數據的框架。如果考慮到大數據技術的應用或決定使用大數據生態圈的架構,可以使用flume+kafka來實時采集mysql數據。但是flume是做不到實時增量同步的,只能說是准實時,不過也能滿足大部分的需求了。
- 同時flume相比起canal來說配置簡單,對比canal不用搭建主庫從庫,還可以將應用產生的數據存儲到任何集中存儲器中。Flume的管道是基於事務,保證了數據在傳送和接收時的一致性。
- 但是如果字段刪除或者更新頻繁,flume+kafka的效果可能不好。而且在對mysql等關系型數據庫、redis、es等,canal似乎更被廣泛接受(目前主流)
canal+kafka的架構:
Canal+Kafka實現數據增量同步是目前比較常見的做法。
- 在數據處理方面:canal主要用途是基於MySQL數據庫增量日志解析,提供增量數據訂閱和消費。比如,B服務數據庫的數據來源於A服務的數據庫;A服務的數據有變更操作時,需要同步到B服務中。使用canal+kafka目的就是通過數據庫的binlog進行同步。這種解決方案,與A服務是獨立的,不會和A服務有代碼上的耦合。可以直接TCP連接進行傳輸數據,優於接口調用的方式。
- 在結構化數據和非結構化數據的數據同步工作中canal有很好的表現,項目的改進需求中需要支持更多類型的數據庫、需要支持非結構化的數據同步這兩項canal都可以很好的適應。
- 在配置方面:為了高可用和更高的性能,我們會創建多個canal-client構成一個集群,來進行解析並同步到新的數據庫。為了保證canal-client集群解析消費binlog的順序性,通常會選擇canal + kafka 的方案,canal同步數據庫的步驟有:
- Canal連接到A數據庫,模擬slave
- canal-client與Canal建立連接,並訂閱對應的數據庫表
- A數據庫發生變更寫入到binlog,Canal向數據庫發送dump請求,獲取binlog並解析,發送解析后的數據給canal-client
- canal-client收到數據,將數據同步到新的數據庫
- 所以說:canal將自己偽裝成mysql的從庫,從主庫那里消費並解析binlog,通過日志來保持數據的一致性。
- 和kafka的配合方面:canal動態監控Mysql,將binlog日志解析后,把采集到的數據發送到Kafka: https://segmentfault.com/a/1190000024443393是一個很好的例子
- 通過不算復雜的配置可以直接將binlog投遞到Kafka,無需再自己寫producer程序
- 需要注意kafka和canal的版本
- 比如在采集msyql數據到es的應用中:canal負責解析MySQL的binlog日志,並將其解析后的數據封裝成特定的對象放到Kafka中; kafka通過編寫Kafka消費者,消費對應的業務數據,將消費的數據通過ES存儲API,通過創建對應的索引的,存儲到ES中,這部分負責消費存放在Kafka中的消息,當消費方拿到具體的用戶表變更消息時,將最新的用戶信息存放到ES數據倉庫中。
對於canal+kafka我的個人觀點:
canal目前主要支持了mysql,如果同時也支持將一些數據寫入到大數據生態圈的數據庫中。他主要是將自己偽裝成mysql的從庫,從主庫那里消費並解析binlog,通過日志來保持數據的一致性。這也說明我們在使用canal+kafka的過程中很可能需要搭建集群。因為canal也是分布式集群項目中同步DB數據的解決方案。相比於flume來說配置和搭建可能顯得更加復雜,不過也比flume靈活很多。如果我們同步的數據主要在關系型數據庫、es、redis、hbase、mongo等,canal有更多經驗,我覺得選擇canal更好。同樣,和flume一樣也是近實時不是完全實時(大概1-2s的誤差)。
我覺得如果兩個技術都可以采用的話,canal+flume+kafka可以提高擴展性,canal 只是模擬 MySQL 中的 從庫“騙”日志,其他數據庫源的采集可能要用到YuGong這個框架,所以數據源太多種的話可以使用flume來統一數據源,也不失canal的靈活性。