如何使用 Kafka、MongoDB 和 Maxwell’s Daemon 构建 SQL 数据库的审计系统
本文要點
? ? ?審計日志系統有很多應用場景,而不僅僅是存儲用于審計目的的數據。除了合規性和安全性的目的之外,它還能夠被市場營銷團隊使用,以便于鎖定目標用戶,也可以用來生成重要的告警。
? ? ?數據庫內置的審計日志功能可能并不夠用,要處理所有的用戶場景,它肯定不是理想的方式。
? ? ?目前,有很多的開源工具,如Maxwell’s Daemons、Debezium,它們能夠以最少的基礎設施和時間需求支持這些需求。
? ? Maxwell’s daemons 能夠讀取 SQL bin 日志并發送事件到各種生產者,比如Kafka、Amazon Kinesis、SQS、Rabbit MQ等。
SQL 數據庫生成的 bin 日志必須是基于 ROW 的格式,這樣才能使整個環境運行起來。
假設你正在使用關系型數據來維護事務性數據并且你需要存儲某些數據的審計跟蹤信息,而這些數據本身是以表的形式存在的。如果你像大多數開發人員那樣,那么最終所采用的方案可能如下所示:
1. 使用數據庫的審計日志功能
大多數數據庫都提供了插件來支持審計日志。這些插件可以很容易地安裝和配置,以便于記錄數據。但是,這種方式存在如下的問題:
完整的審計日志插件一般只有企業級版本才提供。社區版可能會缺失這樣的插件。以 MySQL 為例,審計日志插件只有企業版中才能使用。值得一提的是,MySQL 社區版的用戶依然可以安裝來自 MariaDB 或 Percona 的其他審計日志組件以繞過這個限制。
數據庫級別的審計日志會導致數據庫服務器 10-20%的額外負載,正如該文和該文所討論的。通常,對于高負載的系統,我們可能想要僅對較慢的查詢啟用審計日志,而不是針對所有的查詢。
審計日志會寫入到日志文件中,數據不易于搜索。為了實現數據分析和審計的目的,我們可能想要審計數據能夠遵循可搜索的格式。
大量的審計歸檔文件會消耗非常重要的數據庫存儲,因為它們存儲在與數據庫相同的服務器上。
2. 使用應用程序來負責審計日志
要實現這一點,你可以采用如下的方案之一:
a.在更新現有的數據之前,復制現有的數據到另外一個表中,然后再更新當前表中的數據。
b.為數據添加一個版本號,然后每次更新都會插入一條已遞增版本號的數據。
c.寫入到兩個數據庫表中,其中一張表包含最新的數據,另外一張表包含審計跟蹤信息。
作為設計可擴展系統的一項原則,我們必須要避免多次寫入相同的數據,因為這不僅會降低系統的性能,還會引發各種數據不同步的問題。
那么企業為什么需要審計數據呢?
在開始介紹審計日志系統的架構之前,我們首先看一下各種組織對審計日志系統的一些需求。
合規性和審計:審計人員需要從他們的角度出發,以有意義和相關的方式獲取數據。數據庫審計日志適用于 DBA 團隊,但并不適合審計人員。
對于任何大型軟件來說,一個最基本的需求就是能夠在遇到安全漏洞的時候生成重要的告警。審計日志可以用來實現這一點。
你必須回答各種問題,比如誰訪問了數據,數據在此之前的狀態是什么,在更新的時候都修改了哪些內容以及內部用戶是否濫用了權限等等。
還有很重要的一點需要注意,因為審計跟蹤信息能夠有助于識別滲透者,這能夠強化對“內部人員”的威懾力。人們如果知道自己的行為會被審查,那么他們就不太可能會訪問未經授權的數據庫或篡改特定的數據。
所有的行業,從金融和能源到餐飲服務和公共項目,都需要分析數據訪問情況,并定期向各種政府機構提交詳細的報告。根據“健康保險流通與責任法案(Health Insurance Portability and Accountability Act,HIPAA)”,該法案要求醫療服務供應商提供所有接觸他們數據記錄的每個人的審計跟蹤數據,這個要求要到數據行和記錄級別。新的歐盟通用數據保護條例(European Union General Data Protection Regulation,GDPR)也有類似的需求。薩班斯-奧克斯利法案(Sarbanes-Oxley Act,SOX)對公眾公司提出了廣泛的會計法規。這些組織需要定期分析數據訪問情況并生成詳細的報告。
在本文中,我將會使用像 Maxwell’s Daemon 和 Kafka 這樣的技術提供一個可擴展的方案,以管理審計跟蹤數據。
問題陳述
構建一個獨立于應用程序和數據模型的審計系統。該系統必須要具備可擴展性并且經濟劃算。
架構
重要提示:本系統只適用于使用 MySQL 數據庫的情況,并且使用基于 ROW 的binlog日志格式。
在我們討論解決方案的細節之前,我們先快速看一下本文中所討論的每項技術。
Maxwell’s Daemon
Maxwell’s Daemon(MD)是一個來自Zendesk的開源項目,它會讀取 MySQL bin 日志并將 ROW 更新以 JSON 的格式寫入到 Kafka、Kinesis 或其他流平臺上。Maxwell 的運維開銷非常低,除了 MySQL 和一些寫入數據的地方之外,就沒有其他的需求了,如項目網站所述。簡而言之,MD 是一個數據變化捕獲(Change-Data-Capture,CDC)的工具。
市場上有很多可用的 CDC 變種,比如 Redhat 的 Debezium、Netflix 的 DBLog 以及 LinkedIn 的 Brooklyn。我們這里的環境可以采用這些工具中的任意一個來實現。但是,Netflix 的 DBLog 以及 LinkedIn 的 Brooklyn 是為了滿足不足的使用場景而開發的,正如上述的鏈接中所闡述的那樣。不過,Debezium 與 MD 非常類似,可以用來取代我們的架構中的 MD。關于該選擇 MD 還是 Debezium,我簡要列出了幾件需要考慮的事情。
? ? ? ? Debezium 只能寫入數據到 Kafka 中,至少這是它支持的主要的生產者。而 MD 支持各種生產者,包括 Kafka。MD 支持的生產者是 afka, Kinesis、Google Cloud Pub/Sub、SQS、Rabbit MQ和 Redis。
? ? ? ? MD 提供了編寫自己的生產者并對其進行配置的方案。詳情可參考該文檔。
? ? ? ?Debezium 的優勢在于它可以從多個源讀取變化數據,比如MySQL、MongoDB、PostgreSQL、SQL Server、Cassandra、DB2和Oracle。在添加新的數據源方面,他們非?;钴S。而 MD 目前只支持 MySQL 數據源。
Kafka
Apache Kafka是一個開源的分布式事件流平臺,能夠用于高性能的數據管道、流分析、數據集成和任務關鍵型的應用。
MongoDB
MongoDB是一個通用的、基于文檔的分布式數據庫,它是為現代應用開發人員和云時代所構建的。我們使用 MongoDB 只是為了進行闡述,你可以選擇其他的方案,比如S3,也可以選擇其他的時序數據庫如InfluxDB或Cassandra。
下圖展示了審計跟蹤方案的數據流圖。
圖 1 數據流圖
在審計跟蹤管理系統中,要涉及到如下幾個步驟。
應用程序執行數據庫寫入、更新或刪除操作。
SQL 數據庫將會以 ROW 格式為這些操作生成 bin 日志。這是 SQL 數據庫相關的配置。
Maxwell’s Daemon 輪詢 SQL bin 日志,讀取新的條目并將其寫入到 Kafka 主題中。
消費者應用輪詢 Kafka 主題以讀取數據并進行處理。
消費者將處理后的數據寫入到新的數據存儲中。
環境搭建
為了實現簡便的環境搭建,我們在所有可能的地方都盡可能使用 Docker 容器。如果你的機器還沒有安裝 docker 的話,那么可以考慮安裝Docker Desktop。
MySQL 數據庫
1.在本地運行 mysql 服務器。如下的命令將會在 3307 端口啟動一個 mysql 容器。
docker run -p 3307:3306 -p 33061:33060 --name=mysql83 -d mysql/mysql-server:latest2.如果這是全新安裝的話,我們并不知道 root 密碼,運行如下的命令在控制臺打印密碼出來。
docker logs mysql83 2>&1 | grep GENERATED3.如果需要的話,登錄容器并更改密碼。
docker exec -it mysql83 mysql -uroot -p alter uer 'root'@'localhost' IDENTIFIED BY 'abcd1234'4.處于安全的原因,mysql docker 容器默認不允許從外部應用進行連接。我們需要運行如下的命令改變這一點。
update mysql.user set host = '%' where user='root';5.從 mysql 提示窗口退出并重啟 docker 容器。
docker container restart mysql836.重新登錄 mysql 客戶端并運行如下的命令為 maxwell’s daemon 創建用戶。關于該步驟的詳細信息,請參考Maxwell’s Daemon的快速指南。
Kafka 代理搭建 Kafka 是一項非常簡單直接的任務。從該鏈接下載 Kafka。
運行如下的命令:
提取 Kafka
tar -xzf kafka_2.13-2.6.0.tgzcd kafka_2.13-2.6.0運行 Zookeeper,這是目前使用 Kafka 所需要的
bin/zookeeper-server-start.sh config/zookeeper.properties在一個單獨的終端啟動 Kafka
bin/kafka-server-start.sh config/server.properties在一個單獨的終端創建主題
bin/kafka-topics.sh --create --topic maxwell-events --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1上述的命令會啟動一個 Kafka 代理并在其中創建一個名為“maxwell-events”的主題。
要推送消息到該 Kafka 主題,我們可以在新的終端運行如下的命令
bin/kafka-console-producer.sh --topic maxwell-events --broker-list localhost:9092上述的命令會給我們顯示一個提示,從中可以輸入消息內容,然后點擊回車鍵,以便于發送消息到 Kafka 中。
消費來自 Kafka 主題的消息
bin/kafka-console-producer.sh --topic quickstart-events --broker-list localhost:9092Maxwell’s Daemon
通過該地址下載 maxwell’s daemon。
將其解壓并運行如下的命令。
bin/maxwell --user=maxwell --password=pmaxwell --host=localhost --port=3307這樣的話,我們就建立好了 Maxwell 來監控前面所搭建的數據庫的 bin 日志。當然,我們也可以只監控幾個數據庫或幾個表。關于這方面的更多信息,請參考Maxwell’s Daemon配置文檔。
測試環境
要測試搭建的環境是否正確的話,我們可以連接 MySQL,并在一張表中插入一些數據。
現在,在另外一個終端中,運行如下的命令:
bin/kafka-console-consumer.sh --topic maxwell-events? --from-beginning --bootstrap-server localhost:9092在終端中,你應該能夠看到如下所示的內容:
{"database":"maxwelltest","table":"Persons","type":"insert","ts":1602904030,"xid":17358,"commit":true,"data": {"PersonId":1,"LastName":"Erichsen","FirstName":"Tom","City":"Stavanger"}}正如我們所看到的,Maxwell’s Daemon 捕獲到了數據庫插入事件并寫入一個 JSON 字符串到 Kafka 主題中,其中包含了事件的詳情。
搭建 MongoDB
要在本地運行 MongoDB,可以運行如下的命令:
docker run --name mongolocal -p 27017:27017 mongo:latestKafka 消費者
Kafka-consumer 的代碼可以通過GitHub項目獲取。下載源碼并參考 README 文檔以了解如何運行。
最終測試
最后,我們的環境搭建終于完成了。登錄 MySQL 數據庫并運行任意的插入、刪除或更新命令。如果環境搭建正確的話,將會在 mongodb auditlog 數據庫中看到相應的條目。我們可以愉快地開始進行審計了!
結論
在本文中所描述的系統在實際部署中能夠很好地運行,為我們提供了一個用戶數據之外的額外數據源,但是在采用這種架構之前,有些權衡你必須要注意。
基礎設施成本:要運行這種環境,需要額外的基礎設施。數據要經歷網絡上的多次跳轉,從數據庫到 Kafka,再到另外一個數據庫,后面可能還會到一個備份中。這會增加基礎設施的成本。
因為數據要經歷多次跳轉,審計日志無法以實時的形式進行維護。它可能會延遲幾秒到幾分鐘。我們可能會反問“誰能需要實時的審計日志呢?”但是,如果你計劃使用這種數據進行實時監控的話,必須要考慮到這一點。
在這個架構中,我們捕獲了數據的變化,而不是誰改變了數據。如果你還關心哪個數據庫用戶改變了數據的話,那么這種設計就不能提供直接的支持了。
在強調完這種架構的一些權衡之后,我想重申一下這種環境的收益,它的主要好處在于:
這種環境減少了數據庫在審計日志方面的性能損耗,并且滿足傳統數據源在市場營銷和告警方面的需要。
易于搭建,并且比較健壯:環境中任意組件的任意問題都不會造成數據的丟失。例如,如果 MD 出現故障的話,數據依然會保存在 bin 日志文件中,當 daemon 下次運行的時候,能夠從上次處理的地方繼續讀取。如果 Kafka 代理出現故障的話,MD 能夠探測到并且會停止從 bin 日志中讀取數據。如果 Kafka 消費者崩潰的話,數據會依然保留在 Kafka 代理中。所以,在最糟糕的情況下,審計日志會延遲但是不會出現數據丟失。
環境搭建過程非常簡單,并不需要耗費太多的開發精力。
原文地址:https://www.infoq.cn/article/KuhboGV2zpeI00k1Rxwu
作者簡介
Vishal Sinha 是一位充滿激情的技術專家,對分布式計算和大型可擴展系統有著專業的知識和濃厚的興趣。目前,他在一家領先的印度獨角獸公司擔任技術總監。在 16 年的軟件行業生涯中,他曾在多家跨國公司和創業公司工作,開發過各種大規模的系統,并領導過一個由眾多軟件工程師組成的團隊。他喜歡解決復雜的問題和嘗試新技術。
想知道更多?掃描下面的二維碼關注我后臺回復"技術",加入技術群后臺回復“k8s”,可領取k8s資料【精彩推薦】原創|OpenAPI標準規范
中臺不是萬能藥,關于中臺的思考和嘗試
ClickHouse到底是什么?為什么如此牛逼!
原來ElasticSearch還可以這么理解
面試官:InnoDB中一棵B+樹可以存放多少行數據?
微服務下如何解耦?對于已經緊耦合下如何重構?
如何構建一套高性能、高可用、低成本的視頻處理系統?
架構之道:分離業務邏輯和技術細節
星巴克不使用兩階段提交
點個贊+在看,少個 bug?????
總結
以上是生活随笔為你收集整理的如何使用 Kafka、MongoDB 和 Maxwell’s Daemon 构建 SQL 数据库的审计系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线程、进程、多线程、多进程和多任务有啥关
- 下一篇: 淘宝技术架构从1.0到4.0的演变