├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── dictionaries
│ └── plin.xml
├── encodings.xml
├── libraries
│ ├── Maven__ch_qos_logback_logback_classic_1_1_2.xml
│ ├── Maven__ch_qos_logback_logback_core_1_1_2.xml
│ ├── Maven__com_alibaba_druid_1_0_11.xml
│ ├── Maven__com_alibaba_fastjson_1_1_35.xml
│ ├── Maven__com_alibaba_otter_canal_client_1_0_20.xml
│ ├── Maven__com_alibaba_otter_canal_common_1_0_20.xml
│ ├── Maven__com_alibaba_otter_canal_protocol_1_0_20.xml
│ ├── Maven__com_github_sgroschupf_zkclient_0_1.xml
│ ├── Maven__com_github_stephenc_findbugs_findbugs_annotations_1_3_9_1.xml
│ ├── Maven__com_google_code_findbugs_jsr305_1_3_9.xml
│ ├── Maven__com_google_guava_guava_12_0_1.xml
│ ├── Maven__com_google_guava_guava_18_0.xml
│ ├── Maven__com_google_protobuf_protobuf_java_2_4_1.xml
│ ├── Maven__com_google_protobuf_protobuf_java_2_5_0.xml
│ ├── Maven__com_jcraft_jsch_0_1_42.xml
│ ├── Maven__com_thoughtworks_paranamer_paranamer_2_3.xml
│ ├── Maven__com_yammer_metrics_metrics_core_2_2_0.xml
│ ├── Maven__commons_beanutils_commons_beanutils_1_7_0.xml
│ ├── Maven__commons_beanutils_commons_beanutils_core_1_8_0.xml
│ ├── Maven__commons_cli_commons_cli_1_2.xml
│ ├── Maven__commons_codec_commons_codec_1_9.xml
│ ├── Maven__commons_collections_commons_collections_3_2_2.xml
│ ├── Maven__commons_configuration_commons_configuration_1_6.xml
│ ├── Maven__commons_digester_commons_digester_1_8.xml
│ ├── Maven__commons_el_commons_el_1_0.xml
│ ├── Maven__commons_httpclient_commons_httpclient_3_1.xml
│ ├── Maven__commons_io_commons_io_2_4.xml
│ ├── Maven__commons_lang_commons_lang_2_6.xml
│ ├── Maven__commons_logging_commons_logging_1_2.xml
│ ├── Maven__commons_net_commons_net_3_1.xml
│ ├── Maven__io_netty_netty_3_6_2_Final.xml
│ ├── Maven__io_netty_netty_all_4_0_23_Final.xml
│ ├── Maven__javax_activation_activation_1_1.xml
│ ├── Maven__javax_xml_bind_jaxb_api_2_2_2.xml
│ ├── Maven__javax_xml_stream_stax_api_1_0_2.xml
│ ├── Maven__junit_junit_4_12.xml
│ ├── Maven__log4j_log4j_1_2_17.xml
│ ├── Maven__net_jpountz_lz4_lz4_1_2_0.xml
│ ├── Maven__net_sf_jopt_simple_jopt_simple_3_2.xml
│ ├── Maven__org_apache_avro_avro_1_7_4.xml
│ ├── Maven__org_apache_commons_commons_compress_1_4_1.xml
│ ├── Maven__org_apache_commons_commons_lang3_3_3_2.xml
│ ├── Maven__org_apache_commons_commons_math3_3_1_1.xml
│ ├── Maven__org_apache_directory_api_api_asn1_api_1_0_0_M20.xml
│ ├── Maven__org_apache_directory_api_api_util_1_0_0_M20.xml
│ ├── Maven__org_apache_directory_server_apacheds_i18n_2_0_0_M15.xml
│ ├── Maven__org_apache_directory_server_apacheds_kerberos_codec_2_0_0_M15.xml
│ ├── Maven__org_apache_hadoop_hadoop_annotations_2_5_1.xml
│ ├── Maven__org_apache_hadoop_hadoop_auth_2_5_1.xml
│ ├── Maven__org_apache_hadoop_hadoop_common_2_5_1.xml
│ ├── Maven__org_apache_hadoop_hadoop_mapreduce_client_core_2_5_1.xml
│ ├── Maven__org_apache_hadoop_hadoop_yarn_api_2_5_1.xml
│ ├── Maven__org_apache_hadoop_hadoop_yarn_common_2_5_1.xml
│ ├── Maven__org_apache_hbase_hbase_annotations_1_2_3.xml
│ ├── Maven__org_apache_hbase_hbase_client_1_2_3.xml
│ ├── Maven__org_apache_hbase_hbase_common_1_2_3.xml
│ ├── Maven__org_apache_hbase_hbase_protocol_1_2_3.xml
│ ├── Maven__org_apache_htrace_htrace_core_3_1_0_incubating.xml
│ ├── Maven__org_apache_httpcomponents_httpclient_4_2_5.xml
│ ├── Maven__org_apache_httpcomponents_httpcore_4_2_4.xml
│ ├── Maven__org_apache_kafka_kafka_2_10_0_8_2_0.xml
│ ├── Maven__org_apache_kafka_kafka_clients_0_8_2_0.xml
│ ├── Maven__org_apache_zookeeper_zookeeper_3_4_5.xml
│ ├── Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml
│ ├── Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml
│ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml
│ ├── Maven__org_jboss_netty_netty_3_2_2_Final.xml
│ ├── Maven__org_jruby_jcodings_jcodings_1_0_8.xml
│ ├── Maven__org_jruby_joni_joni_2_1_2.xml
│ ├── Maven__org_mortbay_jetty_jetty_util_6_1_26.xml
│ ├── Maven__org_scala_lang_scala_library_2_10_4.xml
│ ├── Maven__org_slf4j_jcl_over_slf4j_1_7_12.xml
│ ├── Maven__org_slf4j_log4j_over_slf4j_1_7_7.xml
│ ├── Maven__org_slf4j_slf4j_api_1_7_7.xml
│ ├── Maven__org_springframework_spring_2_5_6.xml
│ ├── Maven__org_tukaani_xz_1_0.xml
│ ├── Maven__org_xerial_snappy_snappy_java_1_1_1_6.xml
│ └── Maven__xmlenc_xmlenc_0_52.xml
├── misc.xml
├── modules.xml
├── thriftCompiler.xml
├── uiDesigner.xml
└── workspace.xml
├── .travis.yml
├── README.md
├── build
├── carrygo.build.iml
├── pom.xml
└── src
│ └── main
│ ├── assembly
│ ├── dev.xml
│ └── prod.xml
│ ├── bin
│ ├── start.sh
│ └── stop.sh
│ └── conf
│ ├── dev
│ ├── carrygo-conf.xml
│ ├── carrygo.properties
│ ├── env.sh
│ └── logback.xml
│ └── prod
│ ├── carrygo-conf.xml
│ ├── carrygo.properties
│ ├── env.sh
│ └── logback.xml
├── carrygo.iml
├── common
├── carrygo.common.iml
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── abc
│ │ └── carrygo
│ │ └── common
│ │ ├── Constants.java
│ │ ├── conf
│ │ ├── Configured.java
│ │ └── SpringConf.java
│ │ ├── factory
│ │ └── ListeningExecutorFactory.java
│ │ ├── hbase
│ │ ├── Constant.java
│ │ ├── HBaseCell.java
│ │ ├── HBaseClient.java
│ │ ├── HBaseConnector.java
│ │ └── HBaseTableAdmin.java
│ │ ├── kafka
│ │ ├── KafkaAcceptor.java
│ │ ├── KafkaAddress.java
│ │ ├── KafkaConnectors.java
│ │ ├── KafkaConsumer.java
│ │ ├── KafkaMessage.java
│ │ ├── KafkaPublisher.java
│ │ └── RecordPartitioner.java
│ │ ├── serde
│ │ └── ProtobufSerde.java
│ │ ├── utils
│ │ ├── ConcurrentUtil.java
│ │ ├── ConfigLoader.java
│ │ └── ReflectionUtil.java
│ │ ├── writer
│ │ └── AbstractWriter.java
│ │ └── zookeeper
│ │ └── ZkAddress.java
│ └── test
│ └── java
│ └── com
│ └── abc
│ └── carrgo
│ └── common
│ └── utils
│ └── TestUtils.java
├── install_protobuf.sh
├── parser
├── carrygo.parser.iml
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── abc
│ │ └── carrygo
│ │ └── parser
│ │ ├── AbstractEventFilter.java
│ │ ├── EventService.java
│ │ ├── common
│ │ ├── EventFeedManager.java
│ │ ├── entity
│ │ │ ├── Event.java
│ │ │ └── EventFeed.java
│ │ └── util
│ │ │ ├── DataLock.java
│ │ │ ├── EntryParser.java
│ │ │ └── ParserUtil.java
│ │ ├── kafka
│ │ ├── PublishCount.java
│ │ ├── feed
│ │ │ ├── KafkaFeed.java
│ │ │ └── KafkaFeedTask.java
│ │ ├── manager
│ │ │ └── KafkaFeedManager.java
│ │ ├── mysql
│ │ │ ├── MySQLDDLEvent.java
│ │ │ └── MySQLDMLEvent.java
│ │ ├── parse
│ │ │ ├── KafkaEntryParser.java
│ │ │ └── KafkaEventFilter.java
│ │ └── service
│ │ │ ├── KafkaEventHandler.java
│ │ │ ├── KafkaEventService.java
│ │ │ ├── KafkaFeedProcessor.java
│ │ │ └── KafkaFeedProcessorBuilder.java
│ │ └── server
│ │ └── CarryServer.java
│ └── resources
│ ├── carrygo-conf.xml
│ ├── carrygo.properties
│ └── logback.xml
├── pom.xml
├── protocol
├── carrgo.protocol.iml
├── carrygo.protocol.iml
├── pom.xml
└── src
│ └── main
│ └── proto
│ └── SQLProtocol.proto
└── store
├── carrygo.store.iml
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── abc
│ │ └── carrygo
│ │ └── store
│ │ ├── AbstractWriterProcessor.java
│ │ ├── hbase
│ │ ├── HBaseWriter.java
│ │ ├── HBaseWriterProcessor.java
│ │ ├── HBaseWriterProcessorBuilder.java
│ │ ├── MessageReceived.java
│ │ └── service
│ │ │ └── HBaseWriterService.java
│ │ └── server
│ │ └── WriterServer.java
└── resources
│ ├── carrygo-conf.xml
│ ├── carrygo.properties
│ └── logback.xml
└── test
└── java
└── com
└── abc
└── carrygo
└── store
└── hbase
├── HBaseWriterBase.java
├── HBaseWriterMultiThreadTest.java
└── HBaseWriterTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | logs
3 |
4 | # eclipse
5 | .classpath
6 | .project
7 | .settings
8 |
9 | # idea
10 | .idea
11 | *.iml
12 | *.ipr
13 | *.iws
14 |
15 | # maven
16 | *.versionsBackup
17 |
18 | # OS X
19 | .DS_Store
20 |
21 | # log
22 | *.log
23 | log.*
24 | log
25 |
26 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | carrygo
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/dictionaries/plin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_druid_1_0_11.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_fastjson_1_1_35.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_otter_canal_client_1_0_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_otter_canal_common_1_0_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_otter_canal_protocol_1_0_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_github_sgroschupf_zkclient_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_github_stephenc_findbugs_findbugs_annotations_1_3_9_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_code_findbugs_jsr305_1_3_9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_guava_guava_12_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_guava_guava_18_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_4_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_5_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_jcraft_jsch_0_1_42.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_thoughtworks_paranamer_paranamer_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_yammer_metrics_metrics_core_2_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_7_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_beanutils_commons_beanutils_core_1_8_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_cli_commons_cli_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_codec_commons_codec_1_9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_configuration_commons_configuration_1_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_digester_commons_digester_1_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_el_commons_el_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_io_commons_io_2_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_net_commons_net_3_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_netty_netty_3_6_2_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_netty_netty_all_4_0_23_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_activation_activation_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_xml_stream_stax_api_1_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__junit_junit_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__log4j_log4j_1_2_17.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_jpountz_lz4_lz4_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_sf_jopt_simple_jopt_simple_3_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_avro_avro_1_7_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_compress_1_4_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_3_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_math3_3_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_directory_api_api_asn1_api_1_0_0_M20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_directory_api_api_util_1_0_0_M20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_directory_server_apacheds_i18n_2_0_0_M15.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_directory_server_apacheds_kerberos_codec_2_0_0_M15.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_annotations_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_auth_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_common_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_mapreduce_client_core_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_yarn_api_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hadoop_hadoop_yarn_common_2_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hbase_hbase_annotations_1_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hbase_hbase_client_1_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hbase_hbase_common_1_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_hbase_hbase_protocol_1_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_htrace_htrace_core_3_1_0_incubating.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_2_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_2_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_kafka_kafka_2_10_0_8_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_kafka_kafka_clients_0_8_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_jboss_netty_netty_3_2_2_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_jruby_jcodings_jcodings_1_0_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_jruby_joni_joni_2_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mortbay_jetty_jetty_util_6_1_26.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_scala_lang_scala_library_2_10_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_7_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_7.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_7.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_2_5_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_tukaani_xz_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_xerial_snappy_snappy_java_1_1_1_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__xmlenc_xmlenc_0_52.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Android Lint
22 |
23 |
24 | Data flow issuesJava
25 |
26 |
27 | Groovy
28 |
29 |
30 | Initialization issuesJava
31 |
32 |
33 | J2ME issuesJava
34 |
35 |
36 | Java
37 |
38 |
39 | JavaScript
40 |
41 |
42 | Memory issuesJava
43 |
44 |
45 | Performance issuesJava
46 |
47 |
48 | Potentially confusing code constructsJavaScript
49 |
50 |
51 | Threading issuesGroovy
52 |
53 |
54 | Threading issuesJava
55 |
56 |
57 |
58 |
59 | Android
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | 1.7
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/thriftCompiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: java
4 | jdk: openjdk7
5 | cache:
6 | directories:
7 | - $HOME/.m2
8 | before_install:
9 | - ./install_protobuf.sh
10 | install:
11 | - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
12 | group: stable
13 | os: linux
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | carrygo
2 | ===========
3 |
4 | [](https://travis-ci.org/linpelvis/carrygo)
5 | [](https://landscape.io/github/linpelvis/carrygo/master)
6 | [](https://requires.io/github/linpelvis/carrygo/requirements/?branch=master)
7 |
8 |
9 | 主要作用是同步mysql数据库至hbase,kudu等存储系统。
10 |
11 |
12 |
13 | # 功能 #
14 |
15 | - canal日志解析,kafka持久化消息
16 | - 消费kafka消息同步至hbase等存储引擎
17 | - mysql的数据同步支持DDL、DML至hbase
18 |
19 |
20 | # 原理 #
21 |
22 | carrygo解析及存储服务主要有两个模块,分别是parser和store。
23 |
24 | ### CarryServer ###
25 | 1. 基于canal解析mysql的binlog,批量获取message的entry
26 | 2. 过滤出需同步的db,并解析数据流,同步到kafka中
27 |
28 | ### WriterServer ###
29 | 1. 基于topic接受kafka的消息
30 | 2. HBaseWriter解析数据并存储
31 |
32 | # 相关资源 #
33 | canal:https://github.com/alibaba/canal
34 |
35 | # TODO #
36 | 1. CarryServer服务不可用导致queue数据丢失,存储batchId至zookeeper并记录消费的batchId,丢失就rollback。
37 | 2. 添加CarrygoManager,CarrgoMonitor服务。
38 | 3. 添加管理控制台。
39 |
40 |
41 | # 问题反馈 #
42 | 1. 邮箱:linpelvis@gmail.com
43 | 2. issue:https://github.com/linpelvis/carrygo/issues
44 |
45 |
--------------------------------------------------------------------------------
/build/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | carrygo
7 | com.abc.carrygo
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | carrygo.build
14 |
15 |
16 |
17 |
18 | com.abc.carrygo
19 | carrygo.parser
20 | 1.0-SNAPSHOT
21 |
22 |
23 |
24 | com.abc.carrygo
25 | carrygo.store
26 | 1.0-SNAPSHOT
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | dev
35 |
36 | true
37 |
38 |
39 | carrygo
40 | dev.xml
41 |
42 |
43 |
44 | prod
45 |
46 | carrygo
47 | prod.xml
48 |
49 |
50 |
51 |
52 |
53 | ${project.finalName}
54 |
55 |
56 | maven-assembly-plugin
57 |
58 |
59 | false
60 |
61 | src/main/assembly/${assembly.descriptor.file}
62 |
63 |
64 |
65 |
66 | make-assembly
67 | package
68 |
69 | single
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/build/src/main/assembly/dev.xml:
--------------------------------------------------------------------------------
1 |
4 | dist
5 |
6 | tar.gz
7 |
8 | true
9 |
10 |
11 | .
12 | /
13 |
14 | README*
15 |
16 |
17 |
18 | ./src/main/bin
19 | bin
20 |
21 | **/*
22 |
23 | 0755
24 |
25 |
26 | ./src/main/conf/dev
27 | /conf
28 |
29 | **/*
30 |
31 |
32 |
33 | ./src/main/resources
34 | /conf
35 |
36 | **/*
37 |
38 |
39 |
40 |
41 |
42 | lib
43 | runtime
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/build/src/main/assembly/prod.xml:
--------------------------------------------------------------------------------
1 |
4 | dist
5 |
6 | tar.gz
7 |
8 | true
9 |
10 |
11 | .
12 | /
13 |
14 | README*
15 |
16 |
17 |
18 | ./src/main/bin
19 | bin
20 |
21 | **/*
22 |
23 | 0755
24 |
25 |
26 | ./src/main/conf/prod
27 | /conf
28 |
29 | **/*
30 |
31 |
32 |
33 | ./src/main/resources
34 | /conf
35 |
36 | **/*
37 |
38 |
39 |
40 |
41 |
42 | lib
43 | runtime
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/build/src/main/bin/start.sh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linpelvis/carrygo/deedd9d4841cc3edede2ec6c4f7cc60bc335c2d8/build/src/main/bin/start.sh
--------------------------------------------------------------------------------
/build/src/main/bin/stop.sh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linpelvis/carrygo/deedd9d4841cc3edede2ec6c4f7cc60bc335c2d8/build/src/main/bin/stop.sh
--------------------------------------------------------------------------------
/build/src/main/conf/dev/carrygo-conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | classpath:carrygo.properties
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/build/src/main/conf/dev/carrygo.properties:
--------------------------------------------------------------------------------
1 | [kafka]
2 | kafka.ip = 127.0.0.1
3 | kafka.port = 9092
4 | kafka.topic = test
5 |
6 | [zookeeper]
7 | zookeeper.destination = example
8 | zookeeper.ip = 127.0.0.1
9 | zookeeper.port = 2181
10 |
11 |
--------------------------------------------------------------------------------
/build/src/main/conf/dev/env.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SERVER_LIST="carry writer"
4 |
5 | CARRY_MAIN_CLASS="com.abc.carrygo.parser.server.CarryServer"
6 | WRITER_MAIN_CLASS="com.abc.carrygo.store.server.WriterServer"
7 |
8 |
9 | JAVA_OPTS="-server -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+UseConcMarkSweepGC"
10 | JAVA_OPTS="$JAVA_OPTS -XX:MaxPermSize=512m"
11 |
--------------------------------------------------------------------------------
/build/src/main/conf/dev/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | log
6 |
7 |
9 | log.%d{yyyy-MM-dd}.%i
10 |
11 |
12 | 500MB
13 |
14 |
15 | 3
16 |
17 |
18 |
19 | UTF-8
20 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/build/src/main/conf/prod/carrygo-conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | classpath:carrygo.properties
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/build/src/main/conf/prod/carrygo.properties:
--------------------------------------------------------------------------------
1 | [kafka]
2 | kafka.ip = 127.0.0.1
3 | kafka.port = 9092
4 | kafka.topic = test
5 |
6 | [zookeeper]
7 | zookeeper.destination = example
8 | zookeeper.ip = 127.0.0.1
9 | zookeeper.port = 2181
10 |
11 |
--------------------------------------------------------------------------------
/build/src/main/conf/prod/env.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SERVER_LIST="carry writer"
4 |
5 | CARRY_MAIN_CLASS="com.abc.carrygo.parser.server.CarryServer"
6 | WRITER_MAIN_CLASS="com.abc.carrygo.store.server.WriterServer"
7 |
8 |
9 | JAVA_OPTS="-server -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -Xloggc:gc.log -XX:+UseConcMarkSweepGC"
10 | JAVA_OPTS="$JAVA_OPTS -XX:MaxPermSize=512m"
11 |
--------------------------------------------------------------------------------
/build/src/main/conf/prod/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | log
6 |
7 |
9 | log.%d{yyyy-MM-dd}.%i
10 |
11 |
12 | 500MB
13 |
14 |
15 | 3
16 |
17 |
18 |
19 | UTF-8
20 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/carrygo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | carrygo
7 | com.abc.carrygo
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | carrygo.common
14 | jar
15 |
16 |
17 |
18 |
19 | com.abc.carrygo
20 | carrygo.protocol
21 | 1.0-SNAPSHOT
22 |
23 |
24 |
25 | org.apache.hbase
26 | hbase-client
27 |
28 |
29 |
30 | org.apache.kafka
31 | kafka-clients
32 |
33 |
34 |
35 | org.apache.kafka
36 | kafka_2.10
37 |
38 |
39 |
40 | com.alibaba
41 | druid
42 |
43 |
44 |
45 | org.apache.commons
46 | commons-lang3
47 |
48 |
49 |
50 | com.alibaba.otter
51 | canal.client
52 |
53 |
54 |
55 | ch.qos.logback
56 | logback-classic
57 | runtime
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/Constants.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common;
2 |
3 | /**
4 | * Created by plin on 10/12/16.
5 | */
6 | public final class Constants {
7 | public static final int CAPACITY = 10000;
8 | public static final int THREAD_RETRY_TIMES = 3;
9 | public static final int THREAD_RETRY_INTERVAL = 1000;
10 |
11 | public static final String KEY_ZK_PARENT = "zookeeper.znode.parent";
12 | public static final String KEY_ZK_QUORUM = "hbase.zookeeper.quorum";
13 | public static final String KEY_ZK_CLIENTPORT = "hbase.zookeeper.clientPort";
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/conf/Configured.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.conf;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaAddress;
4 | import com.abc.carrygo.common.utils.ConfigLoader;
5 | import com.abc.carrygo.common.zookeeper.ZkAddress;
6 |
7 | /**
8 | * Created by plin on 10/8/16.
9 | */
10 | public class Configured {
11 | public static ZkAddress zkAddress;
12 | public static KafkaAddress kafkaAddress;
13 |
14 | public static String kafkaTopic;
15 |
16 | static {
17 | ConfigLoader configLoader = new ConfigLoader("carrygo.properties");
18 |
19 | zkAddress = new ZkAddress(
20 | configLoader.getValue("zookeeper.destination"),
21 | configLoader.getValue("zookeeper.ip"),
22 | configLoader.getValue("zookeeper.port"));
23 |
24 | kafkaAddress = new KafkaAddress(
25 | configLoader.getValue("kafka.ip"),
26 | configLoader.getValue("kafka.port"));
27 |
28 | kafkaTopic = configLoader.getValue("kafka.topic");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/conf/SpringConf.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.conf;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaAddress;
4 | import com.abc.carrygo.common.zookeeper.ZkAddress;
5 | import org.springframework.context.ApplicationContext;
6 | import org.springframework.context.support.FileSystemXmlApplicationContext;
7 |
8 | /**
9 | * Created by plin on 10/8/16.
10 | */
11 | public class SpringConf {
12 | private static final String path = "server/src/main/resources/carrygo-conf.xml";
13 |
14 | public static ZkAddress zkAddress;
15 | public static KafkaAddress kafkaAddress;
16 | public static ApplicationContext context;
17 |
18 | static {
19 | context = new FileSystemXmlApplicationContext(path);
20 | zkAddress = (ZkAddress) context.getBean("zkAddress");
21 | kafkaAddress = (KafkaAddress) context.getBean("kafkaAddress");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/factory/ListeningExecutorFactory.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.factory;
2 |
3 | import com.abc.carrygo.common.utils.ConcurrentUtil;
4 | import com.google.common.util.concurrent.ForwardingListeningExecutorService;
5 | import com.google.common.util.concurrent.ListeningExecutorService;
6 | import org.apache.commons.lang3.StringUtils;
7 |
8 | import java.util.concurrent.ExecutorService;
9 | import java.util.concurrent.Executors;
10 | import java.util.concurrent.ThreadFactory;
11 |
12 | public class ListeningExecutorFactory extends ForwardingListeningExecutorService {
13 |
14 | private static final String DEFAULT_THREAD_FACTORY_NAME = "carrygo";
15 | private static final int DEFAULT_THREADS;
16 |
17 | static {
18 | DEFAULT_THREADS = Math.max(1,
19 | Runtime.getRuntime().availableProcessors() * 2);
20 | }
21 |
22 | private ListeningExecutorService listeningExecutorService;
23 |
24 | public ListeningExecutorFactory() {
25 | this(DEFAULT_THREADS);
26 | }
27 |
28 | public ListeningExecutorFactory(int nThreads, String name) {
29 | this(nThreads > 0 ? nThreads : DEFAULT_THREADS,
30 | ConcurrentUtil.getNamedThreadFactory(StringUtils.isNotEmpty(name) ? name : DEFAULT_THREAD_FACTORY_NAME));
31 | }
32 |
33 | public ListeningExecutorFactory(int nThreads) {
34 | this(nThreads, DEFAULT_THREAD_FACTORY_NAME);
35 | }
36 |
37 | public ListeningExecutorFactory(int nThreads, ThreadFactory factory) {
38 | this(Executors.newFixedThreadPool(nThreads, factory));
39 | }
40 |
41 | public ListeningExecutorFactory(ExecutorService executorService) {
42 | this.listeningExecutorService = ConcurrentUtil.getListeningExecutorService(executorService);
43 | }
44 |
45 | @Override
46 | protected ListeningExecutorService delegate() {
47 | return this.listeningExecutorService;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/hbase/Constant.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.hbase;
2 |
3 |
4 | public class Constant {
5 | public static final String DEFAULT_NULLMODE = "EMPTY_BYTES";
6 | public static final String DEFAULT_ENCODING = "utf-8";
7 | public static final int DEFAULT_BATCHROWS = 100;
8 | public static final int MAX_BATCHROWS = 1000;
9 | public static final String DEFAULT_COLUMN_FAMILY = "cf";
10 | public static final String DEFAULT_QUALIFIER = "unknown";
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/hbase/HBaseCell.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.hbase;
2 |
3 | public class HBaseCell {
4 | private String rowKey;
5 | private String colf;
6 | private String col;
7 | private String value;
8 |
9 | public String getRowKey() {
10 | return rowKey;
11 | }
12 |
13 | public void setRowKey(String rowKey) {
14 | this.rowKey = rowKey;
15 | }
16 |
17 | public String getColf() {
18 | return colf;
19 | }
20 |
21 | public void setColf(String colf) {
22 | this.colf = colf;
23 | }
24 |
25 | public String getCol() {
26 | return col;
27 | }
28 |
29 | public void setCol(String col) {
30 | this.col = col;
31 | }
32 |
33 | public String getValue() {
34 | return value;
35 | }
36 |
37 | public void setValue(String value) {
38 | this.value = value;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/hbase/HBaseClient.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.hbase;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import org.apache.hadoop.hbase.client.Delete;
5 | import org.apache.hadoop.hbase.client.Put;
6 | import org.apache.hadoop.hbase.client.Table;
7 | import org.apache.hadoop.hbase.util.Bytes;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.io.IOException;
12 | import java.util.ArrayList;
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | public class HBaseClient {
17 | private final Logger log = LoggerFactory.getLogger(this.getClass());
18 |
19 | public void put(String tableName, HBaseCell cell) throws Exception {
20 | log.info("put cell, tableName:{}, cell:{}", tableName, JSONObject.toJSON(cell));
21 |
22 | Table table = HBaseConnector.getTable(tableName);
23 |
24 | Put p = new Put(Bytes.toBytes(cell.getRowKey()));
25 | p.addColumn(Bytes.toBytes(cell.getColf()),
26 | Bytes.toBytes(cell.getCol()),
27 | Bytes.toBytes(cell.getValue()));
28 |
29 | put(Arrays.asList(p), table);
30 | }
31 |
32 | public void put(String tableName, List cells) throws Exception {
33 | log.info("put cells, tableName:{}, cells:{}", tableName, JSONObject.toJSON(cells));
34 |
35 | Table table = HBaseConnector.getTable(tableName);
36 |
37 | List puts = new ArrayList<>();
38 | if (cells != null && cells.size() > 0) {
39 |
40 | for (HBaseCell cell : cells) {
41 |
42 | Put p = new Put(Bytes.toBytes(cell.getRowKey()));
43 | p.addColumn(Bytes.toBytes(cell.getColf()),
44 | Bytes.toBytes(cell.getCol() == null ? Constant.DEFAULT_QUALIFIER : cell.getCol()),
45 | Bytes.toBytes(cell.getValue() == null ? "" : cell.getValue()));
46 | puts.add(p);
47 | }
48 |
49 | put(puts, table);
50 | } //if(cells != null && cells.size() > 0)
51 | }
52 |
53 |
54 | public void delete(String tableName, String rowKey) throws Exception {
55 | log.info("delete rowKey, tableName:{}, rowKey:{}", tableName, rowKey);
56 |
57 | Table table = HBaseConnector.getTable(tableName);
58 |
59 | Delete delete = new Delete(rowKey.getBytes());
60 |
61 | try {
62 | table.delete(delete);
63 | } catch (Exception e) {
64 | log.error("delete rowKey " + delete.toString() + " failed.", e);
65 | throw e;
66 | } finally {
67 | if (table != null) {
68 | try {
69 | table.close();
70 | } catch (Exception e) {
71 | log.error("close table" + table.getName() + " failed.", e);
72 | throw e;
73 | }
74 | }
75 | }
76 | }
77 |
78 | public void delete(String tableName, List rowKeys) throws Exception {
79 | log.info("delete rowKeys, tableName:{}, rowKeys:{}", tableName, rowKeys);
80 |
81 | Table table = HBaseConnector.getTable(tableName);
82 |
83 | List deletes = new ArrayList<>();
84 |
85 | for (String rowKey : rowKeys) {
86 | Delete delete = new Delete(rowKey.getBytes());
87 | deletes.add(delete);
88 | }
89 |
90 | delete(deletes, table);
91 | }
92 |
93 | private void delete(List deletes, Table table) throws IOException {
94 | try {
95 | table.delete(deletes);
96 | } catch (Exception e) {
97 | log.error("delete rowKeys " + deletes.toString() + " failed.", e);
98 | throw e;
99 | } finally {
100 | if (table != null) {
101 | try {
102 | table.close();
103 | } catch (Exception e) {
104 | log.error("close table" + table.getName() + " failed.", e);
105 | throw e;
106 | }
107 | }
108 | }
109 | }
110 |
111 | private void put(List puts, Table table) throws IOException {
112 | try {
113 | table.put(puts);
114 | } catch (Exception e) {
115 | log.error("put table " + table.getName() + " failed.", e);
116 | throw e;
117 | } finally {
118 | if (table != null) {
119 | try {
120 | table.close();
121 | } catch (Exception e) {
122 | log.error("close table " + table.getName() + " failed.", e);
123 | throw e;
124 | }
125 | }
126 | }
127 | }
128 |
129 | public void close() throws Exception {
130 | HBaseConnector.close();
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/hbase/HBaseConnector.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.hbase;
2 |
3 | import com.abc.carrygo.common.zookeeper.ZkAddress;
4 | import org.apache.hadoop.conf.Configuration;
5 | import org.apache.hadoop.hbase.HBaseConfiguration;
6 | import org.apache.hadoop.hbase.TableName;
7 | import org.apache.hadoop.hbase.client.Admin;
8 | import org.apache.hadoop.hbase.client.Connection;
9 | import org.apache.hadoop.hbase.client.ConnectionFactory;
10 | import org.apache.hadoop.hbase.client.Table;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.io.IOException;
15 |
16 | /**
17 | * Created by plin on 10/13/16.
18 | */
19 | public class HBaseConnector {
20 | private static final Logger log = LoggerFactory.getLogger(HBaseConnector.class);
21 |
22 | private static Connection connection;
23 |
24 | private static Admin admin;
25 |
26 | public static void init(ZkAddress zkAddress) throws IOException {
27 | //configuration.set("hbase.zookeeper.quorum","10.10.3.181,10.10.3.182,10.10.3.183");
28 | //configuration.set("hbase.zookeeper.property.clientPort","2181");
29 | System.setProperty("hadoop.home.dir", "/");
30 |
31 | Configuration configuration = HBaseConfiguration.create();
32 | configuration.set("hbase.zookeeper.quorum", zkAddress.getZkIp());
33 | configuration.set("hbase.zookeeper.property.clientPort", zkAddress.getZkPort());
34 | configuration.set("zookeeper.znode.parent", "/hbase");
35 |
36 | configuration.set("hbase.client.retries.number", "3"); // default 35
37 | configuration.set("hbase.rpc.timeout", "10000"); // default 60 secs
38 | configuration.set("hbase.rpc.shortoperation.timeout", "5000"); // default 10 secs
39 |
40 |
41 | // if (confs != null && confs.size() > 0) {
42 | // for (String key : confs.keySet()) {
43 | // configuration.set(key, confs.get(key));
44 | // }
45 | // }
46 |
47 | try {
48 | //hbase-client中protobuf版本与hbase不兼容会导致无法连接的问题
49 | connection = ConnectionFactory.createConnection(configuration);
50 | admin = connection.getAdmin();
51 | } catch (Exception e) {
52 | log.error("hbase init exception occured.", e);
53 | throw e;
54 | }
55 | }
56 |
57 | public static void close() throws Exception {
58 | try {
59 | if (connection != null) {
60 | connection.close();
61 | }
62 | } catch (Exception e) {
63 | log.error("hbase connection close exception occured.", e);
64 | throw e;
65 | }
66 | }
67 |
68 | public static Admin getAdmin() {
69 | return admin;
70 | }
71 |
72 | public static Connection getConnection() {
73 | return connection;
74 | }
75 |
76 | public static Table getTable(String tableName) throws Exception {
77 | Table table = null;
78 | try {
79 | if (connection != null) {
80 | table = connection.getTable(TableName.valueOf(tableName));
81 | }
82 | } catch (Exception e) {
83 | log.error("get table " + tableName + " failed.", e);
84 | throw e;
85 | }
86 | return table;
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaAcceptor.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import com.abc.carrygo.common.factory.ListeningExecutorFactory;
4 | import com.abc.carrygo.common.utils.ReflectionUtil;
5 | import com.abc.carrygo.common.writer.AbstractWriter;
6 | import com.abc.carrygo.common.zookeeper.ZkAddress;
7 | import kafka.consumer.KafkaStream;
8 | import kafka.javaapi.consumer.ConsumerConnector;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.HashMap;
13 | import java.util.List;
14 | import java.util.Map;
15 | import java.util.concurrent.TimeUnit;
16 |
17 | /**
18 | * Created by plin on 9/26/16.
19 | */
20 | public class KafkaAcceptor {
21 | private static final Logger log = LoggerFactory.getLogger(KafkaAcceptor.class);
22 | private static final String DEFAULT_EXECUTOR_NAME = "kafka-acceptor";
23 | private static final int numThreads = 1;
24 | private ConsumerConnector consumerConnector;
25 | private ListeningExecutorFactory executor;
26 | private String topic;
27 |
28 | public KafkaAcceptor(ZkAddress zkAddress, String topic) {
29 | this(zkAddress, topic, zkAddress.getZkDestination());
30 | }
31 |
32 | public KafkaAcceptor(ZkAddress zkAddress, String topic, String groupId) {
33 | this.consumerConnector = KafkaConnectors.newConsumer(zkAddress, groupId);
34 | this.topic = topic;
35 | }
36 |
37 |
38 | public void run(int nThreads, AbstractWriter writer, String theClass) throws Exception {
39 | Class aClass = Class.forName(theClass);
40 |
41 | Map topicCountMap = new HashMap<>();
42 |
43 | // one topic one thread
44 | topicCountMap.put(topic, numThreads);
45 |
46 | try {
47 | Map>> consumerMap = consumerConnector.createMessageStreams(topicCountMap);
48 |
49 | for (String topic : consumerMap.keySet()) {
50 | log.info("start acceptor topic:{}", topic);
51 |
52 | List> streams = consumerMap.get(topic);
53 |
54 | executor = new ListeningExecutorFactory(nThreads, DEFAULT_EXECUTOR_NAME);
55 |
56 | for (final KafkaStream stream : streams) {
57 | executor.submit((Runnable) ReflectionUtil.newInstance(aClass, writer, stream));
58 | }
59 | }
60 |
61 | } catch (Exception e) {
62 | log.error("acceptor msg failed.", e);
63 | close();
64 |
65 | throw e;
66 | }
67 |
68 | }
69 |
70 |
71 | public void close() {
72 |
73 | if (executor != null) {
74 | try {
75 | Thread.sleep(10000);
76 | } catch (InterruptedException e) {
77 | e.printStackTrace();
78 | }
79 | executor.shutdown();
80 | }
81 |
82 | if (consumerConnector != null) {
83 | consumerConnector.shutdown();
84 | }
85 |
86 | try {
87 | if (!executor.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
88 | log.info("Timed out waiting for consumer threads to shut down, exiting uncleanly");
89 | executor.shutdownNow();
90 | }
91 | } catch (InterruptedException e) {
92 | log.info("Interrupted during shutdown, exiting uncleanly");
93 | executor.shutdownNow();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaAddress.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import com.google.common.base.Joiner;
4 |
5 | /**
6 | * Created by plin on 9/30/16.
7 | */
8 | public class KafkaAddress {
9 | private static final Joiner PATH_JOINER = Joiner.on(":").skipNulls();
10 |
11 | private String kafkaIp;
12 | private String kafkaPort;
13 |
14 | // use spring conf
15 | public KafkaAddress() {
16 | }
17 |
18 | public KafkaAddress(String kafkaIp, String kafkaPort) {
19 | this.kafkaIp = kafkaIp;
20 | this.kafkaPort = kafkaPort;
21 | }
22 |
23 | public void setKafkaPort(String kafkaPort) {
24 | this.kafkaPort = kafkaPort;
25 | }
26 |
27 | public void setKafkaIp(String kafkaIp) {
28 | this.kafkaIp = kafkaIp;
29 | }
30 |
31 | public String getKafkaServers() {
32 | return PATH_JOINER.join(kafkaIp, kafkaPort);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaConnectors.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import com.abc.carrygo.common.zookeeper.ZkAddress;
4 | import kafka.consumer.ConsumerConfig;
5 | import kafka.javaapi.consumer.ConsumerConnector;
6 | import org.apache.kafka.clients.producer.KafkaProducer;
7 | import org.apache.kafka.clients.producer.Producer;
8 | import org.apache.kafka.clients.producer.ProducerConfig;
9 |
10 | import java.util.Properties;
11 |
12 | /**
13 | * Created by plin on 9/26/16.
14 | */
15 | public class KafkaConnectors {
16 | private static volatile KafkaConnectors instance = new KafkaConnectors();
17 |
18 | private KafkaConnectors() {
19 | }
20 |
21 | public static KafkaConnectors getInstance() {
22 | return instance;
23 | }
24 |
25 | public static Producer newProducer(KafkaAddress kafkaAddress) {
26 | return initProducer(kafkaAddress);
27 | }
28 |
29 | private static Producer initProducer(KafkaAddress kafkaAddress) {
30 | Properties props = new Properties();
31 | //分组partition, compression
32 | props.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaAddress.getKafkaServers());
33 | props.setProperty(ProducerConfig.ACKS_CONFIG, "1");
34 | // props.setProperty(ProducerConfig.RETRIES_CONFIG, "3");
35 | // props.setProperty(ProducerConfig.BATCH_SIZE_CONFIG, "16384");
36 | // props.setProperty(ProducerConfig.LINGER_MS_CONFIG, "1");
37 | // props.setProperty(ProducerConfig.BUFFER_MEMORY_CONFIG, "33554432");
38 | // props.setProperty(ProducerConfig.METADATA_FETCH_TIMEOUT_CONFIG, "300");
39 | // props.setProperty(ProducerConfig.TIMEOUT_CONFIG, "300");
40 | // props.setProperty(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, "10000");
41 | // props.setProperty(ProducerConfig.RECONNECT_BACKOFF_MS_CONFIG, "10000");
42 | props.setProperty(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy");
43 |
44 | props.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
45 | "org.apache.kafka.common.serialization.StringSerializer");
46 | props.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
47 | "org.apache.kafka.common.serialization.ByteArraySerializer");
48 |
49 | // props.setProperty("partitioner.class", "com.abc.carrygo.common.kafka.RecordPartitioner");
50 |
51 | return new KafkaProducer<>(props);
52 | }
53 |
54 | public static ConsumerConnector newConsumer(ZkAddress zkAddress, String groupId) {
55 | return initConsumer(zkAddress, groupId);
56 | }
57 |
58 | private static ConsumerConnector initConsumer(ZkAddress zkAddress, String groupId) {
59 | return kafka.consumer.Consumer.createJavaConsumerConnector(
60 | createConsumerConfig(zkAddress.getZkServers(), groupId, true));
61 | }
62 |
63 | private static ConsumerConfig createConsumerConfig(String servers, String groupId, boolean isBeginning) {
64 | Properties props = new Properties();
65 | props.put("zookeeper.connect", servers);
66 | props.put("group.id", groupId);
67 | props.put("zookeeper.session.timeout.ms", "3000");
68 | props.put("zookeeper.sync.time.ms", "1000");
69 | props.put("auto.commit.enable", "true");
70 | props.put("auto.commit.interval.ms", "1000");
71 | // props.put("queued.max.message.chunks", "50");
72 | // props.put("rebalance.max.retries", "5");
73 | if (isBeginning) {
74 | props.put("auto.offset.reset", "smallest");
75 | } else {
76 | props.put("auto.offset.reset", "latest");
77 | }
78 |
79 | return new ConsumerConfig(props);
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaConsumer.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 |
4 | import kafka.consumer.KafkaStream;
5 |
6 | /**
7 | * Created by plin on 10/17/16.
8 | */
9 | public class KafkaConsumer implements Runnable {
10 | protected KafkaStream stream;
11 |
12 | public KafkaConsumer(KafkaStream stream) {
13 | this.stream = stream;
14 | }
15 |
16 | @Override
17 | public void run() {
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaMessage.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import com.abc.carrygo.protocol.SQLEventEntry;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * Created by plin on 9/29/16.
9 | */
10 | public class KafkaMessage implements Serializable {
11 | private String topic;
12 | private String key;
13 | private SQLEventEntry.SQLEntry sqlEntry;
14 |
15 | public KafkaMessage(String topic, String key, SQLEventEntry.SQLEntry sqlEntry) {
16 | this.topic = topic;
17 | this.key = key;
18 | this.sqlEntry = sqlEntry;
19 | }
20 |
21 | public SQLEventEntry.SQLEntry getSqlEntry() {
22 | return sqlEntry;
23 | }
24 |
25 |
26 | public String getTopic() {
27 | return topic;
28 | }
29 |
30 | public String getKey() {
31 | return key;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/KafkaPublisher.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import com.abc.carrygo.common.Constants;
4 | import com.abc.carrygo.common.serde.ProtobufSerde;
5 | import org.apache.commons.lang.StringUtils;
6 | import org.apache.kafka.clients.producer.Producer;
7 | import org.apache.kafka.clients.producer.ProducerRecord;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Created by plin on 9/26/16.
15 | */
16 | public final class KafkaPublisher {
17 | private static final Logger log = LoggerFactory.getLogger(KafkaPublisher.class);
18 |
19 | private final Producer producer;
20 |
21 | public KafkaPublisher(Producer producer) {
22 | this.producer = producer;
23 | }
24 |
25 | public void send(List kafkaMessages) throws Exception {
26 | // TODO: 9/29/16 压缩数据v0.2
27 | if (kafkaMessages == null || kafkaMessages.isEmpty()) {
28 | log.error("kafkaMessages is empty.");
29 | }
30 |
31 | for (KafkaMessage kafkaMessage : kafkaMessages) {
32 | if (StringUtils.isNotEmpty(kafkaMessage.getTopic()) ||
33 | StringUtils.isNotEmpty(kafkaMessage.getKey())) {
34 | ProducerRecord producerRecord = new ProducerRecord<>(kafkaMessage.getTopic(),
35 | kafkaMessage.getKey(),
36 | ProtobufSerde.toBinary(kafkaMessage.getSqlEntry()));
37 |
38 | send(producerRecord);
39 | }
40 |
41 | }
42 | }
43 |
44 | private void send(ProducerRecord record) throws Exception {
45 | // log.info("start send msg, topic:{}, key:{}.", record.topic(), record.key());
46 |
47 | int times = 0;
48 |
49 | while (true) {
50 | try {
51 | producer.send(record);
52 | return;
53 | } catch (Exception e) {
54 | times += 1;
55 | if (times > Constants.THREAD_RETRY_TIMES) {
56 | throw e;
57 | } else {
58 | try {
59 | Thread.sleep(Constants.THREAD_RETRY_INTERVAL);
60 | } catch (InterruptedException e1) {
61 | throw e1;
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/kafka/RecordPartitioner.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.kafka;
2 |
3 | import kafka.producer.Partitioner;
4 | import kafka.utils.VerifiableProperties;
5 |
6 | /**
7 | * Created by plin on 9/29/16.
8 | */
9 | public class RecordPartitioner implements Partitioner {
10 |
11 | public RecordPartitioner(VerifiableProperties verifiableProperties) {
12 | }
13 |
14 | @Override
15 | public int partition(Object key, int numPartitions) {
16 | try {
17 | int partitionNum = Integer.parseInt((String) key);
18 | return Math.abs(partitionNum % numPartitions);
19 | } catch (Exception e) {
20 | return Math.abs(key.hashCode() % numPartitions);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/serde/ProtobufSerde.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.serde;
2 |
3 | import com.google.protobuf.Message;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | /**
8 | * Created by plin on 10/20/16.
9 | */
10 | public class ProtobufSerde {
11 | public static final Logger log = LoggerFactory.getLogger(ProtobufSerde.class);
12 |
13 | public static byte[] toBinary(Message msg) {
14 | try {
15 | return msg.toByteArray();
16 | } catch (Exception e) {
17 | log.warn("Serialize protobuf to binary failed.", e);
18 | return null;
19 | }
20 | }
21 |
22 | public static T fromBinary(byte[] bytes, T obj) {
23 | try {
24 | Message message = obj.newBuilderForType().mergeFrom(bytes).buildPartial();
25 | return (T) message;
26 | } catch (Exception e) {
27 | log.warn("Deserialize protobuf from binary failed.", e);
28 | return null;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/utils/ConcurrentUtil.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.utils;
2 |
3 | import com.google.common.util.concurrent.ListeningExecutorService;
4 | import com.google.common.util.concurrent.MoreExecutors;
5 | import com.google.common.util.concurrent.ThreadFactoryBuilder;
6 |
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Executors;
9 | import java.util.concurrent.ScheduledExecutorService;
10 | import java.util.concurrent.ThreadFactory;
11 |
12 | public class ConcurrentUtil {
13 |
14 | private static Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
15 | public void uncaughtException(Thread t, Throwable e) {
16 | System.err.print("thread has an error!!!" + "thread:" + t.getName() + "." + e);
17 | }
18 | };
19 |
20 | public static ThreadFactory getNamedThreadFactory(String name) {
21 | return getNamedThreadFactory(name, false);
22 | }
23 |
24 | public static ThreadFactory getNamedThreadFactory(String name, boolean isDaemon) {
25 | ThreadFactoryBuilder builder = new ThreadFactoryBuilder();
26 | builder
27 | .setDaemon(isDaemon)
28 | .setNameFormat(name + "-thread-%d")
29 | .setUncaughtExceptionHandler(handler);
30 | return builder.build();
31 | }
32 |
33 | public static ListeningExecutorService getListeningExecutorService(
34 | int nThreads, ThreadFactory threadFactory) {
35 | ExecutorService es = Executors.newFixedThreadPool(nThreads, threadFactory);
36 | return getListeningExecutorService(es);
37 | }
38 |
39 | public static ListeningExecutorService getListeningExecutorService(
40 | ExecutorService executorService) {
41 | return MoreExecutors.listeningDecorator(executorService);
42 | }
43 |
44 | public static ScheduledExecutorService getScheduledExecutorService(int corePoolSize) {
45 | ThreadFactory threadFactory = getNamedThreadFactory("SCHEDULED");
46 | return getScheduledExecutorService(corePoolSize, threadFactory);
47 | }
48 |
49 | public static ScheduledExecutorService getScheduledExecutorService(
50 | int corePoolSize, ThreadFactory threadFactory) {
51 | return Executors.newScheduledThreadPool(corePoolSize, threadFactory);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/utils/ConfigLoader.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.utils;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.io.FileNotFoundException;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.util.Properties;
10 |
11 | /**
12 | * Created by plin on 10/8/16.
13 | */
14 | public class ConfigLoader {
15 | private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class);
16 | private InputStream inputStream;
17 | private Properties prop;
18 |
19 | public ConfigLoader(String propFileName) {
20 | prop = new Properties();
21 | try {
22 | inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
23 | if (inputStream != null) {
24 | prop.load(inputStream);
25 | } else {
26 | throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
27 | }
28 | } catch (IOException e) {
29 | log.error("Exception: " + e);
30 | } finally {
31 | if (inputStream != null) {
32 | try {
33 | inputStream.close();
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | }
39 | }
40 |
41 | public String getValue(String key) {
42 | if (prop.containsKey(key)) {
43 | return prop.getProperty(key);
44 | } else {
45 | return "";
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/utils/ReflectionUtil.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.utils;
2 |
3 | import java.lang.reflect.Constructor;
4 | import java.lang.reflect.Method;
5 |
6 | /**
7 | * Created by plin on 10/18/16.
8 | */
9 | public class ReflectionUtil {
10 |
11 | public static T newInstance(Class clazz, Object... constructorArgs) {
12 | if (clazz == null) {
13 | return null;
14 | }
15 |
16 | T result;
17 | int argLen = constructorArgs == null ? 0 : constructorArgs.length;
18 |
19 | Class>[] parameterTypes = new Class[argLen];
20 | for (int i = 0; i < argLen; i++) {
21 | parameterTypes[i] = constructorArgs[i].getClass();
22 | }
23 |
24 | Constructor constructor = null;
25 |
26 | try {
27 | constructor = clazz.getDeclaredConstructor(parameterTypes);
28 |
29 | if (!constructor.isAccessible()) {
30 | constructor.setAccessible(true);
31 | }
32 |
33 | result = constructor.newInstance(constructorArgs);
34 | } catch (Exception e) {
35 | throw new RuntimeException(e);
36 | }
37 |
38 | return result;
39 | }
40 |
41 | public static T invokeMethod(Object object, String methodName, Object... methodArgs) {
42 | if (object == null) {
43 | return null;
44 | }
45 |
46 | T result = null;
47 |
48 | Class> clazz = object.getClass();
49 |
50 | int argLen = methodArgs == null ? 0 : methodArgs.length;
51 |
52 | Class>[] methodTypes = new Class[argLen];
53 | for (int i = 0; i < argLen; i++) {
54 | methodTypes[i] = methodArgs[i].getClass();
55 | }
56 |
57 | try {
58 | Method method = clazz.getDeclaredMethod(methodName, methodTypes);
59 |
60 | if (method != null) {
61 | if (!method.isAccessible()) {
62 | method.setAccessible(true);
63 | }
64 |
65 | result = (T) method.invoke(object, methodArgs);
66 | }
67 | } catch (Exception e) {
68 | throw new RuntimeException(e);
69 | }
70 |
71 | return result;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/writer/AbstractWriter.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.writer;
2 |
3 | /**
4 | * Created by plin on 10/20/16.
5 | */
6 | public abstract class AbstractWriter {
7 | public abstract void close() throws Exception;
8 |
9 | protected void process(Writer writer) {
10 | writer.message();
11 | }
12 |
13 | protected interface Writer {
14 | void message();
15 | }
16 |
17 | protected interface WriterTransaction {
18 |
19 | void alter(T t);
20 |
21 | void create(T t);
22 |
23 | void put(F t);
24 |
25 | void del(F t);
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/common/src/main/java/com/abc/carrygo/common/zookeeper/ZkAddress.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.zookeeper;
2 |
3 | import com.google.common.base.Joiner;
4 |
5 | /**
6 | * Created by plin on 9/30/16.
7 | */
8 | public class ZkAddress {
9 | private static final Joiner PATH_JOINER = Joiner.on(":").skipNulls();
10 |
11 | private String zkIp;
12 | private String zkPort;
13 | private String zkDestination;
14 |
15 | // use spring conf
16 | public ZkAddress() {
17 | }
18 |
19 | public ZkAddress(String zkDestination, String zkIp, String zkPort) {
20 | this.zkDestination = zkDestination;
21 | this.zkIp = zkIp;
22 | this.zkPort = zkPort;
23 | }
24 |
25 | public String getZkIp() {
26 | return zkIp;
27 | }
28 |
29 | public void setZkIp(String zkIp) {
30 | this.zkIp = zkIp;
31 | }
32 |
33 | public String getZkPort() {
34 | return zkPort;
35 | }
36 |
37 | public void setZkPort(String zkPort) {
38 | this.zkPort = zkPort;
39 | }
40 |
41 | public String getZkServers() {
42 | return PATH_JOINER.join(zkIp, zkPort);
43 | }
44 |
45 | public String getZkDestination() {
46 | return zkDestination;
47 | }
48 |
49 | public void setZkDestination(String zkDestination) {
50 | this.zkDestination = zkDestination;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/common/src/test/java/com/abc/carrgo/common/utils/TestUtils.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrgo.common.utils;
2 |
3 | /**
4 | * Created by plin on 10/20/16.
5 | */
6 | public class TestUtils {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/install_protobuf.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 | wget https://github.com/google/protobuf/releases/download/v2.4.1/protobuf-2.4.1.tar.gz
4 | tar -xzvf protobuf-2.4.1.tar.gz
5 | cd protobuf-2.4.1 && ./configure --prefix=/usr && make && sudo make install
6 |
--------------------------------------------------------------------------------
/parser/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | carrygo
7 | com.abc.carrygo
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | carrygo.parser
14 | jar
15 |
16 |
17 |
18 |
19 | com.abc.carrygo
20 | carrygo.common
21 | 1.0-SNAPSHOT
22 |
23 |
24 |
25 | ch.qos.logback
26 | logback-classic
27 | runtime
28 |
29 |
30 |
31 | com.github.sgroschupf
32 | zkclient
33 |
34 |
35 |
36 | org.slf4j
37 | log4j-over-slf4j
38 |
39 |
40 |
41 | com.google.guava
42 | guava
43 |
44 |
45 |
46 |
47 | com.google.protobuf
48 | protobuf-java
49 | 2.4.1
50 |
51 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/AbstractEventFilter.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by plin on 9/20/16.
7 | */
8 | public abstract class AbstractEventFilter {
9 |
10 | protected List process(Event event) throws Exception {
11 | return event.parser();
12 | }
13 |
14 | protected interface Event {
15 | List parser() throws Exception;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/EventService.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser;
2 |
3 | import com.abc.carrygo.parser.common.util.EntryParser;
4 | import com.alibaba.otter.canal.client.CanalConnector;
5 | import com.alibaba.otter.canal.protocol.Message;
6 | import org.apache.log4j.MDC;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.util.Assert;
10 |
11 | /**
12 | * Created by plin on 9/19/16.
13 | */
14 | public class EventService {
15 |
16 | protected static final int BATCH_SIZE = 5 * 1024;
17 | private static final Logger log = LoggerFactory.getLogger(EventService.class);
18 | protected static Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
19 | public void uncaughtException(Thread t, Throwable e) {
20 | System.err.print("thread has an error!!!" + "thread:" + t.getName() + "." + e);
21 | }
22 | };
23 | protected volatile boolean running = false;
24 | protected CanalConnector connector;
25 | protected String destination;
26 | protected Thread thread = null;
27 |
28 | public EventService(String destination) {
29 | this(destination, null);
30 | }
31 |
32 | public EventService(String destination, CanalConnector connector) {
33 | this.destination = destination;
34 | this.connector = connector;
35 | }
36 |
37 | public void setConnector(CanalConnector connector) {
38 | this.connector = connector;
39 | }
40 |
41 | public void startParse() {
42 | Assert.notNull(connector, "connector is null");
43 |
44 | thread = new Thread(new Runnable() {
45 | @Override
46 | public void run() {
47 | process();
48 | }
49 | });
50 |
51 | thread.setUncaughtExceptionHandler(handler);
52 | thread.start();
53 |
54 | running = true;
55 | }
56 |
57 | public void stopParse() {
58 | if (!running) {
59 | return;
60 | }
61 | running = false;
62 |
63 | if (thread != null) {
64 | try {
65 | thread.join();
66 | } catch (InterruptedException e) {
67 | //
68 | log.warn("interrupt event client!");
69 | }
70 | }
71 |
72 | MDC.remove("destination");
73 | }
74 |
75 | public void process() {
76 | while (running) {
77 | try {
78 | MDC.put("destination", destination);
79 | //protobuf与canal中protobuf版本不一致会导致无法connect问题
80 | //启动服务时, 连接不稳定,待查canal是否存在问题
81 |
82 | log.info("start connect.");
83 | connector.connect();
84 |
85 | log.info("start subscribe.");
86 | connector.subscribe();
87 |
88 | log.info("start parse event.");
89 |
90 | while (running) {
91 | Message message = connector.getWithoutAck(BATCH_SIZE);
92 | long batchId = message.getId();
93 |
94 | parseAndPublish(message, batchId);
95 | }
96 | } catch (Exception e) {
97 | log.error("process error!", e);
98 | } finally {
99 | connector.disconnect();
100 | MDC.remove("destination");
101 | }
102 | }
103 | }
104 |
105 | protected void parseAndPublish(Message message, long batchId) {
106 | try {
107 | int size = message.getEntries().size();
108 | if (batchId == -1 || size == 0) {
109 | // log.debug("message is null");
110 | } else {
111 | // EntryParser.printSummary(message, batchId, size);
112 | // EntryParser.printTransaction(message.getEntries());
113 |
114 | EntryParser.parseRowData(message.getEntries(), null);
115 |
116 | // publish
117 | }
118 | connector.ack(batchId);
119 | } catch (Exception e) {
120 | log.error("rollback msg, batchId:{}", batchId, e);
121 | connector.rollback(batchId);
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/common/EventFeedManager.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.common;
2 |
3 | import com.abc.carrygo.common.Constants;
4 | import com.abc.carrygo.parser.common.entity.EventFeed;
5 |
6 | import java.util.concurrent.ArrayBlockingQueue;
7 | import java.util.concurrent.ConcurrentHashMap;
8 |
9 | /**
10 | * Created by plin on 10/19/16.
11 | */
12 | public class EventFeedManager {
13 | protected static volatile ConcurrentHashMap> blockingQueueMap;
14 |
15 | static {
16 | blockingQueueMap = new ConcurrentHashMap<>();
17 | }
18 |
19 | protected void add(String type, EventFeed eventFeed) throws InterruptedException {
20 | ArrayBlockingQueue queue = new ArrayBlockingQueue(Constants.CAPACITY);
21 | queue.put(eventFeed);
22 |
23 | blockingQueueMap.putIfAbsent(type, queue);
24 |
25 | ArrayBlockingQueue actualQueue = blockingQueueMap.get(type);
26 | if (actualQueue != queue) {
27 | actualQueue.put(eventFeed);
28 | }
29 |
30 | }
31 |
32 | protected ArrayBlockingQueue get(String type) {
33 | ArrayBlockingQueue blockingQueue = blockingQueueMap.get(type);
34 |
35 | return blockingQueue;
36 | }
37 |
38 | protected boolean isExists(String type) {
39 | return blockingQueueMap.containsKey(type);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/common/entity/Event.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.common.entity;
2 |
3 | import com.abc.carrygo.protocol.SQLEventEntry;
4 | import com.alibaba.otter.canal.protocol.CanalEntry;
5 |
6 |
7 | /**
8 | * Created by plin on 10/11/16.
9 | */
10 | public class Event {
11 | //ddl 执行的sql
12 | String sql;
13 |
14 | //dml 执行的数据
15 | CanalEntry.RowData rowData;
16 |
17 | String schemaName;
18 |
19 | String tableName;
20 |
21 | //DML/DDL
22 | SQLEventEntry.EntryType entryType;
23 |
24 | //create, delete, alter...
25 | CanalEntry.EventType eventType;
26 |
27 | public String getSchemaName() {
28 | return schemaName;
29 | }
30 |
31 | public void setSchemaName(String schemaName) {
32 | this.schemaName = schemaName;
33 | }
34 |
35 | public SQLEventEntry.EntryType getEntryType() {
36 | return entryType;
37 | }
38 |
39 | public void setEntryType(SQLEventEntry.EntryType entryType) {
40 | this.entryType = entryType;
41 | }
42 |
43 | public CanalEntry.EventType getEventType() {
44 | return eventType;
45 | }
46 |
47 | public void setEventType(CanalEntry.EventType eventType) {
48 | this.eventType = eventType;
49 | }
50 |
51 | public String getTableName() {
52 | return tableName;
53 | }
54 |
55 | public void setTableName(String tableName) {
56 | this.tableName = tableName;
57 | }
58 |
59 | public CanalEntry.RowData getRowData() {
60 | return rowData;
61 | }
62 |
63 | public void setRowData(CanalEntry.RowData rowData) {
64 | this.rowData = rowData;
65 | }
66 |
67 | public String getSql() {
68 | return sql;
69 | }
70 |
71 | public void setSql(String sql) {
72 | this.sql = sql;
73 | }
74 | }
75 |
76 |
77 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/common/entity/EventFeed.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.common.entity;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by plin on 10/12/16.
7 | */
8 | public class EventFeed {
9 |
10 | public final long batchId;
11 | public final List event;
12 |
13 | public EventFeed(long batchId, List event) {
14 | this.batchId = batchId;
15 | this.event = event;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/common/util/DataLock.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.common.util;
2 |
3 | /**
4 | * Created by plin on 10/11/16.
5 | */
6 | public class DataLock {
7 |
8 | public static final Object writeDataLock = new Object();
9 |
10 | public static final Object readDataLock = new Object();
11 | }
12 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/common/util/EntryParser.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.common.util;
2 |
3 | import com.abc.carrygo.parser.common.entity.Event;
4 | import com.abc.carrygo.protocol.SQLEventEntry.EntryType;
5 | import com.alibaba.otter.canal.protocol.CanalEntry;
6 | import com.alibaba.otter.canal.protocol.Message;
7 | import com.google.protobuf.InvalidProtocolBufferException;
8 | import org.apache.commons.lang.SystemUtils;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.util.CollectionUtils;
12 |
13 | import java.text.SimpleDateFormat;
14 | import java.util.*;
15 |
16 | /**
17 | * Created by plin on 9/20/16.
18 | */
19 | public class EntryParser {
20 | protected static final String SEP = SystemUtils.LINE_SEPARATOR;
21 | protected static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
22 | private static final Logger log = LoggerFactory.getLogger(EntryParser.class);
23 |
24 | private static String context_format = null;
25 | private static String row_format = null;
26 | private static String transaction_format = null;
27 |
28 | static {
29 | context_format = SEP + "****************************************************" + SEP;
30 | context_format += "* Batch Id: [{}] ,count : [{}] , memsize : [{}] , Time : {}" + SEP;
31 | context_format += "* Start : [{}] " + SEP;
32 | context_format += "* End : [{}] " + SEP;
33 | context_format += "****************************************************" + SEP;
34 | row_format = SEP
35 | + "----------------> binlog[{}:{}] , name[{},{}] , eventType : {} , executeTime : {} , delay : {}ms"
36 | + SEP;
37 | transaction_format = SEP + "================> binlog[{}:{}] , executeTime : {} , delay : {}ms" + SEP;
38 | }
39 |
40 | public static void printSummary(Message message, long batchId, int size) {
41 | long memorySize = 0;
42 | for (CanalEntry.Entry entry : message.getEntries()) {
43 | memorySize += entry.getHeader().getEventLength();
44 | }
45 |
46 | String startPosition = null;
47 | String endPosition = null;
48 | if (!CollectionUtils.isEmpty(message.getEntries())) {
49 | startPosition = buildPositionForDump(message.getEntries().get(0));
50 | endPosition = buildPositionForDump(message.getEntries().get(message.getEntries().size() - 1));
51 | }
52 |
53 | SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
54 | log.info(context_format, batchId, size, memorySize, format.format(new Date()), startPosition,
55 | endPosition);
56 | }
57 |
58 | private static String buildPositionForDump(CanalEntry.Entry entry) {
59 | long time = entry.getHeader().getExecuteTime();
60 | Date date = new Date(time);
61 | SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
62 | return entry.getHeader().getLogfileName() + ":" + entry.getHeader().getLogfileOffset() + ":"
63 | + entry.getHeader().getExecuteTime() + "(" + format.format(date) + ")";
64 | }
65 |
66 | public static void printTransaction(List entrys) {
67 | for (CanalEntry.Entry entry : entrys) {
68 | long executeTime = entry.getHeader().getExecuteTime();
69 | long delayTime = new Date().getTime() - executeTime;
70 |
71 | if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN
72 | || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {
73 | if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN) {
74 | CanalEntry.TransactionBegin begin = null;
75 | try {
76 | begin = CanalEntry.TransactionBegin.parseFrom(entry.getStoreValue());
77 | } catch (InvalidProtocolBufferException e) {
78 | throw new RuntimeException("parse event has an error , data:" + entry.toString(), e);
79 | }
80 | // 打印事务头信息,执行的线程id,事务耗时
81 | log.info(transaction_format,
82 | entry.getHeader().getLogfileName(),
83 | String.valueOf(entry.getHeader().getLogfileOffset()),
84 | String.valueOf(entry.getHeader().getExecuteTime()), String.valueOf(delayTime));
85 | log.info(" BEGIN ----> Thread id: {}", begin.getThreadId());
86 | } else if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {
87 | CanalEntry.TransactionEnd end = null;
88 | try {
89 | end = CanalEntry.TransactionEnd.parseFrom(entry.getStoreValue());
90 | } catch (InvalidProtocolBufferException e) {
91 | throw new RuntimeException("parse event has an error , data:" + entry.toString(), e);
92 | }
93 | // 打印事务提交信息,事务id
94 | log.info("----------------\n");
95 | log.info(" END ----> transaction id: {}", end.getTransactionId());
96 | log.info(transaction_format,
97 | entry.getHeader().getLogfileName(),
98 | String.valueOf(entry.getHeader().getLogfileOffset()),
99 | String.valueOf(entry.getHeader().getExecuteTime()), String.valueOf(delayTime));
100 | }
101 | }
102 | }
103 | }
104 |
105 | public static Map> parseRowData(List entries, List schemas) throws InterruptedException {
106 | Map> eventSchemaFeeds = new HashMap<>();
107 |
108 | for (CanalEntry.Entry entry : entries) {
109 |
110 | if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) {
111 | CanalEntry.RowChange rowChange = null;
112 | try {
113 | rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
114 | } catch (Exception e) {
115 | throw new RuntimeException("parse event has an error , data:" + entry.toString(), e);
116 | }
117 |
118 | CanalEntry.EventType eventType = rowChange.getEventType();
119 |
120 | // log.info(row_format,
121 | // entry.getHeader().getLogfileName(),
122 | // String.valueOf(entry.getHeader().getLogfileOffset()), entry.getHeader().getSchemaName(),
123 | // entry.getHeader().getTableName(), eventType,
124 | // String.valueOf(entry.getHeader().getExecuteTime()), String.valueOf(""));
125 |
126 | if (eventType == CanalEntry.EventType.QUERY) {
127 | continue;
128 | }
129 |
130 | String schema = entry.getHeader().getSchemaName();
131 | if (schemas != null && !schemas.isEmpty() && !schemas.contains(schema)) {
132 | continue;
133 | }
134 |
135 |
136 | String table = entry.getHeader().getTableName();
137 |
138 | List events;
139 |
140 |
141 | if (eventSchemaFeeds.containsKey(schema)) {
142 | events = eventSchemaFeeds.get(schema);
143 | } else {
144 | events = new ArrayList<>();
145 | }
146 |
147 | if (rowChange.getIsDdl()) {
148 | Event event = new Event();
149 | event.setEntryType(EntryType.DDL);
150 | event.setSql(rowChange.getSql());
151 | event.setEventType(eventType);
152 | event.setTableName(table);
153 | event.setSchemaName(schema);
154 |
155 | events.add(event);
156 |
157 | synchronized (DataLock.writeDataLock) {
158 | eventSchemaFeeds.put(schema, events);
159 | }
160 | }
161 |
162 | for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
163 | Event event = new Event();
164 | event.setEntryType(EntryType.DML);
165 | event.setRowData(rowData);
166 | event.setEventType(eventType);
167 | event.setTableName(table);
168 | event.setSchemaName(schema);
169 |
170 | events.add(event);
171 |
172 | synchronized (DataLock.writeDataLock) {
173 | eventSchemaFeeds.put(schema, events);
174 | }
175 | }
176 | }
177 | }
178 |
179 | return eventSchemaFeeds;
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/PublishCount.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | /**
6 | * Created by plin on 10/12/16.
7 | */
8 | public class PublishCount {
9 | private static volatile AtomicLong id = new AtomicLong(0);
10 |
11 | public synchronized static void put(long batchId) {
12 | if (id.get() == 0) {
13 | id.set(batchId);
14 | }
15 | }
16 |
17 | public static void set(long batchId) {
18 | id.set(batchId);
19 | }
20 |
21 | public static long get() {
22 | return id.get();
23 | }
24 |
25 | public static boolean check() {
26 | if (PublishCount.get() != 0) {
27 | return Boolean.TRUE;
28 | }
29 |
30 | return Boolean.FALSE;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/feed/KafkaFeed.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.feed;
2 |
3 | import com.abc.carrygo.parser.common.entity.Event;
4 | import com.abc.carrygo.parser.common.entity.EventFeed;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by plin on 10/19/16.
10 | */
11 | public class KafkaFeed extends EventFeed {
12 | public final String topic;
13 |
14 | public KafkaFeed(long batchId,
15 | String topic,
16 | List events) {
17 | super(batchId, events);
18 |
19 | this.topic = topic;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/feed/KafkaFeedTask.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.feed;
2 |
3 |
4 | import com.abc.carrygo.common.Constants;
5 | import com.abc.carrygo.parser.kafka.manager.KafkaFeedManager;
6 | import com.abc.carrygo.parser.kafka.service.KafkaEventHandler;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | * Created by plin on 10/19/16.
12 | */
13 | public class KafkaFeedTask implements Runnable {
14 | private static final Logger log = LoggerFactory.getLogger(KafkaFeedTask.class);
15 |
16 | private KafkaEventHandler handler;
17 | private KafkaFeedManager feedManager;
18 | private String topic;
19 |
20 | public KafkaFeedTask(String topic) {
21 | this.topic = topic;
22 | }
23 |
24 | @Override
25 | public void run() {
26 | while (true) {
27 | try {
28 |
29 | KafkaFeed event = feedManager.getEventFeed(topic);
30 |
31 | if (event != null) {
32 | handler.extractAndPublish(event);
33 | } else {
34 | Thread.sleep(Constants.THREAD_RETRY_INTERVAL);
35 | }
36 |
37 | } catch (Exception e) {
38 | log.error("publish failed.", e);
39 | }
40 | }
41 | }
42 |
43 | public void setFeedManager(KafkaFeedManager feedManager) {
44 | this.feedManager = feedManager;
45 | }
46 |
47 | public void setHandler(KafkaEventHandler handler) {
48 | this.handler = handler;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/manager/KafkaFeedManager.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.manager;
2 |
3 | import com.abc.carrygo.parser.common.EventFeedManager;
4 | import com.abc.carrygo.parser.kafka.PublishCount;
5 | import com.abc.carrygo.parser.kafka.feed.KafkaFeed;
6 |
7 | import java.util.concurrent.ArrayBlockingQueue;
8 |
9 | /**
10 | * Created by plin on 10/19/16.
11 | */
12 | public class KafkaFeedManager extends EventFeedManager {
13 |
14 | public void fill(KafkaFeed feed) throws InterruptedException {
15 | try {
16 |
17 | add(feed.topic, feed);
18 |
19 | //Record the batchId
20 | PublishCount.put(feed.batchId);
21 | } catch (Exception e) {
22 | throw e;
23 | }
24 | }
25 |
26 | public KafkaFeed getEventFeed(String schema) {
27 | ArrayBlockingQueue eventMessages = get(schema);
28 | if (eventMessages == null || eventMessages.isEmpty()) {
29 | return null;
30 | }
31 |
32 | KafkaFeed eventFeed = (KafkaFeed) eventMessages.poll();
33 | if (eventFeed == null) {
34 | return null;
35 | }
36 |
37 | PublishCount.set(eventFeed.batchId);
38 |
39 | return eventFeed;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/mysql/MySQLDDLEvent.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.mysql;
2 |
3 | import com.abc.carrygo.protocol.SQLEventEntry.DDLEntry;
4 | import com.abc.carrygo.protocol.SQLEventEntry.KeyWord;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.List;
9 |
10 | import static com.abc.carrygo.parser.common.util.ParserUtil.statementParser;
11 |
12 |
13 | /**
14 | * Created by plin on 9/26/16.
15 | */
16 | public class MySQLDDLEvent {
17 |
18 | private static final Logger log = LoggerFactory.getLogger(MySQLDDLEvent.class);
19 |
20 |
21 | //DDL:创建表结构, 新增add, modify(改变表的类型,暂不考虑), 修改change或者删除drop列.
22 | public static List filter(final String schemaName,
23 | final String tableName,
24 | final String sql,
25 | final KeyWord keyWord) {
26 | List ddlEntries = statementParser(schemaName, tableName, keyWord, sql);
27 |
28 | log.debug("parser ddlOperas:{}", ddlEntries);
29 |
30 | return ddlEntries;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/mysql/MySQLDMLEvent.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.mysql;
2 |
3 | import com.abc.carrygo.protocol.SQLEventEntry.DMLEntry;
4 | import com.abc.carrygo.protocol.SQLEventEntry.KeyWord;
5 | import com.alibaba.otter.canal.protocol.CanalEntry;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.List;
10 |
11 | import static com.abc.carrygo.parser.common.util.ParserUtil.columnFilter;
12 |
13 |
14 | /**
15 | * Created by plin on 9/26/16.
16 | */
17 | public class MySQLDMLEvent {
18 |
19 | private static final Logger log = LoggerFactory.getLogger(MySQLDMLEvent.class);
20 |
21 | public static DMLEntry filter(final String schemaName,
22 | final String tableName,
23 | List columns,
24 | final KeyWord keyWord) {
25 | return columnFilter(schemaName, tableName, keyWord, columns);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/parse/KafkaEntryParser.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.parse;
2 |
3 | import com.abc.carrygo.parser.common.util.EntryParser;
4 | import com.abc.carrygo.protocol.SQLEventEntry.DDLEntry;
5 | import com.abc.carrygo.protocol.SQLEventEntry.DMLEntry;
6 | import com.abc.carrygo.protocol.SQLEventEntry.KeyWord;
7 | import com.alibaba.otter.canal.protocol.CanalEntry;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Created by plin on 10/11/16.
15 | */
16 | public class KafkaEntryParser extends EntryParser {
17 | private static final Logger log = LoggerFactory.getLogger(KafkaEntryParser.class);
18 | private static final KafkaEventFilter filter = new KafkaEventFilter();
19 |
20 | public static List parse(String schemaName,
21 | String tableName,
22 | String sql,
23 | CanalEntry.EventType eventType) throws Exception {
24 | List ddlEntries = null;
25 | switch (eventType) {
26 | case CREATE:
27 | ddlEntries = filter.filter(schemaName, tableName, sql, KeyWord.CREATE);
28 | break;
29 | case ALTER:
30 | ddlEntries = filter.filter(schemaName, tableName, sql, KeyWord.ALTER);
31 | break;
32 | default:
33 | //ignore
34 | log.info("parse entry sql, sql:{}", sql);
35 | }
36 |
37 | return ddlEntries;
38 | }
39 |
40 | public static List parse(String schemaName,
41 | String tableName,
42 | CanalEntry.RowData rowData,
43 | CanalEntry.EventType eventType) throws Exception {
44 | List dmlEntries = null;
45 | switch (eventType) {
46 | case DELETE:
47 | dmlEntries = filter.filter(schemaName,
48 | tableName,
49 | rowData.getBeforeColumnsList(),
50 | KeyWord.DELETE);
51 | break;
52 | case INSERT:
53 | dmlEntries = filter.filter(schemaName,
54 | tableName,
55 | rowData.getAfterColumnsList(),
56 | KeyWord.INSERT);
57 | break;
58 | case UPDATE:
59 | dmlEntries = filter.filter(schemaName,
60 | tableName,
61 | rowData.getAfterColumnsList(),
62 | KeyWord.UPDATE);
63 | break;
64 | default:
65 | //ignore
66 | log.info("parse entry row data, rowData:{}", rowData);
67 | }
68 |
69 | return dmlEntries;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/parse/KafkaEventFilter.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.parse;
2 |
3 | import com.abc.carrygo.parser.AbstractEventFilter;
4 | import com.abc.carrygo.parser.kafka.mysql.MySQLDDLEvent;
5 | import com.abc.carrygo.parser.kafka.mysql.MySQLDMLEvent;
6 | import com.abc.carrygo.protocol.SQLEventEntry.DDLEntry;
7 | import com.abc.carrygo.protocol.SQLEventEntry.DMLEntry;
8 | import com.abc.carrygo.protocol.SQLEventEntry.KeyWord;
9 | import com.alibaba.otter.canal.protocol.CanalEntry;
10 |
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | /**
15 | * Created by plin on 9/26/16.
16 | */
17 | public class KafkaEventFilter extends AbstractEventFilter {
18 |
19 | public List filter(final String schemaName,
20 | final String tableName,
21 | final String sql,
22 | final KeyWord keyWord) throws Exception {
23 | return process(new Event() {
24 | @Override
25 | public List parser() throws Exception {
26 | return MySQLDDLEvent.filter(schemaName, tableName, sql, keyWord);
27 | }
28 | });
29 | }
30 |
31 | public List filter(final String schemaName,
32 | final String tableName,
33 | final List columns,
34 | final KeyWord keyWord) throws Exception {
35 | return process(new Event() {
36 | @Override
37 | public List parser() throws Exception {
38 | DMLEntry entry = MySQLDMLEvent.filter(schemaName, tableName, columns, keyWord);
39 | return Arrays.asList(entry);
40 | }
41 | });
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/service/KafkaEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.service;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaMessage;
4 | import com.abc.carrygo.common.kafka.KafkaPublisher;
5 | import com.abc.carrygo.parser.common.entity.Event;
6 | import com.abc.carrygo.parser.kafka.feed.KafkaFeed;
7 | import com.abc.carrygo.parser.kafka.parse.KafkaEntryParser;
8 | import com.abc.carrygo.protocol.SQLEventEntry.DDLEntry;
9 | import com.abc.carrygo.protocol.SQLEventEntry.DMLEntry;
10 | import com.abc.carrygo.protocol.SQLEventEntry.SQLEntry;
11 | import org.apache.kafka.clients.producer.Producer;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * Created by plin on 10/11/16.
20 | */
21 | public class KafkaEventHandler {
22 | private static final Logger log = LoggerFactory.getLogger(KafkaEventHandler.class);
23 |
24 | private final KafkaPublisher kafkaPublisher;
25 | private final Producer producer;
26 |
27 | public KafkaEventHandler(Producer producer) {
28 | this.producer = producer;
29 | this.kafkaPublisher = new KafkaPublisher(producer);
30 | }
31 |
32 | public void release() {
33 | producer.close();
34 | }
35 |
36 |
37 | public void extractAndPublish(KafkaFeed feed) throws Exception {
38 | log.info("extractAndPublish, topic:{}, batchId:{}", feed.topic, feed.batchId);
39 |
40 | List kafkaMessages = new ArrayList<>();
41 |
42 | try {
43 | extract(feed.topic, feed.event, kafkaMessages);
44 |
45 | kafkaPublisher.send(kafkaMessages);
46 | } catch (Exception e) {
47 | log.error("extractAndPublish failed.", e);
48 |
49 | throw e;
50 | }
51 |
52 | }
53 |
54 | private void extract(String schema, List events, List kafkaMessages) throws Exception {
55 |
56 | for (Event event : events) {
57 | SQLEntry.Builder sqlEntry = SQLEntry.newBuilder();
58 |
59 | switch (event.getEntryType()) {
60 | case DDL:
61 | List ddlEntries = KafkaEntryParser.parse(schema,
62 | event.getTableName(),
63 | event.getSql(),
64 | event.getEventType());
65 |
66 | if (ddlEntries != null) {
67 | sqlEntry.addAllDdlEntries(ddlEntries);
68 | sqlEntry.setEntry(event.getEntryType());
69 | }
70 |
71 | break;
72 | case DML:
73 | List dmlEntries = KafkaEntryParser.parse(schema,
74 | event.getTableName(),
75 | event.getRowData(),
76 | event.getEventType());
77 |
78 | if (dmlEntries != null) {
79 | sqlEntry.addAllDmlEntries(dmlEntries);
80 | sqlEntry.setEntry(event.getEntryType());
81 | }
82 |
83 | break;
84 | default:
85 | //ignore
86 | }
87 |
88 | if (sqlEntry.hasEntry()) {
89 | String key = schema + event.getEntryType();
90 | kafkaMessages.add(new KafkaMessage(schema, key, sqlEntry.build()));
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/service/KafkaEventService.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.service;
2 |
3 | import com.abc.carrygo.common.factory.ListeningExecutorFactory;
4 | import com.abc.carrygo.common.kafka.KafkaAddress;
5 | import com.abc.carrygo.common.kafka.KafkaConnectors;
6 | import com.abc.carrygo.parser.EventService;
7 | import com.abc.carrygo.parser.common.entity.Event;
8 | import com.abc.carrygo.parser.kafka.PublishCount;
9 | import com.abc.carrygo.parser.kafka.manager.KafkaFeedManager;
10 | import com.abc.carrygo.parser.kafka.parse.KafkaEntryParser;
11 | import com.alibaba.otter.canal.client.CanalConnectors;
12 | import com.alibaba.otter.canal.protocol.Message;
13 | import com.google.common.base.Splitter;
14 | import com.google.common.util.concurrent.FutureCallback;
15 | import com.google.common.util.concurrent.Futures;
16 | import com.google.common.util.concurrent.ListenableFuture;
17 | import org.apache.kafka.clients.producer.Producer;
18 | import org.slf4j.Logger;
19 | import org.slf4j.LoggerFactory;
20 |
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.concurrent.Callable;
24 | import java.util.concurrent.CountDownLatch;
25 |
26 |
27 | public class KafkaEventService extends EventService {
28 | private static final Logger log = LoggerFactory.getLogger(KafkaEventService.class);
29 | private static final Splitter SPLITTER = Splitter.on(",").omitEmptyStrings();
30 | private static final String PUBLISH_EXECUTOR_WORK_NAME = "PUBLISH-WORK";
31 | private static final String PUBLISH_EXECUTOR_LISTENER_NAME = "PUBLISH-LISTENER";
32 | private static final int EXECUTOR_NUM_THREAD = 1;
33 | private static int default_threads;
34 | private static CountDownLatch latch = new CountDownLatch(1);
35 | private volatile boolean publish_running = false;
36 | private KafkaFeedProcessor processor;
37 | private ListeningExecutorFactory service;
38 | private List topics;
39 |
40 | public KafkaEventService(String servers,
41 | String destination,
42 | KafkaAddress kafkaAddress,
43 | String kafkaTopic) {
44 | super(destination, CanalConnectors.newClusterConnector(
45 | servers,
46 | destination,
47 | "",
48 | ""));
49 |
50 | init(kafkaAddress, kafkaTopic);
51 | }
52 |
53 | public void init(KafkaAddress kafkaAddress, String kafkaTopic) {
54 | this.topics = SPLITTER.splitToList(kafkaTopic);
55 |
56 |
57 | default_threads = Math.max(topics.size(),
58 | Runtime.getRuntime().availableProcessors() * 2);
59 |
60 | Producer producer = KafkaConnectors.newProducer(kafkaAddress);
61 | KafkaEventHandler eventHandler = new KafkaEventHandler(producer);
62 |
63 | KafkaFeedProcessorBuilder builder = new KafkaFeedProcessorBuilder();
64 | builder
65 | .setEventHandler(eventHandler)
66 | .setFeedManager(new KafkaFeedManager())
67 | .setEventFactory(new KafkaFeedProcessor(topics))
68 | .setListeningExecutorFactory(new ListeningExecutorFactory(default_threads, PUBLISH_EXECUTOR_WORK_NAME));
69 | processor = builder.build(topics);
70 | }
71 |
72 | public void startPublish() {
73 | service = new ListeningExecutorFactory(EXECUTOR_NUM_THREAD, PUBLISH_EXECUTOR_LISTENER_NAME);
74 | final ListenableFuture future = service.submit(new Callable() {
75 | @Override
76 | public Boolean call() throws Exception {
77 | boolean flag = false;
78 |
79 | // do {
80 | // flag = PublishCount.check();
81 | //
82 | // } while (!flag);
83 |
84 | if (!flag) {
85 | latch.await();
86 | }
87 |
88 | publish_running = true;
89 |
90 | return Boolean.valueOf(publish_running);
91 | }
92 | });
93 |
94 | Futures.addCallback(future, new FutureCallback() {
95 | @Override
96 | public void onSuccess(Object result) {
97 | Boolean b = (Boolean) result;
98 | if (b.booleanValue()) {
99 | processor.start();
100 | } else {
101 | throw new RuntimeException(new Throwable("Publish failed."));
102 | }
103 |
104 | service.shutdown();
105 | }
106 |
107 | public void onFailure(Throwable thrown) {
108 | throw new RuntimeException(thrown);
109 | }
110 | });
111 | }
112 |
113 |
114 | public void stopPublish() {
115 | if (!publish_running) {
116 | return;
117 | }
118 | publish_running = false;
119 |
120 | processor.stop();
121 | }
122 |
123 |
124 | protected void parseAndPublish(Message message, long batchId) {
125 | try {
126 | int size = message.getEntries().size();
127 | if (batchId != -1 && size != 0) {
128 | log.info("parseAndPublish, batchId:{}", batchId);
129 |
130 | Map> eventFeedMaps = KafkaEntryParser.parseRowData(
131 | message.getEntries(),
132 | topics);
133 |
134 | // parse event && put event to queue
135 | processor.extract(batchId, eventFeedMaps);
136 |
137 | if (PublishCount.check() && !publish_running) {
138 | latch.countDown();
139 | }
140 | }
141 |
142 | connector.ack(batchId);
143 | } catch (Exception e) {
144 | long publishBatchId = PublishCount.get();
145 | if (publishBatchId < batchId) {
146 | log.error("origin batchId:{}", batchId);
147 |
148 | batchId = publishBatchId;
149 | }
150 |
151 | log.error("rollback msg, batchId:{}", batchId, e);
152 | connector.rollback(batchId);
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/service/KafkaFeedProcessor.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.service;
2 |
3 | import com.abc.carrygo.common.factory.ListeningExecutorFactory;
4 | import com.abc.carrygo.parser.common.entity.Event;
5 | import com.abc.carrygo.parser.kafka.feed.KafkaFeed;
6 | import com.abc.carrygo.parser.kafka.feed.KafkaFeedTask;
7 | import com.abc.carrygo.parser.kafka.manager.KafkaFeedManager;
8 | import org.apache.commons.lang3.StringUtils;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | /**
16 | * Created by plin on 10/19/16.
17 | */
18 | public class KafkaFeedProcessor {
19 | private static final Logger log = LoggerFactory.getLogger(KafkaFeedProcessor.class);
20 |
21 | public List topics;
22 | private ListeningExecutorFactory executor;
23 | private KafkaEventHandler handler;
24 | private KafkaFeedManager feedMgr;
25 |
26 | public KafkaFeedProcessor(List topics) {
27 | this.topics = topics;
28 | }
29 |
30 | public void extract(long batchId, Map> eventMaps) throws InterruptedException {
31 | for (String topic : eventMaps.keySet()) {
32 |
33 | if (StringUtils.isNotEmpty(topic) && topics.contains(topic)) {
34 | KafkaFeed eventFeed = new KafkaFeed(batchId,
35 | topic,
36 | eventMaps.get(topic));
37 |
38 | log.info("extract, batchId:{}", batchId);
39 |
40 | // TODO: 10/24/16 a topic -> a thread
41 | feedMgr.fill(eventFeed);
42 |
43 | } else {
44 | return;
45 | }
46 |
47 | }
48 | }
49 |
50 |
51 | public void start() {
52 |
53 | for (Object topic : topics) {
54 | log.info("start process task, topic:{}", topic);
55 |
56 | KafkaFeedTask task = new KafkaFeedTask((String) topic);
57 | task.setFeedManager(feedMgr);
58 | task.setHandler(handler);
59 |
60 | executor.execute(task);
61 | }
62 | }
63 |
64 |
65 | public void stop() {
66 |
67 |
68 | try {
69 | executor.shutdown();
70 | } catch (Exception e) {
71 | log.error("stop error.", e);
72 |
73 | executor.shutdownNow();
74 | Thread.currentThread().interrupt();
75 | } finally {
76 | handler.release();
77 | }
78 | }
79 |
80 |
81 | public void setFeedManager(KafkaFeedManager feedMgr) {
82 | this.feedMgr = feedMgr;
83 | }
84 |
85 | public void setHandler(KafkaEventHandler handler) {
86 | this.handler = handler;
87 | }
88 |
89 | public void setExecutorFactory(ListeningExecutorFactory executor) {
90 | this.executor = executor;
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/kafka/service/KafkaFeedProcessorBuilder.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.kafka.service;
2 |
3 | import com.abc.carrygo.common.factory.ListeningExecutorFactory;
4 | import com.abc.carrygo.parser.kafka.manager.KafkaFeedManager;
5 | import org.springframework.util.Assert;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by plin on 10/19/16.
11 | */
12 | public final class KafkaFeedProcessorBuilder {
13 |
14 | private KafkaFeedManager feedManager = null;
15 | private ListeningExecutorFactory listeningExecutorFactory = null;
16 | private KafkaEventHandler eventHandler = null;
17 | private KafkaFeedProcessor processor = null;
18 |
19 | public KafkaFeedProcessorBuilder() {
20 | }
21 |
22 | private static KafkaFeedProcessor build(KafkaFeedProcessorBuilder builder, List topics) {
23 | final KafkaEventHandler eventHandler = builder.eventHandler;
24 | final ListeningExecutorFactory listeningExecutorFactory = builder.listeningExecutorFactory;
25 | final KafkaFeedManager feedManager = builder.feedManager;
26 |
27 | final KafkaFeedProcessor processor =
28 | (builder.processor != null)
29 | ? builder.processor
30 | : new KafkaFeedProcessor(topics);
31 |
32 | processor.setHandler(eventHandler);
33 | processor.setFeedManager(feedManager);
34 | processor.setExecutorFactory(listeningExecutorFactory);
35 |
36 | return processor;
37 | }
38 |
39 | public KafkaFeedProcessorBuilder setFeedManager(KafkaFeedManager feedManager) {
40 | Assert.notNull(feedManager);
41 |
42 | this.feedManager = feedManager;
43 |
44 | return this;
45 | }
46 |
47 | public KafkaFeedProcessorBuilder setListeningExecutorFactory(ListeningExecutorFactory listeningExecutorFactory) {
48 | Assert.notNull(listeningExecutorFactory);
49 |
50 | this.listeningExecutorFactory = listeningExecutorFactory;
51 |
52 | return this;
53 | }
54 |
55 | public KafkaFeedProcessorBuilder setEventFactory(KafkaFeedProcessor processor) {
56 | Assert.notNull(processor);
57 |
58 | this.processor = processor;
59 |
60 | return this;
61 | }
62 |
63 | public KafkaFeedProcessorBuilder setEventHandler(KafkaEventHandler eventHandler) {
64 | Assert.notNull(eventHandler);
65 |
66 | this.eventHandler = eventHandler;
67 |
68 | return this;
69 | }
70 |
71 | public KafkaFeedProcessor build(List topics) {
72 | return build(this, topics);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/parser/src/main/java/com/abc/carrygo/parser/server/CarryServer.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.parser.server;
2 |
3 | import com.abc.carrygo.common.conf.Configured;
4 | import com.abc.carrygo.common.kafka.KafkaAddress;
5 | import com.abc.carrygo.common.zookeeper.ZkAddress;
6 | import com.abc.carrygo.parser.kafka.service.KafkaEventService;
7 | import org.apache.commons.lang.exception.ExceptionUtils;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | * Created by plin on 9/30/16.
13 | */
14 | public class CarryServer {
15 | private static final Logger log = LoggerFactory.getLogger(CarryServer.class);
16 | private static ZkAddress zkAddress;
17 | private static KafkaAddress kafkaAddress;
18 | private KafkaEventService service;
19 |
20 | @SuppressWarnings("resource")
21 | public static void main(String[] args) {
22 | // ZkAddress zkAddress = SpringConf.zkAddress;
23 | // KafkaAddress kafkaAddress = SpringConf.kafkaAddress;
24 |
25 | zkAddress = Configured.zkAddress;
26 | kafkaAddress = Configured.kafkaAddress;
27 |
28 | final CarryServer server = new CarryServer();
29 | server.start();
30 |
31 | Runtime.getRuntime().addShutdownHook(new Thread() {
32 |
33 | public void run() {
34 | try {
35 |
36 | server.stop();
37 |
38 | } catch (Throwable e) {
39 | log.warn("something goes wrong when stopping carry server:\n{}", ExceptionUtils.getFullStackTrace(e));
40 | } finally {
41 | log.info("carry server is down.");
42 | }
43 | }
44 |
45 | });
46 | }
47 |
48 | public void start() {
49 | log.info("start the carry server");
50 |
51 | service = new KafkaEventService(
52 | zkAddress.getZkServers(),
53 | zkAddress.getZkDestination(),
54 | kafkaAddress,
55 | Configured.kafkaTopic);
56 |
57 | service.startParse();
58 | service.startPublish();
59 | }
60 |
61 | public void stop() {
62 | log.info("stop the carry server");
63 |
64 | service.stopParse();
65 | service.stopPublish();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/parser/src/main/resources/carrygo-conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 | classpath:carrygo.properties
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/parser/src/main/resources/carrygo.properties:
--------------------------------------------------------------------------------
1 | [kafka]
2 | kafka.ip = 127.0.0.1
3 | kafka.port = 9092
4 | kafka.topic = test
5 |
6 | [zookeeper]
7 | zookeeper.destination = example
8 | zookeeper.ip = 127.0.0.1
9 | zookeeper.port = 2181
10 |
11 |
--------------------------------------------------------------------------------
/parser/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | log
6 |
7 |
9 | log.%d{yyyy-MM-dd}.%i
10 |
11 |
12 | 500MB
13 |
14 |
15 | 3
16 |
17 |
18 |
19 | UTF-8
20 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/protocol/carrgo.protocol.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/protocol/carrygo.protocol.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/protocol/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | carrygo
7 | com.abc.carrygo
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | carrygo.protocol
14 | jar
15 |
16 |
17 |
18 | com.google.protobuf
19 | protobuf-java
20 |
21 |
22 |
23 |
24 |
25 |
26 | org.xolstice.maven.plugins
27 | protobuf-maven-plugin
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/protocol/src/main/proto/SQLProtocol.proto:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.common.protocol;
2 |
3 | option java_package = "com.abc.carrygo.protocol";
4 |
5 | option java_outer_classname = "SQLEventEntry";
6 |
7 | option optimize_for = SPEED;
8 |
9 | message SQLEntry {
10 | required EntryType entry = 1;
11 | repeated DMLEntry dmlEntries = 2;
12 | repeated DDLEntry ddlEntries = 3;
13 | }
14 |
15 | message DDLEntry {
16 | required string db = 1;
17 | required string table = 2;
18 | required KeyWord keyword = 3;
19 | repeated DDLCol ddlCols = 4;
20 | }
21 |
22 | message DDLCol {
23 | required KeyWord keyword = 1;
24 | optional bool isKey = 2 [default = false];
25 | optional string col = 3;
26 | optional string changeCol = 4;
27 | }
28 |
29 | message DMLEntry {
30 | required string db = 1;
31 | required string table = 2;
32 | required KeyWord keyword = 3;
33 | repeated DMLCol dmlCols = 4;
34 | }
35 |
36 | message DMLCol {
37 | required string col = 1;
38 | required bool isKey = 2;
39 | required bool isUpdate = 3;
40 | required string value = 4;
41 | }
42 |
43 | enum EntryType {
44 | DML = 1;
45 | DDL = 2;
46 | }
47 |
48 | enum KeyWord {
49 | CREATE = 1;
50 | ALTER = 2;
51 | ADD = 3;
52 | DROP = 4;
53 | CHANGE = 5;
54 | UPDATE = 6;
55 | INSERT = 7;
56 | DELETE = 8;
57 | }
--------------------------------------------------------------------------------
/store/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | carrygo
7 | com.abc.carrygo
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | carrygo.store
14 | jar
15 |
16 |
17 |
18 |
19 | com.abc.carrygo
20 | carrygo.common
21 | 1.0-SNAPSHOT
22 |
23 |
24 |
25 | ch.qos.logback
26 | logback-classic
27 | runtime
28 |
29 |
30 |
31 | org.apache.hbase
32 | hbase-client
33 |
34 |
35 |
36 |
37 | com.google.guava
38 | guava
39 | 12.0.1
40 |
41 |
42 |
43 |
44 | com.google.protobuf
45 | protobuf-java
46 | 2.5.0
47 |
48 |
49 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/AbstractWriterProcessor.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | * Created by plin on 10/17/16.
8 | */
9 | public abstract class AbstractWriterProcessor {
10 | private static final Logger log = LoggerFactory.getLogger(AbstractWriterProcessor.class);
11 |
12 |
13 | public abstract void process();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/hbase/HBaseWriterProcessor.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaAcceptor;
4 | import com.abc.carrygo.store.AbstractWriterProcessor;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by plin on 10/17/16.
12 | */
13 | public class HBaseWriterProcessor extends AbstractWriterProcessor {
14 | private static final Logger log = LoggerFactory.getLogger(HBaseWriterProcessor.class);
15 | private static final int N_THREADS = 1;
16 | private HBaseWriter writer;
17 | private List acceptors;
18 |
19 | public void process() {
20 |
21 | try {
22 | for (KafkaAcceptor acceptor : acceptors) {
23 | acceptor.run(N_THREADS, writer, MessageReceived.class.getName());
24 | }
25 | } catch (Exception e) {
26 | log.error("hbase event writer failed.", e);
27 | }
28 | }
29 |
30 | public void close() {
31 |
32 | for (KafkaAcceptor acceptor : acceptors) {
33 | acceptor.close();
34 | }
35 |
36 | if (writer != null) {
37 | try {
38 | writer.close();
39 | } catch (Exception e1) {
40 | log.error("hbase event writer close failed.", e1);
41 | }
42 | }
43 | }
44 |
45 | public void setAcceptors(List acceptors) {
46 | this.acceptors = acceptors;
47 | }
48 |
49 | public void setWriter(HBaseWriter writer) {
50 | this.writer = writer;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/hbase/HBaseWriterProcessorBuilder.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaAcceptor;
4 | import org.springframework.util.Assert;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by plin on 10/19/16.
10 | */
11 | public final class HBaseWriterProcessorBuilder {
12 |
13 | private HBaseWriterProcessor processor = null;
14 | private List acceptors = null;
15 | private HBaseWriter writer = null;
16 |
17 | public HBaseWriterProcessorBuilder() {
18 | }
19 |
20 | private static HBaseWriterProcessor build(HBaseWriterProcessorBuilder builder) {
21 | final List acceptors = builder.acceptors;
22 | final HBaseWriter writer = builder.writer;
23 |
24 | final HBaseWriterProcessor processor =
25 | (builder.processor != null)
26 | ? builder.processor
27 | : new HBaseWriterProcessor();
28 |
29 | processor.setAcceptors(acceptors);
30 | processor.setWriter(writer);
31 |
32 | return processor;
33 | }
34 |
35 | public HBaseWriterProcessorBuilder setAcceptors(List acceptors) {
36 | Assert.notNull(acceptors);
37 | this.acceptors = acceptors;
38 | return this;
39 | }
40 |
41 | public HBaseWriterProcessorBuilder setWriter(HBaseWriter writer) {
42 | Assert.notNull(writer);
43 | this.writer = writer;
44 | return this;
45 | }
46 |
47 | public HBaseWriterProcessor build() {
48 | return build(this);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/hbase/MessageReceived.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | import com.abc.carrygo.common.kafka.KafkaConsumer;
4 | import com.abc.carrygo.common.serde.ProtobufSerde;
5 | import com.abc.carrygo.protocol.SQLEventEntry.SQLEntry;
6 | import kafka.consumer.ConsumerIterator;
7 | import kafka.consumer.KafkaStream;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | * Created by plin on 10/18/16.
13 | */
14 | public class MessageReceived extends KafkaConsumer {
15 | private static final Logger log = LoggerFactory.getLogger(MessageReceived.class);
16 |
17 | private HBaseWriter writer;
18 |
19 | public MessageReceived(HBaseWriter writer, KafkaStream stream) {
20 | super(stream);
21 | this.writer = writer;
22 | }
23 |
24 | @Override
25 | public void run() {
26 |
27 | ConsumerIterator it = stream.iterator();
28 | while (it.hasNext()) {
29 | // log.info("msg:{}", new String(it.next().message()));
30 |
31 | byte[] bytes = it.next().message();
32 | SQLEntry sqlEntry = ProtobufSerde.fromBinary(bytes, SQLEntry.getDefaultInstance());
33 | writer.write(sqlEntry);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/hbase/service/HBaseWriterService.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase.service;
2 |
3 | import com.abc.carrygo.common.hbase.HBaseConnector;
4 | import com.abc.carrygo.common.kafka.KafkaAcceptor;
5 | import com.abc.carrygo.common.zookeeper.ZkAddress;
6 | import com.abc.carrygo.store.hbase.HBaseWriter;
7 | import com.abc.carrygo.store.hbase.HBaseWriterProcessor;
8 | import com.abc.carrygo.store.hbase.HBaseWriterProcessorBuilder;
9 | import org.apache.commons.lang3.StringUtils;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 |
13 | import java.io.IOException;
14 | import java.util.ArrayList;
15 | import java.util.Arrays;
16 | import java.util.List;
17 |
18 | /**
19 | * Created by plin on 10/20/16.
20 | */
21 | public class HBaseWriterService {
22 | private static final Logger log = LoggerFactory.getLogger(HBaseWriterService.class);
23 |
24 | private static final String SEPARATOR_CHAR = ",";
25 |
26 |
27 | private HBaseWriterProcessor processor;
28 |
29 | public void init(ZkAddress zkAddress, String specifiedTopics) {
30 | try {
31 | HBaseConnector.init(zkAddress);
32 | } catch (IOException e) {
33 | log.error("hbase connector init failed.", e);
34 | }
35 |
36 | String[] strings = StringUtils.split(specifiedTopics, SEPARATOR_CHAR);
37 | List topics = Arrays.asList(strings);
38 |
39 | List acceptors = new ArrayList<>(topics.size());
40 | for (String topic : topics) {
41 | KafkaAcceptor acceptor = new KafkaAcceptor(zkAddress, topic);
42 | acceptors.add(acceptor);
43 | }
44 |
45 |
46 | HBaseWriter writer = new HBaseWriter();
47 | HBaseWriterProcessorBuilder builder = new HBaseWriterProcessorBuilder();
48 | builder
49 | .setAcceptors(acceptors)
50 | .setWriter(writer);
51 | this.processor = builder.build();
52 | }
53 |
54 |
55 | public void write() {
56 | processor.process();
57 | }
58 |
59 | public void close() {
60 | processor.close();
61 | }
62 |
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/store/src/main/java/com/abc/carrygo/store/server/WriterServer.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.server;
2 |
3 | import com.abc.carrygo.common.conf.Configured;
4 | import com.abc.carrygo.common.zookeeper.ZkAddress;
5 | import com.abc.carrygo.store.hbase.service.HBaseWriterService;
6 | import org.apache.commons.lang.exception.ExceptionUtils;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | * Created by plin on 10/20/16.
12 | */
13 | public class WriterServer {
14 | private static final Logger log = LoggerFactory.getLogger(WriterServer.class);
15 |
16 | private static ZkAddress zkAddress;
17 | private static String specifiedTopics;
18 |
19 | private HBaseWriterService service;
20 |
21 | public static void main(String[] args) {
22 | zkAddress = Configured.zkAddress;
23 | specifiedTopics = Configured.kafkaTopic;
24 |
25 | final WriterServer server = new WriterServer();
26 | server.start();
27 |
28 | Runtime.getRuntime().addShutdownHook(new Thread() {
29 |
30 | public void run() {
31 | try {
32 | log.info("stop the writer server");
33 | server.stop();
34 |
35 | } catch (Throwable e) {
36 | log.warn("something goes wrong when stopping writer server:\n{}", ExceptionUtils.getFullStackTrace(e));
37 | } finally {
38 | log.info("writer server is down.");
39 | }
40 | }
41 | });
42 | }
43 |
44 | public void start() {
45 | log.info("start the writer server");
46 | startWriter();
47 | }
48 |
49 | public void startWriter() {
50 | service = new HBaseWriterService();
51 | service.init(zkAddress, specifiedTopics);
52 |
53 | service.write();
54 | }
55 |
56 | public void stop() {
57 | service.close();
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/store/src/main/resources/carrygo-conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 | classpath:carrygo.properties
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/store/src/main/resources/carrygo.properties:
--------------------------------------------------------------------------------
1 | [kafka]
2 | kafka.ip = 127.0.0.1
3 | kafka.port = 9092
4 | kafka.topic = test
5 |
6 | [zookeeper]
7 | zookeeper.destination = example
8 | zookeeper.ip = 127.0.0.1
9 | zookeeper.port = 2181
10 |
11 |
--------------------------------------------------------------------------------
/store/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | log
6 |
7 |
9 | log.%d{yyyy-MM-dd}.%i
10 |
11 |
12 | 500MB
13 |
14 |
15 | 3
16 |
17 |
18 |
19 | UTF-8
20 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/store/src/test/java/com/abc/carrygo/store/hbase/HBaseWriterBase.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | import com.abc.carrygo.protocol.SQLEventEntry.*;
4 |
5 | /**
6 | * Created by plin on 10/25/16.
7 | */
8 | public class HBaseWriterBase {
9 | protected static DDLEntry.Builder ddlBuilder;
10 | protected static DMLEntry.Builder dmlBuilder;
11 | protected static SQLEntry.Builder builder;
12 |
13 | public void init() {
14 | ddlBuilder = DDLEntry.newBuilder();
15 | dmlBuilder = DMLEntry.newBuilder();
16 | builder = SQLEntry.newBuilder();
17 | }
18 |
19 |
20 | public SQLEntry buildSQLEntry(DDLEntry ddlEntry) {
21 | SQLEntry sqlEntry = builder
22 | .setEntry(EntryType.DDL)
23 | .addDdlEntries(ddlEntry)
24 | .build();
25 | return sqlEntry;
26 | }
27 |
28 | public SQLEntry buildSQLEntry(DMLEntry dmlEntry) {
29 | SQLEntry sqlEntry = builder
30 | .setEntry(EntryType.DML)
31 | .addDmlEntries(dmlEntry)
32 | .build();
33 | return sqlEntry;
34 | }
35 |
36 | public DDLEntry buildDDLEntry(KeyWord keyWord, DDLCol col) {
37 | DDLEntry ddlEntry = ddlBuilder
38 | .setKeyword(keyWord)
39 | .addDdlCols(col)
40 | .build();
41 |
42 | return ddlEntry;
43 | }
44 |
45 | public DMLEntry buildDMLEntry(KeyWord keyWord, DMLCol col) {
46 | DMLEntry dmlEntry = dmlBuilder
47 | .setKeyword(keyWord)
48 | .addDmlCols(col)
49 | .build();
50 |
51 | return dmlEntry;
52 | }
53 |
54 | public DDLCol buildDDLCol(String colName, KeyWord keyWord, boolean isKey) {
55 | DDLCol ddlCol = DDLCol.newBuilder()
56 | .setCol(colName)
57 | .setIsKey(isKey)
58 | .setKeyword(keyWord)
59 | .build();
60 |
61 | return ddlCol;
62 | }
63 |
64 | public DMLCol buildDMLCol(String colName,
65 | String value,
66 | boolean isUpdate,
67 | boolean isKey) {
68 | DMLCol dmlCol = DMLCol.newBuilder()
69 | .setCol(colName)
70 | .setIsKey(isKey)
71 | .setIsUpdate(isUpdate)
72 | .setValue(value)
73 | .build();
74 |
75 | return dmlCol;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/store/src/test/java/com/abc/carrygo/store/hbase/HBaseWriterMultiThreadTest.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | public class HBaseWriterMultiThreadTest extends HBaseWriterBase {
4 |
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/store/src/test/java/com/abc/carrygo/store/hbase/HBaseWriterTest.java:
--------------------------------------------------------------------------------
1 | package com.abc.carrygo.store.hbase;
2 |
3 | import com.abc.carrygo.common.hbase.HBaseConnector;
4 | import com.abc.carrygo.common.zookeeper.ZkAddress;
5 | import com.abc.carrygo.protocol.SQLEventEntry.*;
6 | import org.junit.After;
7 | import org.junit.Assert;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 |
11 | import java.io.IOException;
12 | import java.util.List;
13 | import java.util.concurrent.atomic.AtomicLong;
14 |
15 | /**
16 | * Created by plin on 10/21/16.
17 | */
18 | public class HBaseWriterTest extends HBaseWriterBase {
19 | private static final String NS = "example";
20 | private static final String DB = "test";
21 | private static final String TABLE = "user";
22 |
23 | private static final String ZK_IP = "127.0.0.1";
24 | private static final String ZK_PORT = "2181";
25 | private static final String ZK_DESTINATION = "example";
26 | private static final String PRIMARY_KEY = "id";
27 | private static HBaseWriter hbaseWriter;
28 | private AtomicLong atomicId = new AtomicLong(1);
29 |
30 | @Before
31 | public void setUp() {
32 | init();
33 |
34 | ddlBuilder = ddlBuilder.setDb(DB).setTable(TABLE);
35 | dmlBuilder.setDb(DB).setTable(TABLE);
36 |
37 | ZkAddress zkAddress = new ZkAddress(ZK_DESTINATION, ZK_IP, ZK_PORT);
38 | try {
39 | HBaseConnector.init(zkAddress);
40 | } catch (IOException e) {
41 | e.printStackTrace();
42 | }
43 | hbaseWriter = new HBaseWriter();
44 | }
45 |
46 | // @Test
47 | public void testCreate() {
48 |
49 | DDLCol col = buildDDLCol(PRIMARY_KEY, KeyWord.CREATE, true);
50 | DDLEntry ddlEntry = buildDDLEntry(KeyWord.CREATE, col);
51 | SQLEntry sqlEntry = buildSQLEntry(ddlEntry);
52 |
53 | test(sqlEntry);
54 | }
55 |
56 | // @Test
57 | public void testAlter() {
58 | String colName = "name";
59 |
60 | DDLCol col = buildDDLCol(colName, KeyWord.ADD, false);
61 | DDLEntry ddlEntry = buildDDLEntry(KeyWord.ALTER, col);
62 | SQLEntry sqlEntry = buildSQLEntry(ddlEntry);
63 |
64 | test(sqlEntry);
65 | }
66 |
67 | // @Test
68 | public void testInsert() {
69 | long value = atomicId.addAndGet(System.nanoTime());
70 |
71 | DMLCol col = buildDMLCol(PRIMARY_KEY, String.valueOf(value), true, true);
72 | DMLEntry dmlEntry = buildDMLEntry(KeyWord.INSERT, col);
73 | SQLEntry sqlEntry = buildSQLEntry(dmlEntry);
74 |
75 | test(sqlEntry);
76 | }
77 |
78 | // @Test
79 | public void testUpdate() {
80 | long value = atomicId.get();
81 |
82 | DMLCol col = buildDMLCol(PRIMARY_KEY, String.valueOf(value), true, true);
83 | DMLEntry dmlEntry = buildDMLEntry(KeyWord.UPDATE, col);
84 | SQLEntry sqlEntry = buildSQLEntry(dmlEntry);
85 |
86 | test(sqlEntry);
87 | }
88 |
89 | // @Test
90 | public void testDel() {
91 | long value = atomicId.get();
92 |
93 | DMLCol col = buildDMLCol(PRIMARY_KEY, String.valueOf(value), true, true);
94 | DMLEntry dmlEntry = buildDMLEntry(KeyWord.DELETE, col);
95 | SQLEntry sqlEntry = buildSQLEntry(dmlEntry);
96 |
97 | test(sqlEntry);
98 | }
99 |
100 | // @Test
101 | public void testDelTable() {
102 | HBaseWriter.EventWriter eventWriter = hbaseWriter.getWriter();
103 |
104 | try {
105 | eventWriter.del(TABLE);
106 | } catch (Exception e) {
107 | e.printStackTrace();
108 |
109 | Assert.fail();
110 | }
111 |
112 | }
113 |
114 | @Test
115 | public void testDelTables() {
116 | HBaseWriter.EventWriter eventWriter = hbaseWriter.getWriter();
117 | List tables = eventWriter.getTables(NS);
118 |
119 | try {
120 | for (String table : tables) {
121 | eventWriter.del(table);
122 | }
123 | } catch (Exception e) {
124 | e.printStackTrace();
125 |
126 | Assert.fail();
127 | }
128 |
129 | }
130 |
131 | private void test(SQLEntry entry) {
132 | try {
133 | hbaseWriter.write(entry);
134 | } catch (Exception e) {
135 | e.printStackTrace();
136 |
137 | Assert.fail();
138 | }
139 |
140 | Assert.assertTrue(true);
141 | }
142 |
143 | @After
144 | public void tearDown() {
145 | try {
146 | hbaseWriter.close();
147 | } catch (Exception e) {
148 | e.printStackTrace();
149 |
150 | Assert.fail();
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------