SymmetricDS 是一个基于 Java 的数据库同步框架。本文并不打算带你熟悉 SymmetricDS 的实现原理,只是从安装与配置入手,让你感觉一下 SymmetricDS 运行效果。若是你的系统中是干净(空白)的,那么你须要作的事情就比较多了。本文但愿尽量全面且细致地讲解配置过程,而不至于你按照本文的教程安装,出现没法使用的状况。若是真的有这样的状况产生,你能够在下面进行留言。如下是我在安装环境时配置的一些记录,但愿于你有益。java
著做权归做者全部。
商业转载请联系做者得到受权,非商业转载请注明出处。
本文做者:Q-WHai
发表日期: 2016年7月12日
本文连接:http://blog.csdn.net/lemon_tree12138/article/details/51891291
来源:CSDN
更多内容:分类 >> 数据库
node
这里须要你的 JDK 版本为 jdk1.6 以上,关于 JDK 的安装和配置这里就很少说了,网上一大堆。mysql
此处为测试环境,故设置了关闭防火墙linux
$ sudo service iptables stop
$ sudo chkconfig iptables off # 设置防火墙不随系统启动,这一条你能够选择性添加
关于 SSH 的免密码登陆在这里不是很重要,只是本人在下发文件的时候用到了。你能够选择性配置。
配置过程可参见本人另外一篇博客《Hadoop 2.2.0 集群搭建》spring
这里为了不使用 root 账户,因此建立了新的数据库操做用户:symmetric
首先使用 root 账户登陆 MySQL,并执行以下 SQL 语句:sql
mysql> INSERT INTO mysql.user(HOST,USER,PASSWORD) values("localhost","symmetric",password("123456"));
mysql> FLUSH privileges;
上面的 SQL 语句可让你有一个 symmetric 的MySQL 用户,但是这个用户在不少地方都没有操做权限。这里须要修改某些操做的权限:数据库
mysql> UPDATE mysql.user SET Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',Create_priv='Y', Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',Process_priv='Y',File_priv='Y', Grant_priv='Y',References_priv='Y',Index_priv='Y',Alter_priv='Y',Show_db_priv='Y', Super_priv='Y',Create_tmp_table_priv='Y',Lock_tables_priv='Y',Execute_priv='Y',Repl_slave_priv='Y', Repl_client_priv='Y',Create_view_priv='Y',Show_view_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y', Create_user_priv='Y',Event_priv='Y',Trigger_priv='Y' WHERE USER="symmetric" AND HOST="localhost";
mysql> FLUSH privileges;
在 Java 中,若是须要链接 MySQL 数据库,须要使用 JDBC 的数据库链接技术。在使用 JDBC 的时候比较容易忽略的就是链接驱动的配置了。
这一点在 Windows 下还好,不过要在 Linux 下使用 JDBC 就须要配置 MySQL 的驱动程序了。
1. 首先上传 MySQL 的驱动 jar 包 mysql-connector-java-5.1.6-bin.jar 到 Linux 的合适位置
2. 配置环境变量vim
$ sudo vim /etc/profile
在文件末尾处添加以下内容:ruby
export CLASSPATH=${CLASSPATH}:/home/hadoop/libs/mysql-connector-java-5.1.6-bin.jar
设置配置当即生效bash
$ source /etc/profile
首先上传 symmetric-server-3.7.34 到 master 节点自定义的一个目录下,再重命名移动到用户根目录。
$ mv symmetric-server-3.7.34/ ~/symmetric
而后再下发此文件夹:
$ scp -r ~/symmetric/ slave:~/symmetric/
这里的 corp 也就是个人 master 节点。
复制 symmetric 目录下的 samples/corp-000.properties 文件到 engines 目录下:
$ cp samples/corp-000.properties engines/
并修改此文件内容
$ vim engines/corp-000.properties
修改后的内容以下:
engine.name=corp-000
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://master/sample
db.user=symmetric
db.password=123456
registration.url=
sync.url=http://master:8080/sync/corp-000
group.id=corp
external.id=000
job.purge.period.time.ms=7200000
job.routing.period.time.ms=5000
job.push.period.time.ms=10000
job.pull.period.time.ms=10000
initial.load.create.first=true
这里我只保留了实际的内容,不包含注释。
这里的 store 也就是个人 slave 节点。
复制 symmetric 目录下的 samples/store-001.properties 文件到 engines 目录下:
$ cp samples/store-001.properties engines/
并修改此文件内容
$ vim engines/store-001.properties
修改后的内容以下:
engine.name=store-001
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://slave/sample
db.user=symmetric
db.password=123456
registration.url=http://master:8080/sync/corp-000
group.id=store
external.id=001
job.routing.period.time.ms=5000
job.push.period.time.ms=10000
job.pull.period.time.ms=10000
在默认的状况下,symmetric/bin 目录下的文件没有执行权限,因此这里咱们要为这些文件添加可执行权限:
$ chmod 755 bin/*
$ mysql -usymmetric -p123456
mysql> create database sample;
在 symmetric 中默认已经给出了自动化的数据建立过程,不过这种自动化的建立有一些不足的地方,那就是数据不够完整。这样就会导致在后面自动化插入数据时出现找不到数据表的状况,因此这里我比较推荐你使用下面手动建立的方式。自动化的建立方式只做为参考:
建立指令
$ ./bin/symadmin --engine corp-000 create-sym-tables
建立结果
mysql> show tables;
+-----------------------------+
| Tables_in_sample |
+-----------------------------+
| sym_channel |
| sym_conflict |
| sym_data |
| sym_data_event |
| sym_data_gap |
| sym_extension |
| sym_extract_request |
| sym_file_incoming |
| sym_file_snapshot |
| sym_file_trigger |
| sym_file_trigger_router |
| sym_grouplet |
| sym_grouplet_link |
| sym_incoming_batch |
| sym_incoming_error |
| sym_load_filter |
| sym_lock |
| sym_node |
| sym_node_channel_ctl |
| sym_node_communication |
| sym_node_group |
| sym_node_group_channel_wnd |
| sym_node_group_link |
| sym_node_host |
| sym_node_host_channel_stats |
| sym_node_host_job_stats |
| sym_node_host_stats |
| sym_node_identity |
| sym_node_security |
| sym_outgoing_batch |
| sym_parameter |
| sym_registration_redirect |
| sym_registration_request |
| sym_router |
| sym_sequence |
| sym_table_reload_request |
| sym_transform_column |
| sym_transform_table |
| sym_trigger |
| sym_trigger_hist |
| sym_trigger_router |
| sym_trigger_router_grouplet |
+-----------------------------+
42 rows in set (0.00 sec)
手动建立虽然比较繁琐,可是数据比较完整,整个过程也很顺利。
item
CREATE TABLE item( item_id INTEGER PRIMARY KEY, name VARCHAR(100) );
item_selling_price
CREATE TABLE item_selling_price( item_id INTEGER REFERENCES item(item_id), store_id VARCHAR(5), price DECIMAL(10,2), cost DECIMAL(10,2), PRIMARY KEY(item_id, store_id) );
sale_transaction
CREATE TABLE sale_transaction( tran_id INTEGER PRIMARY KEY, store_id VARCHAR(5) NOT NULL, workstation VARCHAR(3) NOT NULL, day VARCHAR(10) NOT NULL, seq INTEGER NOT NULL );
sale_return_line_item
CREATE TABLE sale_return_line_item( tran_id INTEGER PRIMARY KEY REFERENCES sale_transaction(tran_id), item_id INTEGER NOT NULL REFERENCES item(item_id), price DECIMAL(10,2) NOT NULL, quantity INTEGER NOT NULL, returned_quantity INTEGER );
因而建立了以下 4 张数据表:
mysql> show tables; +-----------------------+
| Tables_in_sample | +-----------------------+
| item |
| item_selling_price |
| sale_return_line_item | | sale_transaction |
+-----------------------+
因为以前的配置文件中设置了 HOST 为 master,因此这里须要修改用户 symmetric 的 HOST。
mysql> UPDATE user SET HOST='%' WHERE user='symmetric';
mysql> FLUSH privileges;
在 symmetric 中默认已经给出了自动化生成分销系统表的方式,只要一句指令便可:
指令
$ ./bin/symadmin --engine corp-000 create-sym-tables
检查结果
查看 MySQL 中的数据表
mysql> show tables;
+-----------------------------+
| Tables_in_sample |
+-----------------------------+
| item |
| item_selling_price |
| sale_return_line_item |
| sale_transaction |
| sym_channel |
| sym_conflict |
| sym_data |
| sym_data_event |
| sym_data_gap |
| sym_extension |
| sym_extract_request |
| sym_file_incoming |
| sym_file_snapshot |
| sym_file_trigger |
| sym_file_trigger_router |
| sym_grouplet |
| sym_grouplet_link |
| sym_incoming_batch |
| sym_incoming_error |
| sym_load_filter |
| sym_lock |
| sym_node |
| sym_node_channel_ctl |
| sym_node_communication |
| sym_node_group |
| sym_node_group_channel_wnd |
| sym_node_group_link |
| sym_node_host |
| sym_node_host_channel_stats |
| sym_node_host_job_stats |
| sym_node_host_stats |
| sym_node_identity |
| sym_node_security |
| sym_outgoing_batch |
| sym_parameter |
| sym_registration_redirect |
| sym_registration_request |
| sym_router |
| sym_sequence |
| sym_table_reload_request |
| sym_transform_column |
| sym_transform_table |
| sym_trigger |
| sym_trigger_hist |
| sym_trigger_router |
| sym_trigger_router_grouplet |
+-----------------------------+
46 rows in set (0.00 sec)
虽然上面说了一堆东西,可是还只是一堆空的数据表,以下咱们就把 symmetric 自带的数据填充到数据表中。操做过程以下:
指令
$ ./bin/dbimport --engine corp-000 ./samples/insert_sample.sql
结果检查
mysql> select * from item_selling_price; +----------+----------+-------+------+
| item_id | store_id | price | cost | +----------+----------+-------+------+
| 11000001 | 001 | 0.20 | 0.10 |
| 11000001 | 002 | 0.30 | 0.20 | +----------+----------+-------+------+
2 rows in set (0.00 sec)
由于这里是两个节点之间的数据同步,因此咱们须要启动两个节点:corp 和 store
start corp node
corp 设置开启的端口为 8080
$ ./bin/sym --engine corp-000 --port 8080
start store node
store 设置开启的端口为 9090
$ ./bin/sym --engine store-001 --port 9090
上面两个窗口的启动以后,会进入等待状态,因此若是有其余操做,就须要另外打开窗口了。
这里还有一步须要处理就是注册节点,注册操做在 corp 和 store 启动以后进行。
$ ./bin/symadmin --engine corp-000 open-registration store 001
Log output will be written to /home/hadoop/symmetric/logs/symmetric.log
[] - AbstractCommandLauncher - Option: name=engine, value={corp-000}
[corp-000] - JdbcDatabasePlatformFactory - Detected database 'MySQL', version '5', protocol 'mysql'
[corp-000] - JdbcDatabasePlatformFactory - The IDatabasePlatform being used is org.jumpmind.db.platform.mysql.MySqlDatabasePlatform
[corp-000] - MySqlSymmetricDialect - The DbDialect being used is org.jumpmind.symmetric.db.mysql.MySqlSymmetricDialect
[corp-000] - ExtensionService - Found 0 extension points from the database that will be registered
[corp-000] - StagingManager - The staging directory was initialized at the following location: /home/hadoop/symmetric/tmp/corp-000
[corp-000] - ClusterService - This node picked a server id of master
[corp-000] - ExtensionService - Found 0 extension points from the database that will be registered
[corp-000] - ClientExtensionService - Found 9 extension points from spring that will be registered
[corp-000] - RegistrationService - Registration was reopened for 001
Opened registration for node group of 'store' external ID of '001'
发送初始负载的目的是将最开始的时候 corp 节点数据表中的数据同步到 store 节点中。若是你开始的数据表中没有这些数据,那么就能够不用发送此负载了。
指令
$ ./bin/symadmin --engine corp-000 reload-node 001
结果
Log output will be written to /home/hadoop/symmetric/logs/symmetric.log
[] - AbstractCommandLauncher - Option: name=engine, value={corp-000}
[corp-000] - JdbcDatabasePlatformFactory - Detected database 'MySQL', version '5', protocol 'mysql'
[corp-000] - JdbcDatabasePlatformFactory - The IDatabasePlatform being used is org.jumpmind.db.platform.mysql.MySqlDatabasePlatform
[corp-000] - MySqlSymmetricDialect - The DbDialect being used is org.jumpmind.symmetric.db.mysql.MySqlSymmetricDialect
[corp-000] - ExtensionService - Found 0 extension points from the database that will be registered
[corp-000] - StagingManager - The staging directory was initialized at the following location: /home/hadoop/symmetric/tmp/corp-000
[corp-000] - ClusterService - This node picked a server id of master
[corp-000] - ExtensionService - Found 0 extension points from the database that will be registered
[corp-000] - ClientExtensionService - Found 9 extension points from spring that will be registered
Successfully enabled initial load for node 001
这里的验证为在 corp(即 master) 节点上修改一条数据,观察两个节点中数据表的变化。
在 corp 节点的数据库中执行相应 SQL 语句:
mysql> UPDATE item_selling_price SET price='0.21' WHERE item_id='11000001' AND store_id='001';
corp
mysql> select * from item_selling_price; +----------+----------+-------+------+
| item_id | store_id | price | cost | +----------+----------+-------+------+
| 11000001 | 001 | 0.21 | 0.10 |
| 11000001 | 002 | 0.30 | 0.20 | +----------+----------+-------+------+
2 rows in set (0.00 sec)
store
mysql> select * from item_selling_price; +----------+----------+-------+------+
| item_id | store_id | price | cost | +----------+----------+-------+------+
| 11000001 | 001 | 0.21 | 0.10 | +----------+----------+-------+------+
1 row in set (0.00 sec)
注意这里不要只添加一条记录,由于涉及到了数据库的触发器,咱们虚拟了一条交易记录,以下:
mysql> INSERT INTO item (item_id, name) VALUES (110000055, 'Soft Drink');
mysql> INSERT INTO item_selling_price (item_id, store_id, price) VALUES (110000055, '001', 0.65);
mysql> INSERT INTO item_selling_price (item_id, store_id, price) VALUES (110000055, '002', 1.00);
当一条交易被完成以后,咱们再去检查一下 store 节点中的数据信息:
mysql> select * from item_selling_price;
+-----------+----------+-------+------+
| item_id | store_id | price | cost | +-----------+----------+-------+------+
| 11000001 | 001 | 0.22 | 0.10 |
| 110000055 | 001 | 0.65 | NULL | +-----------+----------+-------+------+
2 rows in set (0.00 sec)
mysql> select * from item;
+-----------+------------+
| item_id | name | +-----------+------------+
| 11000001 | Yummy Gum |
| 110000055 | Soft Drink | +-----------+------------+
2 rows in set (0.00 sec)
数据的确是有增长的,验证完成。