当今时代,数据是企业运营的核心。随着业务的扩张和用户规模的增加,确保不同部分之间的数据一致性、实时性和可靠性变得尤为关键。本文将探讨几种常见的数据同步方案,涵盖了数据库主从同步、数据迁移同步和数据实时同步。通过深入了解各种方案的特点、优势和局限性,我们可以更好地选择和定制适合特定业务场景的数据同步策略,为构建高效、稳定、可扩展的系统奠定基础。
同步方案 | 描述 | 优势 | 局限性 |
---|---|---|---|
数据库主从复制 | 利用数据库自身的主从复制特性,将主数据库的变更同步到一个或多个从数据库。 | 实现简单,可以提供相对实时的数据同步,适用于读多写少的场景。 | 主从之间需要稳定的网络连接,伴随主从延迟问题。适用于MySQL、PostgreSQL等数据库。 |
ETL工具数据迁移 | 使用专业的ETL工具,如Apache NiFi、Talend等,定期抽取源数据库中的数据,进行数据转换,然后加载到目标数据库中。 | 可以进行复杂的数据转换和清洗,适用于异构数据库之间的同步。 | 需要配置合适的调度策略,处理好增量同步和全量同步的问题。 |
基于数据库触发器的同步 | 在源数据库中设置触发器,当数据发生变更时触发相应的动作,例如将变更信息记录到一个同步表,目标数据库定期轮询同步表并处理变更。 | 可以实现较为实时的同步,适用于小规模数据。 | 需要小心设计触发器,避免对源数据库性能造成过大影响。 |
手工数据脚本 | 手动编写数据脚本,将数据从一个数据库插入到另一个数据库中。 | 简单直接,适用于小规模数据的同步。上线配置,数据割接等 | 异常情况处理,认为干扰因素。 |
实时数据同步方案(使用消息队列) | 将源数据库的变更操作发布到消息队列,消费者订阅消息并将变更操作同步到目标数据库。 | 实现实时同步,异步处理对系统性能影响较小。 | 需要考虑消息队列的可靠性和消费者的幂等性。 |
主要内容如下:
数据库主从复制是一种常见的数据同步方案,其中主数据库将其变更操作传播到一个或多个从数据库。
MySQL数据库主从复制的配置步骤:
#设置主服务器的唯一标识
server-id = 1
#启用二进制日志,记录主数据库上的所有更改
log_bin = /var/log/mysql/mysql-bin.log
#指定要复制的数据库
binlog_do_db = your_database_name
#replication_user和replication_password替换成自己的用户名和密码
#创建用于复制的用户
create user 'replication_user'@'%' identified by 'replication_password';
#复制授权
grant replication slave on *.* to 'replication_user'@'%';
#刷新权更改应用
flush privileges;
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)
server-id = 2
保存配置并重启从数据库。
#配置从数据库连接到主数据库
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;
START SLAVE;
SHOW SLAVE STATUS\G
总之,数据库主从复制方案,适用于读多写少的场景,读请求可以分担到从数据库,减轻主数据库负载。优势: 提高读取性能,分担主数据库负载,提供容灾和备份机制。局限性: 存在复制延迟,可能导致从数据库数据不一致;主库单点故障可能影响整个系统;不适用于写入密集型应用。
ETL(Extract, Transform, Load)工具广泛用于不同数据存储系统之间的数据迁移、整合和同步,特别是在大规模数据迁移、数据仓库建设、数据清洗和转换等方面。常见的ETL工具有:
名称 | 主要特点 | 适用场景 |
---|---|---|
Apache NiFi | 提供直观的可视化界面,支持实时数据流,强调易用性和可管理性 | 适用于构建实时数据流程,易用界面,强大的管理功能 |
Talend Open Studio | 强大的图形化界面和丰富的连接器,支持多种数据源和目标,复杂的转换和清洗功能 | 适用于复杂数据转换,多源多目标数据同步,大规模数据迁移 |
Apache Camel | 基于企业集成模式,支持多种协议和数据格式 | 适用于构建灵活的数据集成解决方案,企业级数据集成和消息路由 |
Kettle (Pentaho) | 提供图形界面,支持强大的数据操作和转换功能,整合Pentaho平台的其他组件 | 适用于全面数据整合,业务智能和数据分析 |
选择建议:
具体使用依赖于企业的具体需求、技术栈和团队的技能水平。
这里我们以Apache NiFi为例简单探究其使用,说明数据迁移的过程即可。
下载地址:https://archive.apache.org/dist/nifi/
安装和部署读者自行查阅。这里根据ETL功能说明下主要执行流程。
单机架构:
Web Server Web服务器的作用是托管NiFi的基于HTTP的命令和控制API。
Flow Controller 流程控制器是整个操作的核心。它为扩展提供线程运行,并管理扩展何时接收到执行资源的调度。
Extensions 有各种类型的NiFi扩展,这些在其他文档中有描述。这里的关键点是扩展在JVM中运行和执行。
FlowFile Repository FlowFile存储库是NiFi用于跟踪当前在流中活动的给定FlowFile状态的地方。存储库的实现是可插拔的。
Content Repository 内容存储库是给定FlowFile的实际内容字节所在的地方。
Provenance Repository Provenance存储库是存储所有Provenance事件数据的地方。
工具定位及使用流程:
这边就以从mysql查询数据在写入到mysql为例做一个简单流程进行演示:
详细步骤可参考(文章出处):https://blog.csdn.net/be_racle/article/details/134223354
感兴趣的可以深究,这里只想说明:对大数据量处理,包括数据提取,数据加载,增量数据同步,可以借助这些工具,ETL工具提供了一些可视化的组件+配置具体的链接类型。可以省去很多人工的成本,也间接的保证了数据一致性的问题。是很好的数据处理工具。但是因为引入新的组件,在多数据源的情况下,不可避免的带来系统的复杂性。
如上,比如:例子中的触发器是在tb_order表中插入新数据时触发的,将新数据同步到tb_order_his表中(读者可以根据需要调整触发器的触发时机和逻辑)
现状:tb_order 共有3条记录
tb_order_his 0条记录
触发器逻辑脚本:
# 创建触发器
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 ;
这个触发器是在tb_order表发生插入操作之后触发的,会将新插入的数据复制到tb_order_his表中。请注意,我假设 tb_order_his 表的结构和 tb_order 表相同。
测试触发器的工作:
# 向tb_order插入数据
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,确保数据同步成功
SELECT * FROM tb_order_his;
查看结果:同步成功:
tb_order
tb_order_his
触发器同步的优点:
实时性: 触发器可以实现实时数据同步,当触发事件发生时,同步操作会立即执行,确保目标表中的数据与源表保持同步。
简化操作: 触发器能够在数据库层面自动执行同步操作,无需在应用程序中编写额外的同步逻辑,简化了开发和维护工作。确保源表和目标表之间的数据一致性。
触发器同步的缺点:
性能影响: 触发器的执行会引入额外的性能开销,特别是在大规模数据操作时。频繁触发的触发器可能导致数据库性能下降。
复杂性: 当触发器逻辑复杂或有多个触发器时,可能难以追踪和调试触发器的行为,特别是在维护时。
并发控制: 在高并发环境中,触发器可能引发并发控制的问题,需要谨慎处理以确保数据一致性。
这种就是常见的SQL脚本,常用于数据割接,错误数据修改,包括配置数据,业务字段,运维手工调整异常数据等。比较简单,只是为了文章结构完整说明一下。举个简单的例子吧:
# insert into tb_target select * from tb_source
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
)
SELECT
order_id, customer_id, order_date, product_id, quantity,
total_price, status, shipping_address, payment_method,
coupon_code, create_time, update_time
FROM tb_order;
比较简单,没什么好总结的。
这种方案主要是:将 MySQL 数据变更事件捕获并通过消息队列传递给下游数据源。比如:从Mysql同步数据到ClickHouse,一种常见的方法是使用Debezium作为MySQL CDC(Change Data Capture)工具,结合Kafka作为消息队列。大致的步骤:
# 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-connector-mysql my-connector.properties
Debezium将变更事件发送到 Kafka 主题,确保 Kafka 主题已经创建:
kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic my-topic
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 消息,获取变更数据
// 将数据写入 ClickHouse
writeToClickHouse(message);
}
private static void writeToClickHouse(String message) {
// 实现将数据写入 ClickHouse 的逻辑
}
}
使用 Kafka 实时同步 MySQL 具有一些优势和缺点:
优势:
实时性高: Kafka 是一个高吞吐、低延迟的消息队列系统,能够提供近实时的数据同步,使得应用能够快速获取最新的数据变更。
消息持久化: Kafka 具有消息持久化的特性,能够保证即使消费者离线一段时间,仍然可以获取之前未处理的消息,确保数据不丢失。
缺点:
一致性保证: Kafka 保证了分区内的消息顺序性,但在整个集群范围内的消息顺序性较难保证。在某些场景下,可能需要额外的手段来保证全局的一致性。
对于小规模的应用,引入 Kafka 可能显得过于笨重,使用轻量级的解决方案可能更为合适。
文章浏览阅读3k次,点赞3次,收藏13次。root@server ~]# vim /etc/named.rfc1912.zones #添加如下内容,也可直接更改模板。[root@server ~]# vim /etc/named.conf #打开主配置文件,将如下两处地方修改为。注意:ip地址必须反向书写,这里文件名需要和反向解析数据文件名相同。新建或者拷贝一份进行修改。nslookup命令。_dns反向解析
文章浏览阅读2.5w次,点赞16次,收藏103次。这个函数TIM_SetCompare1,这个函数有四个,分别是TIM_SetCompare1,TIM_SetCompare2,TIM_SetCompare3,TIM_SetCompare4。位于CH1那一行的GPIO口使用TIM_SetCompare1这个函数,位于CH2那一行的GPIO口使用TIM_SetCompare2这个函数。使用stm32f103的除了tim6和tim7没有PWM..._tim_setcompare1
文章浏览阅读950次,点赞33次,收藏19次。多线程_进程和线程,并发与并行,线程优先级,守护线程,实现线程的四种方式,线程周期;线程同步,线程中的锁,Lock类,死锁,生产者和消费者案例
文章浏览阅读2.9k次。ifort 编译器的安装ifort 编译器可以在 intel 官网上下载。打开https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/fortran-compiler.html#gs.7iqrsm点击网页中下方处的 Download, 选择 Intel Fortran Compiler Classic and Intel Fortran Compiler(Beta) 下方对应的版本。我选择的是 l_在linux系统的用户目录下安装ifort和mkl库并配置
文章浏览阅读689次,点赞7次,收藏8次。些项目时需要一个生成图片的方法,我在网上找到比较方便且适合我去设置一些样式的生成方式之一就是使用Freemarker,在对应位置上先写好一个html格式的ftl文件,在对应位置用${参数名}填写上。还记得当时为了解决图片大小设置不上,搜索了好久资料,不记得是在哪看到的需要在里面使用width与height直接设置,而我当时用style去设置,怎么都不对。找不到,自己测试链接,准备将所有含有中文的图片链接复制一份,在服务器上存储一份不带中文的文件。突然发现就算无中文,有的链接也是打不开的。_ftl格式pdf的样式调整
文章浏览阅读1.5k次,点赞6次,收藏12次。拉取librealsense。_opt/ros/noetic/lib/nodelet/nodelet: symbol lookup error: /home/admin07/reals
文章浏览阅读3.4k次,点赞3次,收藏29次。一.单选题二.填空题三.判断题一.单选题静态链接是在( )进行的。A、编译某段程序时B、装入某段程序时C、紧凑时D、装入程序之前Pentium处理器(32位)最大可寻址的虚拟存储器地址空间为( )。A、由内存的容量而定B、4GC、2GD、1G分页系统中,主存分配的单位是( )。A、字节B、物理块C、作业D、段在段页式存储管理中,当执行一段程序时,至少访问()次内存。A、1B、2C、3D、4在分段管理中,( )。A、以段为单位分配,每._系统抖动现象的发生由什么引起的
文章浏览阅读2.4k次。在实际的工作生产中,零件的加工制造一般都需要二维工程图来辅助设计。UG NX 的工程图主要是为了满足二维出图需要。在绘制工程图时,需要先确定所绘制图形要表达的内容,然后根据需要并按照视图的选择原则,绘制工程图的主视图、其他视图以及某些特殊视图,最后标注图形的尺寸、技术说明等信息,即可完成工程图的绘制。1.视图选择原则工程图合理的表达方案要综合运用各种表达方法,清晰完整地表达出零件的结构形状,并便于看图。确定工程图表达方案的一般步骤如下:口分析零件结构形状由于零件的结构形状以及加工位置或工作位置的不._ug-nx工程图
文章浏览阅读920次,点赞29次,收藏18次。原文《智能制造数字化工厂智慧供应链大数据解决方案》PPT格式主要从智能制造数字化工厂智慧供应链大数据解决方案框架图、销量预测+S&OP大数据解决方案、计划统筹大数据解决方案、订单履约大数据解决方案、库存周转大数据解决方案、采购及供应商管理大数据模块、智慧工厂大数据解决方案、设备管理大数据解决方案、质量管理大数据解决方案、仓储物流与网络优化大数据解决方案、供应链决策分析大数据解决方案进行建设。适用于售前项目汇报、项目规划、领导汇报。
文章浏览阅读2w次,点赞38次,收藏102次。在服务器端,socket()返回的套接字用于监听(listen)和接受(accept)客户端的连接请求。这个套接字不能用于与客户端之间发送和接收数据。 accept()接受一个客户端的连接请求,并返回一个新的套接字。所谓“新的”就是说这个套接字与socket()返回的用于监听和接受客户端的连接请求的套接字不是同一个套接字。与本次接受的客户端的通信是通过在这个新的套接字上发送和接收数_当在函数 'main' 中调用 'open_socket_accept'时.line: 8. connection request fa
文章浏览阅读4.3k次。对象销毁对象销毁的标准语法Close和Stop何时销毁对象销毁对象时清除字段对象销毁的标准语法Framework在销毁对象的逻辑方面遵循一套规则,这些规则并不限用于.NET Framework或C#语言;这些规则的目的是定义一套便于使用的协议。这些协议如下:一旦销毁,对象不可恢复。对象不能被再次激活,调用对象的方法或者属性抛出ObjectDisposedException异常重复地调用对象的Disposal方法会导致错误如果一个可销毁对象x 包含或包装或处理另外一个可销毁对象y,那么x的Disp_c# 销毁对象及其所有引用
文章浏览阅读1.1w次。这是记录,在中项、高项过程中的错题笔记;https://www.zenwu.site/post/2b6d.html1. 信息系统的规划工具在制订计划时,可以利用PERT图和甘特图;访谈时,可以应用各种调查表和调查提纲;在确定各部门、各层管理人员的需求,梳理流程时,可以采用会谈和正式会议的方法。为把企业组织结构与企业过程联系起来,说明每个过程与组织的联系,指出过程决策人,可以采用建立过程/组织(Process/Organization,P/O)矩阵的方法。例如,一个简单的P/O矩阵示例,其中._大型设备可靠性测试可否拆解为几个部分进行测试