數(shù)據(jù)庫數(shù)據(jù)同步常用的5種實施方案
引言
當今時代,數(shù)據(jù)是企業(yè)運營的核心。隨著業(yè)務(wù)的擴張和用戶規(guī)模的增加,確保不同部分之間的數(shù)據(jù)一致性、實時性和可靠性變得尤為關(guān)鍵。本文將探討幾種常見的數(shù)據(jù)同步方案,涵蓋了數(shù)據(jù)庫主從同步、數(shù)據(jù)遷移同步和數(shù)據(jù)實時同步。通過深入了解各種方案的特點、優(yōu)勢和局限性,我們可以更好地選擇和定制適合特定業(yè)務(wù)場景的數(shù)據(jù)同步策略,為構(gòu)建高效、穩(wěn)定、可擴展的系統(tǒng)奠定基礎(chǔ)。
同步方案 | 描述 | 優(yōu)勢 | 局限性 |
---|---|---|---|
數(shù)據(jù)庫主從復(fù)制 | 利用數(shù)據(jù)庫自身的主從復(fù)制特性,將主數(shù)據(jù)庫的變更同步到一個或多個從數(shù)據(jù)庫。 | 實現(xiàn)簡單,可以提供相對實時的數(shù)據(jù)同步,適用于讀多寫少的場景。 | 主從之間需要穩(wěn)定的網(wǎng)絡(luò)連接,伴隨主從延遲問題。適用于MySQL、PostgreSQL等數(shù)據(jù)庫。 |
ETL工具數(shù)據(jù)遷移 | 使用專業(yè)的ETL工具,如Apache NiFi、Talend等,定期抽取源數(shù)據(jù)庫中的數(shù)據(jù),進行數(shù)據(jù)轉(zhuǎn)換,然后加載到目標數(shù)據(jù)庫中。 | 可以進行復(fù)雜的數(shù)據(jù)轉(zhuǎn)換和清洗,適用于異構(gòu)數(shù)據(jù)庫之間的同步。 | 需要配置合適的調(diào)度策略,處理好增量同步和全量同步的問題。 |
基于數(shù)據(jù)庫觸發(fā)器的同步 | 在源數(shù)據(jù)庫中設(shè)置觸發(fā)器,當數(shù)據(jù)發(fā)生變更時觸發(fā)相應(yīng)的動作,例如將變更信息記錄到一個同步表,目標數(shù)據(jù)庫定期輪詢同步表并處理變更。 | 可以實現(xiàn)較為實時的同步,適用于小規(guī)模數(shù)據(jù)。 | 需要小心設(shè)計觸發(fā)器,避免對源數(shù)據(jù)庫性能造成過大影響。 |
手工數(shù)據(jù)腳本 | 手動編寫數(shù)據(jù)腳本,將數(shù)據(jù)從一個數(shù)據(jù)庫插入到另一個數(shù)據(jù)庫中。 | 簡單直接,適用于小規(guī)模數(shù)據(jù)的同步。上線配置,數(shù)據(jù)割接等 | 異常情況處理,認為干擾因素。 |
實時數(shù)據(jù)同步方案(使用消息隊列) | 將源數(shù)據(jù)庫的變更操作發(fā)布到消息隊列,消費者訂閱消息并將變更操作同步到目標數(shù)據(jù)庫。 | 實現(xiàn)實時同步,異步處理對系統(tǒng)性能影響較小。 | 需要考慮消息隊列的可靠性和消費者的冪等性。 |
方案一、數(shù)據(jù)庫主從復(fù)制
數(shù)據(jù)庫主從復(fù)制是一種常見的數(shù)據(jù)同步方案,其中主數(shù)據(jù)庫將其變更操作傳播到一個或多個從數(shù)據(jù)庫。
MySQL數(shù)據(jù)庫主從復(fù)制的配置步驟:
確保主從數(shù)據(jù)庫版本一致:確保主數(shù)據(jù)庫和從數(shù)據(jù)庫使用相同的MySQL版本,以避免兼容性問題。配置主數(shù)據(jù)庫:在主數(shù)據(jù)庫上進行配置,打開MySQL配置文件(通常是my.cnf或my.ini),參數(shù)設(shè)置:
#設(shè)置主服務(wù)器的唯一標識 server-id = 1 #啟用二進制日志,記錄主數(shù)據(jù)庫上的所有更改 log_bin = /var/log/mysql/mysql-bin.log #指定要復(fù)制的數(shù)據(jù)庫 binlog_do_db = your_database_name
創(chuàng)建復(fù)制用戶: 在主數(shù)據(jù)庫上創(chuàng)建一個用于復(fù)制的用戶,確保該用戶具有適當?shù)臋?quán)限:
#replication_user和replication_password替換成自己的用戶名和密碼 #創(chuàng)建用于復(fù)制的用戶 create user 'replication_user'@'%' identified by 'replication_password'; #復(fù)制授權(quán) grant replication slave on *.* to 'replication_user'@'%'; #刷新權(quán)更改應(yīng)用 flush privileges;
獲取主數(shù)據(jù)庫的二進制日志位置: 在主數(shù)據(jù)庫上執(zhí)行以下命令,記錄輸出的File和Position,配置從數(shù)據(jù)庫時用到:
SHOW MASTER STATUS; mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 6470 | your_name | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
配置從數(shù)據(jù)庫:在從數(shù)據(jù)庫上進行配置,打開MySQL配置文件,參數(shù)設(shè)置:
server-id = 2
保存配置并重啟從數(shù)據(jù)庫。
連接從數(shù)據(jù)庫到主數(shù)據(jù)庫: 在從數(shù)據(jù)庫上執(zhí)行以下命令,替換master_host、master_user、master_password、master_log_file和master_log_pos為主數(shù)據(jù)庫的信息:
#配置從數(shù)據(jù)庫連接到主數(shù)據(jù)庫 change master to master_host = 'master_host', master_user = 'replication_user', master_password = 'replication_password', #從SHOW MASTER STATUS;中獲取的File值。 master_log_file = 'master_log_file', #從SHOW MASTER STATUS;中獲取的Position值 master_log_pos = master_log_pos;
啟動從數(shù)據(jù)庫的復(fù)制進程:
START SLAVE;
驗證復(fù)制狀態(tài): 在主數(shù)據(jù)庫上進行一些數(shù)據(jù)更改,并在從數(shù)據(jù)庫上執(zhí)行以下命令:
SHOW SLAVE STATUS\G
總之,數(shù)據(jù)庫主從復(fù)制方案,適用于讀多寫少的場景,讀請求可以分擔(dān)到從數(shù)據(jù)庫,減輕主數(shù)據(jù)庫負載。優(yōu)勢: 提高讀取性能,分擔(dān)主數(shù)據(jù)庫負載,提供容災(zāi)和備份機制。局限性: 存在復(fù)制延遲,可能導(dǎo)致從數(shù)據(jù)庫數(shù)據(jù)不一致;主庫單點故障可能影響整個系統(tǒng);不適用于寫入密集型應(yīng)用。
方案二、ETL工具數(shù)據(jù)遷移
ETL(Extract, Transform, Load)工具廣泛用于不同數(shù)據(jù)存儲系統(tǒng)之間的數(shù)據(jù)遷移、整合和同步,特別是在大規(guī)模數(shù)據(jù)遷移、數(shù)據(jù)倉庫建設(shè)、數(shù)據(jù)清洗和轉(zhuǎn)換等方面。常見的ETL工具有:
名稱主要特點適用場景Apache NiFi提供直觀的可視化界面,支持實時數(shù)據(jù)流,強調(diào)易用性和可管理性適用于構(gòu)建實時數(shù)據(jù)流程,易用界面,強大的管理功能Talend Open Studio強大的圖形化界面和豐富的連接器,支持多種數(shù)據(jù)源和目標,復(fù)雜的轉(zhuǎn)換和清洗功能適用于復(fù)雜數(shù)據(jù)轉(zhuǎn)換,多源多目標數(shù)據(jù)同步,大規(guī)模數(shù)據(jù)遷移Apache Camel基于企業(yè)集成模式,支持多種協(xié)議和數(shù)據(jù)格式適用于構(gòu)建靈活的數(shù)據(jù)集成解決方案,企業(yè)級數(shù)據(jù)集成和消息路由Kettle (Pentaho)提供圖形界面,支持強大的數(shù)據(jù)操作和轉(zhuǎn)換功能,整合Pentaho平臺的其他組件適用于全面數(shù)據(jù)整合,業(yè)務(wù)智能和數(shù)據(jù)分析
選擇建議:
如果注重實時數(shù)據(jù)流程和易用性,Apache NiFi 是一個好的選擇。對于復(fù)雜數(shù)據(jù)轉(zhuǎn)換和大規(guī)模遷移,Talend Open Studio 提供了豐富的功能和廣泛的連接器。如果已經(jīng)使用 Apache Camel 的其他組件,或需要高度靈活性和可定制性,可以考慮使用 Apache Camel。對于全面數(shù)據(jù)整合和業(yè)務(wù)智能,Pentaho Data Integration 可能是一個全面的解決方案。
具體使用依賴于企業(yè)的具體需求、技術(shù)棧和團隊的技能水平。
這里我們以Apache NiFi為例簡單探究其使用,說明數(shù)據(jù)遷移的過程即可。
官網(wǎng)地址:https://nifi.apache.org/
下載地址:https://archive.apache.org/dist/nifi/
安裝和部署讀者自行查閱。這里根據(jù)ETL功能說明下主要執(zhí)行流程。
單機架構(gòu):
Web Server Web服務(wù)器的作用是托管NiFi的基于HTTP的命令和控制API。
Flow Controller 流程控制器是整個操作的核心。它為擴展提供線程運行,并管理擴展何時接收到執(zhí)行資源的調(diào)度。
Extensions 有各種類型的NiFi擴展,這些在其他文檔中有描述。這里的關(guān)鍵點是擴展在JVM中運行和執(zhí)行。
FlowFile Repository FlowFile存儲庫是NiFi用于跟蹤當前在流中活動的給定FlowFile狀態(tài)的地方。存儲庫的實現(xiàn)是可插拔的。
Content Repository 內(nèi)容存儲庫是給定FlowFile的實際內(nèi)容字節(jié)所在的地方。
Provenance Repository Provenance存儲庫是存儲所有Provenance事件數(shù)據(jù)的地方。
工具定位及使用流程:
這邊就以從mysql查詢數(shù)據(jù)在寫入到mysql為例做一個簡單流程進行演示:
詳細步驟可參考(文章出處):https://blog.csdn.net/be_racle/article/details/134223354
感興趣的可以深究,這里只想說明:對大數(shù)據(jù)量處理,包括數(shù)據(jù)提取,數(shù)據(jù)加載,增量數(shù)據(jù)同步,可以借助這些工具,ETL工具提供了一些可視化的組件+配置具體的鏈接類型??梢允∪ズ芏嗳斯さ某杀?,也間接的保證了數(shù)據(jù)一致性的問題。是很好的數(shù)據(jù)處理工具。但是因為引入新的組件,在多數(shù)據(jù)源的情況下,不可避免的帶來系統(tǒng)的復(fù)雜性。
方案三、觸發(fā)器增量數(shù)據(jù)同步
如上,比如:例子中的觸發(fā)器是在tb_order表中插入新數(shù)據(jù)時觸發(fā)的,將新數(shù)據(jù)同步到tb_order_his表中(讀者可以根據(jù)需要調(diào)整觸發(fā)器的觸發(fā)時機和邏輯)
現(xiàn)狀:tb_order 共有3條記錄
tb_order_his 0條記錄
觸發(fā)器邏輯腳本:
# 創(chuàng)建觸發(fā)器 DELIMITER // CREATE TRIGGER sync_order_to_history AFTER INSERT ON tb_order FOR EACH ROW BEGIN INSERT INTO tb_order_his ( order_id, customer_id, order_date, product_id, quantity, total_price, status, shipping_address, payment_method, coupon_code, create_time, update_time ) VALUES ( NEW.order_id, NEW.customer_id, NEW.order_date, NEW.product_id, NEW.quantity, NEW.total_price, NEW.status, NEW.shipping_address, NEW.payment_method, NEW.coupon_code, NEW.create_time, NEW.update_time ); END; // DELIMITER ;
這個觸發(fā)器是在tb_order表發(fā)生插入操作之后觸發(fā)的,會將新插入的數(shù)據(jù)復(fù)制到tb_order_his表中。請注意,我假設(shè) tb_order_his 表的結(jié)構(gòu)和 tb_order 表相同。
測試觸發(fā)器的工作:
# 向tb_order插入數(shù)據(jù) INSERT INTO tb_order VALUES (4, 4, '2024-01-15 12:00:00', 104, 4, 150.25, '待支付', '567 Elm St, County', 'Credit Card', 'DISCOUNT_15', '2024-01-15 12:00:00', '2024-01-15 12:00:00'); # 查詢tb_order_his,確保數(shù)據(jù)同步成功 SELECT * FROM tb_order_his;
查看結(jié)果:同步成功:
tb_order
tb_order_his
觸發(fā)器同步的優(yōu)點:
實時性: 觸發(fā)器可以實現(xiàn)實時數(shù)據(jù)同步,當觸發(fā)事件發(fā)生時,同步操作會立即執(zhí)行,確保目標表中的數(shù)據(jù)與源表保持同步。
簡化操作: 觸發(fā)器能夠在數(shù)據(jù)庫層面自動執(zhí)行同步操作,無需在應(yīng)用程序中編寫額外的同步邏輯,簡化了開發(fā)和維護工作。確保源表和目標表之間的數(shù)據(jù)一致性。
觸發(fā)器同步的缺點:
性能影響: 觸發(fā)器的執(zhí)行會引入額外的性能開銷,特別是在大規(guī)模數(shù)據(jù)操作時。頻繁觸發(fā)的觸發(fā)器可能導(dǎo)致數(shù)據(jù)庫性能下降。
復(fù)雜性: 當觸發(fā)器邏輯復(fù)雜或有多個觸發(fā)器時,可能難以追蹤和調(diào)試觸發(fā)器的行為,特別是在維護時。
并發(fā)控制: 在高并發(fā)環(huán)境中,觸發(fā)器可能引發(fā)并發(fā)控制的問題,需要謹慎處理以確保數(shù)據(jù)一致性。
方案四、手工腳本同步(樸實無華)
這種就是常見的SQL腳本,常用于數(shù)據(jù)割接,錯誤數(shù)據(jù)修改,包括配置數(shù)據(jù),業(yè)務(wù)字段,運維手工調(diào)整異常數(shù)據(jù)等。比較簡單,只是為了文章結(jié)構(gòu)完整說明一下。舉個簡單的例子吧:
# insert into tb_target select * from tb_sourceINSERT INTO tb_order_his ( order_id, customer_id, order_date, product_id, quantity, total_price, status, shipping_address, payment_method, coupon_code, create_time, update_time)SELECT order_id, customer_id, order_date, product_id, quantity, total_price, status, shipping_address, payment_method, coupon_code, create_time, update_timeFROM tb_order;
比較簡單,沒什么好總結(jié)的。
方案五、實時數(shù)據(jù)同步方案(使用消息隊列)
這種方案主要是:將 MySQL 數(shù)據(jù)變更事件捕獲并通過消息隊列傳遞給下游數(shù)據(jù)源。比如:從Mysql同步數(shù)據(jù)到ClickHouse,一種常見的方法是使用Debezium作為MySQL CDC(Change Data Capture)工具,結(jié)合Kafka作為消息隊列。大致的步驟:
配置 MySQL 數(shù)據(jù)庫連接信息:
# MySQL 連接配置 database.hostname=mysql-host database.port=3306 database.user=mysql-user database.password=mysql-password # Debezium 配置 connector.class=io.debezium.connector.mysql.MySqlConnector tasks.max=1 database.server.id=1 database.server.name=my-app-connector database.whitelist=mydatabase
啟動 Debezium 連接器:
通過命令行或配置文件啟動 Debezium 連接器,例如:
debezium-connector-mysql my-connector.properties
創(chuàng)建 Kafka-topic:
Debezium將變更事件發(fā)送到 Kafka 主題,確保 Kafka 主題已經(jīng)創(chuàng)建:
kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic my-topic
Java 偽代碼示例 - 消費 Kafka 主題并將數(shù)據(jù)寫入 ClickHouse:
import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.Collections; import java.util.Properties; public class ClickHouseDataConsumer { private static final String KAFKA_BOOTSTRAP_SERVERS = "localhost:9092"; private static final String KAFKA_TOPIC = "my-topic"; private static final String CLICKHOUSE_URL = "clickhouse-url"; private static final String CLICKHOUSE_USER = "clickhouse-user"; private static final String CLICKHOUSE_PASSWORD = "clickhouse-password"; public static void main(String[] args) { Properties properties = new Properties(); properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_BOOTSTRAP_SERVERS); properties.put(ConsumerConfig.GROUP_ID_CONFIG, "clickhouse-consumer-group"); properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); try (Consumer<String, String> consumer = new KafkaConsumer<>(properties)) { consumer.subscribe(Collections.singletonList(KAFKA_TOPIC)); while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); records.forEach(record -> processKafkaMessage(record.value())); } } catch (Exception e) { e.printStackTrace(); } } private static void processKafkaMessage(String message) { // 解析 Kafka 消息,獲取變更數(shù)據(jù) // 將數(shù)據(jù)寫入 ClickHouse writeToClickHouse(message); } private static void writeToClickHouse(String message) { // 實現(xiàn)將數(shù)據(jù)寫入 ClickHouse 的邏輯 } }
使用 Kafka 實時同步 MySQL 具有一些優(yōu)勢和缺點:
優(yōu)勢:
實時性高: Kafka 是一個高吞吐、低延遲的消息隊列系統(tǒng),能夠提供近實時的數(shù)據(jù)同步,使得應(yīng)用能夠快速獲取最新的數(shù)據(jù)變更。
消息持久化: Kafka 具有消息持久化的特性,能夠保證即使消費者離線一段時間,仍然可以獲取之前未處理的消息,確保數(shù)據(jù)不丟失。
缺點:
一致性保證: Kafka 保證了分區(qū)內(nèi)的消息順序性,但在整個集群范圍內(nèi)的消息順序性較難保證。在某些場景下,可能需要額外的手段來保證全局的一致性。
對于小規(guī)模的應(yīng)用,引入 Kafka 可能顯得過于笨重,使用輕量級的解決方案可能更為合適。
總結(jié)
到此這篇關(guān)于數(shù)據(jù)庫數(shù)據(jù)同步常用的5種實施方案的文章就介紹到這了,更多相關(guān)數(shù)據(jù)庫同步方案內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ubuntu14.04LTS安裝nginx+mariaDB+php7+YAF的方法
這篇文章主要介紹了ubuntu14.04LTS安裝nginx+mariaDB+php7+YAF的方法,詳細講述了ubuntu14.04LTS環(huán)境下nginx+mariaDB+php7+YAF的安裝方法與相關(guān)注意事項,需要的朋友可以參考下2016-05-05解決FileZilla_Server:425 Can''t open data connection 問題詳解
在騰訊云服務(wù)器上安裝FileZilla Server時出現(xiàn)425 Can't open data connection客戶端無法獲取目錄列表的問題,下面就是解決這個問題的方法2018-10-10win10遇到服務(wù)器啟動失敗 80端口被占用如何解決
這篇文章主要為大家詳細介紹了win10遇到服務(wù)器啟動失敗,80端口被占用的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03服務(wù)器常用磁盤陣列RAID原理、種類及性能優(yōu)缺點對比
這篇文章主要介紹了磁盤陣列RAID原理、種類及性能優(yōu)缺點對比,根據(jù)硬件與硬盤數(shù)量選擇適合自己的磁盤陣列很重要,需要的朋友可以參考下2018-05-05