├── DIRECTORY.md ├── Kafka-example ├── .gitignore ├── avro │ └── user.avsc ├── bin │ ├── default │ │ └── test │ │ │ └── java │ │ │ └── mincloud │ │ │ └── example │ │ │ ├── KafkaExampleApplicationTests.class │ │ │ ├── consumer │ │ │ └── KafkaReceiverTest.class │ │ │ └── producer │ │ │ └── KafkaSenderTest.class │ ├── main │ │ ├── application.yml │ │ └── mincloud │ │ │ └── example │ │ │ ├── KafkaExampleApplication.class │ │ │ ├── avro │ │ │ ├── User$Builder.class │ │ │ └── User.class │ │ │ ├── consumer │ │ │ ├── Receiver.class │ │ │ └── ReceiverConfig.class │ │ │ ├── model │ │ │ └── Car.class │ │ │ ├── producer │ │ │ ├── Sender.class │ │ │ └── SenderConfig.class │ │ │ └── serializer │ │ │ ├── AvroDeserializer.class │ │ │ └── AvroSerializer.class │ └── test │ │ └── mincloud │ │ └── example │ │ ├── KafkaExampleApplicationTests.class │ │ ├── consumer │ │ └── KafkaReceiverTest.class │ │ └── producer │ │ ├── KafkaSenderTest$1.class │ │ └── KafkaSenderTest.class ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── mincloud │ │ │ └── example │ │ │ ├── KafkaExampleApplication.java │ │ │ ├── avro │ │ │ └── User.java │ │ │ ├── consumer │ │ │ ├── Receiver.java │ │ │ └── ReceiverConfig.java │ │ │ ├── model │ │ │ └── Car.java │ │ │ ├── producer │ │ │ ├── Sender.java │ │ │ └── SenderConfig.java │ │ │ └── serializer │ │ │ ├── AvroDeserializer.java │ │ │ └── AvroSerializer.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── mincloud │ └── example │ ├── KafkaExampleApplicationTests.java │ ├── consumer │ └── KafkaReceiverTest.java │ └── producer │ └── KafkaSenderTest.java ├── LICENSE ├── README.md ├── files ├── splunk_forum_1.pdf ├── splunk_forum_2.pdf ├── splunk_forum_3.pdf └── splunk_forum_4.pdf └── images ├── aes_architecture.png ├── airflow.png ├── ambari.png ├── apache_flink.png ├── apache_kafka.png ├── apache_kafka1.png ├── apache_spark.png ├── cloud_storage.png ├── cloudera_architecture.png ├── druid_architecture.png ├── elasticsearch.png ├── hadoop_architecture.png ├── hdfs_architecture.jpg ├── ignite_architecture.png ├── kabana_vs_grafana.png ├── kappa_architecture.png ├── lambda_architecture.jpg ├── lambda_architecture.png ├── lucene_architecture.png ├── mapreduce.jpg ├── mapreduce.png ├── opentsdb_architecture.png ├── pipeline.jpg ├── spark.png ├── spark_architecture.png ├── spark_rdd.jpg ├── spark_stack.png ├── spark_streaming.png ├── splunk_architecture.png └── streaming_flow.png /DIRECTORY.md: -------------------------------------------------------------------------------- 1 | ## Splunk Forum Data 2 | 3 | - [The Data-to-Everything Platform](https://github.com/mincloud1501/BigData/blob/master/files/splunk_forum_1.pdf) 4 | - [What's New in Splunk](https://github.com/mincloud1501/BigData/blob/master/files/splunk_forum_2.pdf) 5 | - [Splunk for ITOps+DevOps](https://github.com/mincloud1501/BigData/blob/master/files/splunk_forum_3.pdf) 6 | - [Splunk for Security](https://github.com/mincloud1501/BigData/blob/master/files/splunk_forum_4.pdf) -------------------------------------------------------------------------------- /Kafka-example/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /Kafka-example/avro/user.avsc: -------------------------------------------------------------------------------- 1 | {"namespace": "kafka-example.avro", 2 | "type": "record", 3 | "name": "User", 4 | "fields": [ 5 | {"name": "name", "type": "string"}, 6 | {"name": "favorite_number", "type": ["int", "null"]}, 7 | {"name": "favorite_color", "type": ["string", "null"]} 8 | ] 9 | } -------------------------------------------------------------------------------- /Kafka-example/bin/default/test/java/mincloud/example/KafkaExampleApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/default/test/java/mincloud/example/KafkaExampleApplicationTests.class -------------------------------------------------------------------------------- /Kafka-example/bin/default/test/java/mincloud/example/consumer/KafkaReceiverTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/default/test/java/mincloud/example/consumer/KafkaReceiverTest.class -------------------------------------------------------------------------------- /Kafka-example/bin/default/test/java/mincloud/example/producer/KafkaSenderTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/default/test/java/mincloud/example/producer/KafkaSenderTest.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/application.yml: -------------------------------------------------------------------------------- 1 | kafka: 2 | bootstrap-servers: localhost:9092 3 | -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/KafkaExampleApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/KafkaExampleApplication.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/avro/User$Builder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/avro/User$Builder.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/avro/User.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/avro/User.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/consumer/Receiver.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/consumer/Receiver.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/consumer/ReceiverConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/consumer/ReceiverConfig.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/model/Car.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/model/Car.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/producer/Sender.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/producer/Sender.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/producer/SenderConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/producer/SenderConfig.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/serializer/AvroDeserializer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/serializer/AvroDeserializer.class -------------------------------------------------------------------------------- /Kafka-example/bin/main/mincloud/example/serializer/AvroSerializer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/main/mincloud/example/serializer/AvroSerializer.class -------------------------------------------------------------------------------- /Kafka-example/bin/test/mincloud/example/KafkaExampleApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/test/mincloud/example/KafkaExampleApplicationTests.class -------------------------------------------------------------------------------- /Kafka-example/bin/test/mincloud/example/consumer/KafkaReceiverTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/test/mincloud/example/consumer/KafkaReceiverTest.class -------------------------------------------------------------------------------- /Kafka-example/bin/test/mincloud/example/producer/KafkaSenderTest$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/test/mincloud/example/producer/KafkaSenderTest$1.class -------------------------------------------------------------------------------- /Kafka-example/bin/test/mincloud/example/producer/KafkaSenderTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/bin/test/mincloud/example/producer/KafkaSenderTest.class -------------------------------------------------------------------------------- /Kafka-example/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.2.0.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'mincloud.example' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | configurations { 12 | developmentOnly 13 | runtimeClasspath { 14 | extendsFrom developmentOnly 15 | } 16 | } 17 | 18 | repositories { 19 | mavenCentral() 20 | maven { url 'https://repo.spring.io/milestone' } 21 | } 22 | 23 | ext { 24 | set('springCloudVersion', "Hoxton.M3") 25 | } 26 | 27 | 28 | dependencies { 29 | implementation 'org.springframework.boot:spring-boot-starter-web' 30 | implementation 'org.apache.kafka:kafka-streams' 31 | implementation 'org.springframework.cloud:spring-cloud-starter-zookeeper-config' 32 | implementation 'org.springframework.kafka:spring-kafka' 33 | 34 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 35 | 36 | testImplementation('org.springframework.boot:spring-boot-starter-test') { 37 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 38 | exclude module: 'junit' 39 | } 40 | testImplementation 'org.springframework.kafka:spring-kafka-test' 41 | } 42 | 43 | dependencyManagement { 44 | imports { 45 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" 46 | } 47 | } 48 | 49 | test { 50 | useJUnitPlatform() 51 | } 52 | -------------------------------------------------------------------------------- /Kafka-example/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/Kafka-example/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Kafka-example/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /Kafka-example/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /Kafka-example/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /Kafka-example/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Kafka-example' 2 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/KafkaExampleApplication.java: -------------------------------------------------------------------------------- 1 | package mincloud.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class KafkaExampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(KafkaExampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/avro/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Avro 3 | * 4 | * DO NOT EDIT DIRECTLY 5 | */ 6 | package mincloud.example.avro; 7 | 8 | import org.apache.avro.specific.SpecificData; 9 | 10 | @SuppressWarnings("all") 11 | @org.apache.avro.specific.AvroGenerated 12 | public class User extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { 13 | private static final long serialVersionUID = -19344816715736557L; 14 | public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"mincloud.example.avro\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favorite_number\",\"type\":[\"int\",\"null\"]},{\"name\":\"favorite_color\",\"type\":[\"string\",\"null\"]}]}"); 15 | public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } 16 | @Deprecated public java.lang.CharSequence name; 17 | @Deprecated public java.lang.Integer favorite_number; 18 | @Deprecated public java.lang.CharSequence favorite_color; 19 | 20 | /** 21 | * Default constructor. Note that this does not initialize fields 22 | * to their default values from the schema. If that is desired then 23 | * one should use newBuilder(). 24 | */ 25 | public User() {} 26 | 27 | /** 28 | * All-args constructor. 29 | * @param name The new value for name 30 | * @param favorite_number The new value for favorite_number 31 | * @param favorite_color The new value for favorite_color 32 | */ 33 | public User(java.lang.CharSequence name, java.lang.Integer favorite_number, java.lang.CharSequence favorite_color) { 34 | this.name = name; 35 | this.favorite_number = favorite_number; 36 | this.favorite_color = favorite_color; 37 | } 38 | 39 | public org.apache.avro.Schema getSchema() { return SCHEMA$; } 40 | // Used by DatumWriter. Applications should not call. 41 | public java.lang.Object get(int field$) { 42 | switch (field$) { 43 | case 0: return name; 44 | case 1: return favorite_number; 45 | case 2: return favorite_color; 46 | default: throw new org.apache.avro.AvroRuntimeException("Bad index"); 47 | } 48 | } 49 | 50 | // Used by DatumReader. Applications should not call. 51 | @SuppressWarnings(value="unchecked") 52 | public void put(int field$, java.lang.Object value$) { 53 | switch (field$) { 54 | case 0: name = (java.lang.CharSequence)value$; break; 55 | case 1: favorite_number = (java.lang.Integer)value$; break; 56 | case 2: favorite_color = (java.lang.CharSequence)value$; break; 57 | default: throw new org.apache.avro.AvroRuntimeException("Bad index"); 58 | } 59 | } 60 | 61 | /** 62 | * Gets the value of the 'name' field. 63 | * @return The value of the 'name' field. 64 | */ 65 | public java.lang.CharSequence getName() { 66 | return name; 67 | } 68 | 69 | /** 70 | * Sets the value of the 'name' field. 71 | * @param value the value to set. 72 | */ 73 | public void setName(java.lang.CharSequence value) { 74 | this.name = value; 75 | } 76 | 77 | /** 78 | * Gets the value of the 'favorite_number' field. 79 | * @return The value of the 'favorite_number' field. 80 | */ 81 | public java.lang.Integer getFavoriteNumber() { 82 | return favorite_number; 83 | } 84 | 85 | /** 86 | * Sets the value of the 'favorite_number' field. 87 | * @param value the value to set. 88 | */ 89 | public void setFavoriteNumber(java.lang.Integer value) { 90 | this.favorite_number = value; 91 | } 92 | 93 | /** 94 | * Gets the value of the 'favorite_color' field. 95 | * @return The value of the 'favorite_color' field. 96 | */ 97 | public java.lang.CharSequence getFavoriteColor() { 98 | return favorite_color; 99 | } 100 | 101 | /** 102 | * Sets the value of the 'favorite_color' field. 103 | * @param value the value to set. 104 | */ 105 | public void setFavoriteColor(java.lang.CharSequence value) { 106 | this.favorite_color = value; 107 | } 108 | 109 | /** 110 | * Creates a new User RecordBuilder. 111 | * @return A new User RecordBuilder 112 | */ 113 | public static mincloud.example.avro.User.Builder newBuilder() { 114 | return new mincloud.example.avro.User.Builder(); 115 | } 116 | 117 | /** 118 | * Creates a new User RecordBuilder by copying an existing Builder. 119 | * @param other The existing builder to copy. 120 | * @return A new User RecordBuilder 121 | */ 122 | public static mincloud.example.avro.User.Builder newBuilder(mincloud.example.avro.User.Builder other) { 123 | return new mincloud.example.avro.User.Builder(other); 124 | } 125 | 126 | /** 127 | * Creates a new User RecordBuilder by copying an existing User instance. 128 | * @param other The existing instance to copy. 129 | * @return A new User RecordBuilder 130 | */ 131 | public static mincloud.example.avro.User.Builder newBuilder(mincloud.example.avro.User other) { 132 | return new mincloud.example.avro.User.Builder(other); 133 | } 134 | 135 | /** 136 | * RecordBuilder for User instances. 137 | */ 138 | public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase 139 | implements org.apache.avro.data.RecordBuilder { 140 | 141 | private java.lang.CharSequence name; 142 | private java.lang.Integer favorite_number; 143 | private java.lang.CharSequence favorite_color; 144 | 145 | /** Creates a new Builder */ 146 | private Builder() { 147 | super(SCHEMA$); 148 | } 149 | 150 | /** 151 | * Creates a Builder by copying an existing Builder. 152 | * @param other The existing Builder to copy. 153 | */ 154 | private Builder(mincloud.example.avro.User.Builder other) { 155 | super(other); 156 | if (isValidValue(fields()[0], other.name)) { 157 | this.name = data().deepCopy(fields()[0].schema(), other.name); 158 | fieldSetFlags()[0] = true; 159 | } 160 | if (isValidValue(fields()[1], other.favorite_number)) { 161 | this.favorite_number = data().deepCopy(fields()[1].schema(), other.favorite_number); 162 | fieldSetFlags()[1] = true; 163 | } 164 | if (isValidValue(fields()[2], other.favorite_color)) { 165 | this.favorite_color = data().deepCopy(fields()[2].schema(), other.favorite_color); 166 | fieldSetFlags()[2] = true; 167 | } 168 | } 169 | 170 | /** 171 | * Creates a Builder by copying an existing User instance 172 | * @param other The existing instance to copy. 173 | */ 174 | private Builder(mincloud.example.avro.User other) { 175 | super(SCHEMA$); 176 | if (isValidValue(fields()[0], other.name)) { 177 | this.name = data().deepCopy(fields()[0].schema(), other.name); 178 | fieldSetFlags()[0] = true; 179 | } 180 | if (isValidValue(fields()[1], other.favorite_number)) { 181 | this.favorite_number = data().deepCopy(fields()[1].schema(), other.favorite_number); 182 | fieldSetFlags()[1] = true; 183 | } 184 | if (isValidValue(fields()[2], other.favorite_color)) { 185 | this.favorite_color = data().deepCopy(fields()[2].schema(), other.favorite_color); 186 | fieldSetFlags()[2] = true; 187 | } 188 | } 189 | 190 | /** 191 | * Gets the value of the 'name' field. 192 | * @return The value. 193 | */ 194 | public java.lang.CharSequence getName() { 195 | return name; 196 | } 197 | 198 | /** 199 | * Sets the value of the 'name' field. 200 | * @param value The value of 'name'. 201 | * @return This builder. 202 | */ 203 | public mincloud.example.avro.User.Builder setName(java.lang.CharSequence value) { 204 | validate(fields()[0], value); 205 | this.name = value; 206 | fieldSetFlags()[0] = true; 207 | return this; 208 | } 209 | 210 | /** 211 | * Checks whether the 'name' field has been set. 212 | * @return True if the 'name' field has been set, false otherwise. 213 | */ 214 | public boolean hasName() { 215 | return fieldSetFlags()[0]; 216 | } 217 | 218 | 219 | /** 220 | * Clears the value of the 'name' field. 221 | * @return This builder. 222 | */ 223 | public mincloud.example.avro.User.Builder clearName() { 224 | name = null; 225 | fieldSetFlags()[0] = false; 226 | return this; 227 | } 228 | 229 | /** 230 | * Gets the value of the 'favorite_number' field. 231 | * @return The value. 232 | */ 233 | public java.lang.Integer getFavoriteNumber() { 234 | return favorite_number; 235 | } 236 | 237 | /** 238 | * Sets the value of the 'favorite_number' field. 239 | * @param value The value of 'favorite_number'. 240 | * @return This builder. 241 | */ 242 | public mincloud.example.avro.User.Builder setFavoriteNumber(java.lang.Integer value) { 243 | validate(fields()[1], value); 244 | this.favorite_number = value; 245 | fieldSetFlags()[1] = true; 246 | return this; 247 | } 248 | 249 | /** 250 | * Checks whether the 'favorite_number' field has been set. 251 | * @return True if the 'favorite_number' field has been set, false otherwise. 252 | */ 253 | public boolean hasFavoriteNumber() { 254 | return fieldSetFlags()[1]; 255 | } 256 | 257 | 258 | /** 259 | * Clears the value of the 'favorite_number' field. 260 | * @return This builder. 261 | */ 262 | public mincloud.example.avro.User.Builder clearFavoriteNumber() { 263 | favorite_number = null; 264 | fieldSetFlags()[1] = false; 265 | return this; 266 | } 267 | 268 | /** 269 | * Gets the value of the 'favorite_color' field. 270 | * @return The value. 271 | */ 272 | public java.lang.CharSequence getFavoriteColor() { 273 | return favorite_color; 274 | } 275 | 276 | /** 277 | * Sets the value of the 'favorite_color' field. 278 | * @param value The value of 'favorite_color'. 279 | * @return This builder. 280 | */ 281 | public mincloud.example.avro.User.Builder setFavoriteColor(java.lang.CharSequence value) { 282 | validate(fields()[2], value); 283 | this.favorite_color = value; 284 | fieldSetFlags()[2] = true; 285 | return this; 286 | } 287 | 288 | /** 289 | * Checks whether the 'favorite_color' field has been set. 290 | * @return True if the 'favorite_color' field has been set, false otherwise. 291 | */ 292 | public boolean hasFavoriteColor() { 293 | return fieldSetFlags()[2]; 294 | } 295 | 296 | 297 | /** 298 | * Clears the value of the 'favorite_color' field. 299 | * @return This builder. 300 | */ 301 | public mincloud.example.avro.User.Builder clearFavoriteColor() { 302 | favorite_color = null; 303 | fieldSetFlags()[2] = false; 304 | return this; 305 | } 306 | 307 | @Override 308 | public User build() { 309 | try { 310 | User record = new User(); 311 | record.name = fieldSetFlags()[0] ? this.name : (java.lang.CharSequence) defaultValue(fields()[0]); 312 | record.favorite_number = fieldSetFlags()[1] ? this.favorite_number : (java.lang.Integer) defaultValue(fields()[1]); 313 | record.favorite_color = fieldSetFlags()[2] ? this.favorite_color : (java.lang.CharSequence) defaultValue(fields()[2]); 314 | return record; 315 | } catch (Exception e) { 316 | throw new org.apache.avro.AvroRuntimeException(e); 317 | } 318 | } 319 | } 320 | 321 | private static final org.apache.avro.io.DatumWriter 322 | WRITER$ = new org.apache.avro.specific.SpecificDatumWriter(SCHEMA$); 323 | 324 | @Override public void writeExternal(java.io.ObjectOutput out) 325 | throws java.io.IOException { 326 | WRITER$.write(this, SpecificData.getEncoder(out)); 327 | } 328 | 329 | private static final org.apache.avro.io.DatumReader 330 | READER$ = new org.apache.avro.specific.SpecificDatumReader(SCHEMA$); 331 | 332 | @Override public void readExternal(java.io.ObjectInput in) 333 | throws java.io.IOException { 334 | READER$.read(this, SpecificData.getDecoder(in)); 335 | } 336 | 337 | } 338 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/consumer/Receiver.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.consumer; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.kafka.annotation.KafkaListener; 8 | 9 | import mincloud.example.avro.User; 10 | 11 | public class Receiver { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class); 14 | 15 | //public static final int COUNT = 20; 16 | 17 | private CountDownLatch latch = new CountDownLatch(1); 18 | 19 | public CountDownLatch getLatch() { 20 | return latch; 21 | } 22 | 23 | //@KafkaListener(topics = "kafka-test.t") 24 | //@KafkaListener(id = "batch-listener", topics = "kafka-test.t") 25 | //@KafkaListener(topics = "${kafka.topic.avro}") 26 | @KafkaListener(topics = "kafka-test-topic") 27 | 28 | public void receive(User user) { 29 | LOGGER.info("#####received user='{}'", user.toString()); 30 | latch.countDown(); 31 | } 32 | 33 | /* 34 | public void receive(List data, 35 | @Header(KafkaHeaders.RECEIVED_PARTITION_ID) List partitions, 36 | @Header(KafkaHeaders.OFFSET) List offsets) { 37 | 38 | LOGGER.info("start of batch receive"); 39 | 40 | for (int i = 0; i < data.size(); i++) { 41 | LOGGER.info("received message='{}' with partition-offset='{}'", data.get(i), 42 | partitions.get(i) + "-" + offsets.get(i)); 43 | 44 | // handle message 45 | latch.countDown(); 46 | } 47 | LOGGER.info("end of batch receive"); 48 | } */ 49 | 50 | /* 51 | public void receive(ConsumerRecord consumerRecord) { 52 | LOGGER.info("received payload='{}'", consumerRecord.toString()); 53 | latch.countDown(); 54 | }*/ 55 | } 56 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/consumer/ReceiverConfig.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.consumer; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.kafka.clients.consumer.ConsumerConfig; 7 | import org.apache.kafka.common.serialization.StringDeserializer; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.kafka.annotation.EnableKafka; 12 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 13 | import org.springframework.kafka.config.KafkaListenerContainerFactory; 14 | import org.springframework.kafka.core.ConsumerFactory; 15 | import org.springframework.kafka.core.DefaultKafkaConsumerFactory; 16 | import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; 17 | import org.springframework.kafka.support.serializer.JsonDeserializer; 18 | 19 | import mincloud.example.avro.User; 20 | import mincloud.example.serializer.AvroDeserializer; 21 | 22 | @Configuration 23 | @EnableKafka 24 | public class ReceiverConfig { 25 | 26 | @Value("${kafka.bootstrap-servers}") 27 | private String bootstrapServers; 28 | 29 | @Bean 30 | public Map consumerConfigs() { 31 | 32 | Map props = new HashMap<>(); 33 | 34 | // list of host:port pairs used for establishing the initial connections to the Kafka cluster 35 | props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 36 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 37 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, AvroDeserializer.class); 38 | // allows a pool of processes to divide the work of consuming and processing records 39 | props.put(ConsumerConfig.GROUP_ID_CONFIG, "avro"); 40 | 41 | // automatically reset the offset to the earliest offset 42 | //props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); 43 | 44 | // maximum records per poll 45 | //props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "10"); 46 | 47 | return props; 48 | } 49 | 50 | @Bean 51 | public ConsumerFactory consumerFactory() { 52 | //return new DefaultKafkaConsumerFactory<>(consumerConfigs()); 53 | return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(), 54 | new JsonDeserializer<>(User.class)); 55 | } 56 | 57 | @Bean 58 | public KafkaListenerContainerFactory> kafkaListenerContainerFactory() { 59 | ConcurrentKafkaListenerContainerFactory factory = 60 | new ConcurrentKafkaListenerContainerFactory<>(); 61 | factory.setConsumerFactory(consumerFactory()); 62 | 63 | // enable batch listening 64 | //factory.setBatchListener(true); 65 | 66 | return factory; 67 | } 68 | 69 | @Bean 70 | public Receiver receiver() { 71 | return new Receiver(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/model/Car.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.model; 2 | 3 | public class Car { 4 | 5 | private String make; 6 | private String manufacturer; 7 | private String id; 8 | 9 | public Car() { 10 | super(); 11 | } 12 | 13 | public Car(String make, String manufacturer, String id) { 14 | super(); 15 | this.make = make; 16 | this.manufacturer = manufacturer; 17 | this.id = id; 18 | } 19 | 20 | public String getMake() { 21 | return make; 22 | } 23 | 24 | public void setMake(String make) { 25 | this.make = make; 26 | } 27 | 28 | public String getManufacturer() { 29 | return manufacturer; 30 | } 31 | 32 | 33 | public void setManufacturer(String manufacturer) { 34 | this.manufacturer = manufacturer; 35 | } 36 | 37 | public String getId() { 38 | return id; 39 | } 40 | 41 | 42 | public void setId(String id) { 43 | this.id = id; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "Car [make=" + make + ", manufacturer=" + manufacturer + ", id=" + id + "]"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/producer/Sender.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.producer; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.kafka.core.KafkaTemplate; 7 | 8 | import mincloud.example.avro.User; 9 | 10 | public class Sender { 11 | 12 | private static final Logger LOGGER = LoggerFactory.getLogger(Sender.class); 13 | 14 | //@Value("${kafka.topic.json}") 15 | //private String jsonTopic; 16 | 17 | //@Value("${kafka.topic.avro}") 18 | //private String avroTopic; 19 | 20 | @Autowired 21 | private KafkaTemplate kafkaTemplate; 22 | 23 | public void send(User user) { 24 | 25 | //LOGGER.info("sending payload='{}'", payload); 26 | //kafkaTemplate.send("kafka-test.t", payload); 27 | 28 | //LOGGER.info("#####sending car='{}'", car.toString()); 29 | //kafkaTemplate.send(jsonTopic, car); 30 | 31 | LOGGER.info("#####sending car='{}'", user.toString()); 32 | kafkaTemplate.send("kafka-test-topic", user); 33 | } 34 | } -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/producer/SenderConfig.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.producer; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.kafka.clients.producer.ProducerConfig; 7 | import org.apache.kafka.common.serialization.StringSerializer; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 12 | import org.springframework.kafka.core.KafkaTemplate; 13 | import org.springframework.kafka.core.ProducerFactory; 14 | 15 | import mincloud.example.avro.User; 16 | import mincloud.example.serializer.AvroSerializer; 17 | 18 | @Configuration 19 | public class SenderConfig { 20 | 21 | @Value("${kafka.bootstrap-servers}") 22 | private String bootstrapServers; 23 | 24 | @Bean 25 | public Map producerConfigs() { 26 | Map props = new HashMap<>(); 27 | 28 | // list of host:port pairs used for establishing the initial connections to the Kakfa cluster 29 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 30 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 31 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, AvroSerializer.class); 32 | 33 | return props; 34 | } 35 | 36 | @Bean 37 | public ProducerFactory producerFactory() { 38 | return new DefaultKafkaProducerFactory<>(producerConfigs()); 39 | } 40 | 41 | @Bean 42 | public KafkaTemplate kafkaTemplate() { 43 | return new KafkaTemplate<>(producerFactory()); 44 | } 45 | 46 | @Bean 47 | public Sender sender() { 48 | return new Sender(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/serializer/AvroDeserializer.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.serializer; 2 | 3 | import java.util.Arrays; 4 | import java.util.Map; 5 | 6 | import javax.xml.bind.DatatypeConverter; 7 | 8 | import org.apache.avro.generic.GenericRecord; 9 | import org.apache.avro.io.DatumReader; 10 | import org.apache.avro.io.Decoder; 11 | import org.apache.avro.io.DecoderFactory; 12 | import org.apache.avro.specific.SpecificDatumReader; 13 | import org.apache.avro.specific.SpecificRecordBase; 14 | import org.apache.kafka.common.errors.SerializationException; 15 | import org.apache.kafka.common.serialization.Deserializer; 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | 19 | public class AvroDeserializer implements Deserializer { 20 | 21 | private static final Logger LOGGER = LoggerFactory.getLogger(AvroDeserializer.class); 22 | 23 | protected final Class targetType; 24 | 25 | public AvroDeserializer(Class targetType) { 26 | this.targetType = targetType; 27 | } 28 | 29 | @Override 30 | public void close() { 31 | // No-op 32 | } 33 | 34 | @Override 35 | public void configure(Map arg0, boolean arg1) { 36 | // No-op 37 | } 38 | 39 | @SuppressWarnings("unchecked") 40 | @Override 41 | public T deserialize(String topic, byte[] data) { 42 | try { 43 | T result = null; 44 | 45 | if (data != null) { 46 | LOGGER.debug("data='{}'", DatatypeConverter.printHexBinary(data)); 47 | 48 | DatumReader datumReader = 49 | new SpecificDatumReader<>(targetType.newInstance().getSchema()); 50 | Decoder decoder = DecoderFactory.get().binaryDecoder(data, null); 51 | 52 | result = (T) datumReader.read(null, decoder); 53 | LOGGER.debug("@@@@@deserialized data='{}'", result); 54 | } 55 | return result; 56 | 57 | } catch (Exception ex) { 58 | throw new SerializationException( 59 | "Can't deserialize data '" + Arrays.toString(data) + "' from topic '" + topic + "'", ex); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Kafka-example/src/main/java/mincloud/example/serializer/AvroSerializer.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.serializer; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.util.Map; 6 | 7 | import javax.xml.bind.DatatypeConverter; 8 | 9 | import org.apache.avro.generic.GenericDatumWriter; 10 | import org.apache.avro.generic.GenericRecord; 11 | import org.apache.avro.io.BinaryEncoder; 12 | import org.apache.avro.io.DatumWriter; 13 | import org.apache.avro.io.EncoderFactory; 14 | import org.apache.avro.specific.SpecificRecordBase; 15 | import org.apache.kafka.common.errors.SerializationException; 16 | import org.apache.kafka.common.serialization.Serializer; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | public class AvroSerializer implements Serializer { 21 | 22 | private static final Logger LOGGER = LoggerFactory.getLogger(AvroSerializer.class); 23 | 24 | @Override 25 | public void close() { 26 | // No-op 27 | } 28 | 29 | @Override 30 | public void configure(Map arg0, boolean arg1) { 31 | // No-op 32 | } 33 | 34 | @Override 35 | public byte[] serialize(String topic, T data) { 36 | try { 37 | byte[] result = null; 38 | 39 | if (data != null) { 40 | LOGGER.debug("data='{}'", data); 41 | 42 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 43 | BinaryEncoder binaryEncoder = 44 | EncoderFactory.get().binaryEncoder(byteArrayOutputStream, null); 45 | 46 | DatumWriter datumWriter = new GenericDatumWriter<>(data.getSchema()); 47 | datumWriter.write(data, binaryEncoder); 48 | 49 | binaryEncoder.flush(); 50 | byteArrayOutputStream.close(); 51 | 52 | result = byteArrayOutputStream.toByteArray(); 53 | LOGGER.debug("@@@@@serialized data='{}'", DatatypeConverter.printHexBinary(result)); 54 | } 55 | return result; 56 | 57 | } catch (IOException ex) { 58 | throw new SerializationException( 59 | "Can't serialize data='" + data + "' for topic='" + topic + "'", ex); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Kafka-example/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | kafka: 2 | bootstrap-servers: localhost:9092 3 | -------------------------------------------------------------------------------- /Kafka-example/src/test/java/mincloud/example/KafkaExampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package mincloud.example; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import mincloud.example.avro.User; 14 | import mincloud.example.consumer.Receiver; 15 | import mincloud.example.producer.Sender; 16 | 17 | @RunWith(SpringRunner.class) 18 | @SpringBootTest 19 | 20 | public class KafkaExampleApplicationTests { 21 | 22 | static final String RECEIVER_TOPIC = "kafka-test-topic"; 23 | 24 | @Autowired 25 | private Receiver receiver; 26 | 27 | @Autowired 28 | private Sender sender; 29 | 30 | //@ClassRule 31 | //public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, RECEIVER_TOPIC); 32 | 33 | @Test 34 | public void testReceive() throws Exception { 35 | // Use JsonSerializer 36 | //Car car = new Car("Passat", "Volkswagen", "ABC-123"); 37 | 38 | // Use AvroSerializer 39 | User user = User.newBuilder().setName("Keith, Moon").setFavoriteColor("yellow").setFavoriteNumber(null).build(); 40 | sender.send(user); 41 | 42 | receiver.getLatch().await(10000, TimeUnit.MILLISECONDS); 43 | assertThat(receiver.getLatch().getCount()).isEqualTo(0); 44 | } 45 | 46 | /* 47 | public void testReceive() throws Exception { 48 | 49 | // Use StringSerializer 50 | int numberOfMessages = Receiver.COUNT; 51 | 52 | for (int i = 0; i < numberOfMessages; i++) { 53 | sender.send("message " + i); 54 | } 55 | 56 | //sender.send("###Hello Spring Boot Kafka!!!"); 57 | 58 | receiver.getLatch().await(10000, TimeUnit.MILLISECONDS); 59 | assertThat(receiver.getLatch().getCount()).isEqualTo(0); 60 | }*/ 61 | } 62 | -------------------------------------------------------------------------------- /Kafka-example/src/test/java/mincloud/example/consumer/KafkaReceiverTest.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.consumer; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import java.util.Map; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import org.junit.Before; 9 | import org.junit.ClassRule; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.boot.test.context.SpringBootTest; 17 | import org.springframework.kafka.config.KafkaListenerEndpointRegistry; 18 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 19 | import org.springframework.kafka.core.KafkaTemplate; 20 | import org.springframework.kafka.core.ProducerFactory; 21 | import org.springframework.kafka.listener.MessageListenerContainer; 22 | import org.springframework.kafka.test.rule.EmbeddedKafkaRule; 23 | import org.springframework.kafka.test.utils.ContainerTestUtils; 24 | import org.springframework.kafka.test.utils.KafkaTestUtils; 25 | import org.springframework.test.annotation.DirtiesContext; 26 | import org.springframework.test.context.junit4.SpringRunner; 27 | 28 | @RunWith(SpringRunner.class) 29 | @SpringBootTest 30 | @DirtiesContext 31 | public class KafkaReceiverTest { 32 | 33 | private static final Logger LOGGER = LoggerFactory.getLogger(KafkaReceiverTest.class); 34 | 35 | private static String RECEIVER_TOPIC = "kafka-test.t"; 36 | 37 | @Autowired 38 | private Receiver receiver; 39 | 40 | private KafkaTemplate template; 41 | 42 | @Autowired 43 | private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry; 44 | 45 | @ClassRule 46 | public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, RECEIVER_TOPIC); 47 | 48 | @Before 49 | public void setUp() throws Exception { 50 | 51 | // set up the Kafka producer properties 52 | Map senderProperties = 53 | KafkaTestUtils.senderProps( 54 | embeddedKafka.getEmbeddedKafka().getBrokersAsString()); 55 | 56 | // create a Kafka producer factory 57 | ProducerFactory producerFactory = 58 | new DefaultKafkaProducerFactory( 59 | senderProperties); 60 | 61 | // create a Kafka template 62 | template = new KafkaTemplate<>(producerFactory); 63 | 64 | // set the default topic to send to 65 | template.setDefaultTopic(RECEIVER_TOPIC); 66 | 67 | // wait until the partitions are assigned 68 | for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry 69 | .getListenerContainers()) { 70 | ContainerTestUtils.waitForAssignment(messageListenerContainer, 71 | embeddedKafka.getEmbeddedKafka().getPartitionsPerTopic()); 72 | } 73 | } 74 | 75 | @Test 76 | public void testReceive() throws Exception { 77 | 78 | // send the message 79 | String greeting = "Hello Spring Boot Kafka Receiver!"; 80 | template.sendDefault(greeting); 81 | 82 | LOGGER.debug("test-sender sent message='{}'", greeting); 83 | 84 | receiver.getLatch().await(10000, TimeUnit.MILLISECONDS); 85 | 86 | // check that the message was received 87 | assertThat(receiver.getLatch().getCount()).isEqualTo(0); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Kafka-example/src/test/java/mincloud/example/producer/KafkaSenderTest.java: -------------------------------------------------------------------------------- 1 | package mincloud.example.producer; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.junit.Assert.assertThat; 5 | import static org.springframework.kafka.test.assertj.KafkaConditions.key; 6 | import static org.springframework.kafka.test.hamcrest.KafkaMatchers.hasValue; 7 | 8 | import java.util.Map; 9 | import java.util.concurrent.BlockingQueue; 10 | import java.util.concurrent.LinkedBlockingQueue; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | import org.apache.kafka.clients.consumer.ConsumerRecord; 14 | import org.junit.After; 15 | import org.junit.Before; 16 | import org.junit.ClassRule; 17 | import org.junit.Test; 18 | import org.junit.runner.RunWith; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.test.context.SpringBootTest; 23 | import org.springframework.kafka.core.DefaultKafkaConsumerFactory; 24 | import org.springframework.kafka.listener.ContainerProperties; 25 | import org.springframework.kafka.listener.KafkaMessageListenerContainer; 26 | import org.springframework.kafka.listener.MessageListener; 27 | import org.springframework.kafka.test.rule.EmbeddedKafkaRule; 28 | import org.springframework.kafka.test.utils.ContainerTestUtils; 29 | import org.springframework.kafka.test.utils.KafkaTestUtils; 30 | import org.springframework.test.annotation.DirtiesContext; 31 | import org.springframework.test.context.junit4.SpringRunner; 32 | 33 | @RunWith(SpringRunner.class) 34 | @SpringBootTest 35 | @DirtiesContext 36 | public class KafkaSenderTest { 37 | 38 | private static final Logger LOGGER = LoggerFactory.getLogger(KafkaSenderTest.class); 39 | 40 | private static String SENDER_TOPIC = "kafka-test.t"; 41 | 42 | @Autowired 43 | private Sender sender; 44 | 45 | private KafkaMessageListenerContainer container; 46 | 47 | private BlockingQueue> records; 48 | 49 | @ClassRule 50 | public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, SENDER_TOPIC); 51 | 52 | @Before 53 | public void setUp() throws Exception { 54 | // set up the Kafka consumer properties 55 | Map consumerProperties = 56 | KafkaTestUtils.consumerProps("sender", "false", embeddedKafka.getEmbeddedKafka()); 57 | 58 | // create a Kafka consumer factory 59 | DefaultKafkaConsumerFactory consumerFactory = 60 | new DefaultKafkaConsumerFactory(consumerProperties); 61 | 62 | // set the topic that needs to be consumed 63 | ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC); 64 | 65 | // create a Kafka MessageListenerContainer 66 | container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties); 67 | 68 | // create a thread safe queue to store the received message 69 | records = new LinkedBlockingQueue<>(); 70 | 71 | // setup a Kafka message listener 72 | container.setupMessageListener(new MessageListener() { 73 | @Override 74 | public void onMessage( 75 | ConsumerRecord record) { 76 | LOGGER.debug("test-listener received message='{}'", 77 | record.toString()); 78 | records.add(record); 79 | } 80 | }); 81 | 82 | // start the container and underlying message listener 83 | container.start(); 84 | 85 | // wait until the container has the required number of assigned partitions 86 | ContainerTestUtils.waitForAssignment(container, embeddedKafka.getEmbeddedKafka().getPartitionsPerTopic()); 87 | } 88 | 89 | @After 90 | public void tearDown() { 91 | // stop the container 92 | container.stop(); 93 | } 94 | 95 | @Test 96 | public void testSend() throws InterruptedException { 97 | // send the message 98 | String greeting = "Hello Spring Kafka Sender!"; 99 | //sender.send(greeting); 100 | 101 | // check that the message was received 102 | ConsumerRecord received = records.poll(10, TimeUnit.SECONDS); 103 | 104 | // Hamcrest Matchers to check the value 105 | assertThat(received, hasValue(greeting)); 106 | // AssertJ Condition to check the key 107 | assertThat(received).has(key(null)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 J.Ho Moon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BigData Study Project 2 | 3 | **BigData Pipeline** 4 | 5 | - [Data 수집] ▶ [Data 직렬화] ▶ [Data 저장] ▶ [Data 처리] ▶ [Data 분석] ▶ [Data 시각화] ▶ [Data 관리] 6 | 7 | [BigData Pipeline] 8 | ![pipeline](images/pipeline.jpg) 9 | 10 | ## [Data 수집] 11 | - Logstash, Beats (Packet/Top/File beats) 12 | - **Apache Flume**, Yahoo Chuckwa, Facebook Scribe, Apache Sqoop 13 | 14 | ### ☞ Apache Kafka [![kafka](https://img.shields.io/badge/Apache-Kafka-blue)](https://kafka.apache.org/documentation/) [![quickstart](https://img.shields.io/badge/Kafka-Quickstart-red)](https://kafka.apache.org/quickstart)  15 | 16 | [Kafka Architecture] [![Sources](https://img.shields.io/badge/출처-Kafka-yellow)](https://kafka.apache.org/intro) 17 | 18 | ![kafka](images/apache_kafka.png) 19 | 20 | ```js 21 | - Producer API : 한 개 이상의 topic에 stream을 publish할 수 있는 응용 프로그램을 제작 22 | - Consumer API : 한 개 이상의 topic을 subscribe하고 생성된 record stream을 처리 23 | - Streams API : 한 개 이상의 topic에서 메시지의 직렬화/역직렬화를 처리하고 상태 저장 작업에 필요한 상태를 유지, Kafka Cluster와 통신하는 Java Client Library (현재 Scala) 24 | - Connector API: kafka에 기록된 data를 기존 응용 프로그램 또는 DB에 연결하는 재사용 가능한 Producer 또는 Consumer를 구축 및 실행 25 | ``` 26 | 27 | - Apachae Camus : 카프카에서 hdfs로 데이터를 배치로 옮겨주는 역할 28 | 29 | ### ★Run (On Windows) 30 | 31 | - Download : http://mirror.navercorp.com/apache/kafka/2.3.1/ 32 | 33 | - Run Zookeeper/Kafka & Create Topic & Run Consumer/Producer 34 | 35 | ```java 36 | # Zookeeper Run 37 | > bin/windows/zookeeper-server-start.bat config/zookeeper.properties 38 | 39 | # Kafka Run 40 | > bin/windows/kafka-server-start.bat config/server.properties 41 | 42 | # Topic 생성 43 | > bin/windows/kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic kafka-test-topic 44 | 45 | # Topic List 확인 46 | > bin/windows/kafka-topics.bat --list --zookeeper localhost:2181 47 | 48 | # Topic 삭제 : /temp/zookeeper & kafka-logs로 관리 49 | > bin/windows/kafka-topics.bat --delete --zookeeper localhost --topic kafka-test-topic 50 | 51 | # Consumer Run -> Get Message 52 | > bin/windows/kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic kafka-test-topic 53 | 54 | # Producer Run -> Send Message 55 | > bin/windows/kafka-console-producer.bat --broker-list localhost:9092 --topic kafka-test-topic 56 | > test message#1 57 | > test message#2 58 | > test message#3 59 | ``` 60 | 61 | - Run API : http://localhost:8080/get?message=kafka-test-message 62 | 63 | ```java 64 | # Run Zookeeper & Kafka 65 | # Create Topic 66 | # JUnit Test KafkaExampleApplicationTests 67 | ``` 68 | 69 | #### <설계/고려사항> 70 | - Kafka는 실제로 대규모 Stream을 처리하도록 설계되어 규모가 없거나 예상하지 못한 경우, 설정하고 유지/관리하는 것은 가치가 없음. 71 | 72 | ```js 73 | - 장애 발생 시 데이터 처리 보장 74 | - 누락 데이터 확인을 위한 메타정보 추가 75 | - 데이터 복구 방안 76 | ``` 77 | 78 | --- 79 | 80 | ## [Data 직렬화] 81 | 82 | #### ■ Apache Parquet [![parquet](https://img.shields.io/badge/Apache-Parquet-orange)](https://parquet.apache.org/)  83 | 84 | - Apache Parquet는 데이터 처리 프레임 워크, 데이터 모델 또는 프로그래밍 언어의 선택에 관계없이 Hadoop 에코 시스템의 모든 프로젝트에서 사용할 수 있는 컬럼 스토리지 형식 85 | 86 | ```js 87 | - Hadoop HDFS에서 주로 사용하는 파일 포맷 88 | - 중첩된 데이터를 효율적으로 저장할 수 있는 컬럼 기준 저장 포맷 <- 압축률이 더 좋다. 89 | - 컬럼 기준 포맷은 파일 크기와 쿼리 성능 측면에 모두 효율성이 높음 <- I/O 사용률이 줄어든다. 90 | - 자바 구현체는 단일 표현에 얽매이지 않기 때문에 Parquet 파일에서 데이터를 읽고 쓰는데 Avro, Thrift, Protocol Buffer의 In-memory 데이터 모델을 사용할 수 있음 91 | ``` 92 | 93 | #### ■ Apache Thrift [![thrift](https://img.shields.io/badge/Apache-Thrift-orange)](https://thrift.apache.org/)  94 | 95 | - 확장 가능한 언어 간 서비스 개발을 위한 Apache Thrift 소프트웨어 프레임 워크는 소프트웨어 스택과 코드 생성 엔진을 결합 (C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cocoa, JavaScript, Node.js, Smalltalk, OCaml 및 Delphi 및 기타 언어) 96 | 97 | ```js 98 | - Facebook에서 개발한 서로 다른 언어로 개발된 모듈들의 통합을 지원하는 RPC Framework 99 | ``` 100 | 101 | ### ☞ Google Protocol Buffer [![gpb](https://img.shields.io/badge/Google-Protocol_Buffer-orange)](https://developers.google.com/protocol-buffers)  102 | 103 | - 프로토콜 버퍼는 구조화된 데이터를 직렬화하기 위한 Google의 언어, 플랫폼 중립적이며 확장 가능한 메커니즘으로 XML은 작지만 더 빠르고 단순함 104 | 105 | ```js 106 | - 구글에서 개발 오픈한 Serialized Data Structure 107 | - C++,C#, Go, Java, Python, Object C, Javascript, Ruby 등 다양한 언어를 지원하며, 직렬화 속도가 빠르고 직렬화된 파일의 크기도 작아서 Apache Avro 파일 포맷과 함께 많이 사용됨 108 | - GRPC Network Protocol의 경우 HTTP 2.0 을 기반으로 하여 직렬화 109 | - 하나의 파일에 최대 64M 까지 지원 가능하며, JSON 파일을 프로토콜 버퍼 파일 포맷으로 전환이 가능하고, 반대로 프로토콜 버퍼 파일도 JSON으로 전환이 가능 110 | ``` 111 | 112 | ### ☞ Apache Avro [![avro](https://img.shields.io/badge/Apache-Avro-orange)](http://avro.apache.org/docs/current/)  113 | 114 | - Avro는 언어 독립적인 직렬화 라이브러리로 핵심 구성 요소 중 하나인 스키마를 사용. 추가 데이터 처리를 위해 스키마를 JSON 파일에 저장함 115 | 116 | ```js 117 | - 특정 언어에 종속되지 않은 언어 중립적 데이터 직렬화 시스템 118 | - 하둡 Writable(직렬화 방식)의 주요 단점인 언어 이식성(language portablility)을 해결하기 위해 만든 프로젝트 119 | - 스키마는 JSON으로 작성 120 | - 데이터는 작고 빠른 바이너리 포맷으로 직렬화 121 | ``` 122 | 123 | ### ★Run [![Sources](https://img.shields.io/badge/출처-Avro-yellow)](https://avro.apache.org/docs/current/gettingstartedjava.html#Defining+a+schema) 124 | - Apache Avro를 사용하여 AvroHttRequest Class를 직렬화 및 역직렬화 수행 example code 125 | - Apache Kafka에는 다수의 built in (de)serializers가 제공되지만 Avro는 포함되어 있지 않음 126 | 127 | [Add dependency] 128 | 129 | ```xml 130 | 131 | org.apache.avro 132 | avro-compiler 133 | 1.8.2 134 | 135 | 136 | org.apache.avro 137 | avro-maven-plugin 138 | 1.8.2 139 | 140 | ``` 141 | 142 | [Defining a schema (user.avsc)] 143 | 144 | ```json 145 | { 146 | "namespace": "mincloud.example.avro", 147 | "type": "record", 148 | "name": "User", 149 | "fields": [ 150 | {"name": "name", "type": "string"}, 151 | {"name": "favorite_number", "type": ["int", "null"]}, 152 | {"name": "favorite_color", "type": ["string", "null"]} 153 | ] 154 | } 155 | ``` 156 | 157 | [Compiling the schema] 158 | 159 | ``` 160 | > java -jar avro-tools-1.9.1.jar compile schema user.avsc . 161 | ``` 162 | 163 | [Serializing / Deserializing Test] 164 | 165 | - Zookeeper 실행 후 embeddedKafka 연동하여 Test 166 | 167 | ```java 168 | @ClassRule 169 | public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, RECEIVER_TOPIC); 170 | 171 | @Before 172 | public void setUp() throws Exception { 173 | for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry.getListenerContainers()) { 174 | ContainerTestUtils.waitForAssignment(messageListenerContainer, embeddedKafka.getEmbeddedKafka().getPartitionsPerTopic()); 175 | } 176 | } 177 | ``` 178 | 179 | --- 180 | 181 | ## [Data 저장] 182 | 183 | #### ■ Apache Hadoop HDFS(Hadoop Distributed File System) [![Sources](https://img.shields.io/badge/출처-Hadoop-yellow)](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html) 184 | 185 | [구성요소] 186 | 187 | ```js 188 | - 여러 데이터 서버에 데이터를 저장하는 Hadoop의 스토리지 계층으로 Namenode와 Datanode로 구성 189 | - NameNode : Namenode는 마스터 서버, Namenode는 다양한 데이터 노드,위치,각 블록의 크기 등에 대한 Metadata 정보를 저장 190 | - DataNode : Block report를 10초마다 Namenode에 전송하는 multi-instance server. N개의 Datanode server가 있을 수 있으며, Namenode에 의해 요청될 때 블록을 저장하고 검색하며, 클라이언트의 요청을 read/write하며 Namenode의 지시에 따라 블록 생성/삭제 및 복제를 수행 191 | ``` 192 | 193 | [HDFS Architecture] 194 | 195 | ![hdfs_architecture](images/hdfs_architecture.jpg) 196 | 197 | [동작 원리] 198 | 199 | ```js 200 | - HDFS는 데이터를 수집할 때 정보를 개별 블록으로 나누어 클러스터의 다른 노드에 분산시켜 작업을 병렬로 수행하여 보다 효율적으로 작업할 수 있도록 함 201 | - 무장애 기능이 뛰어나도록 특별히 설계되어, 파일 시스템은 각 데이터 조각을 여러번 복제하거나 복사하고(복제 팩터라고 함) 개별 노드에 배포하여 다른 노드와 다른 서버 랙에 하나 이상의 복사본을 배치 202 | ``` 203 | 204 | #### ■ Apache HBASE (HDFS 컬럼 기반 DB) 205 | 206 | ```js 207 | - 뛰어난 Horizontal Scalability를 가지는 Distributed DB, Column-oriented store model 208 | - Hadoop 특유의 Sequential read/write를 최대한 활용해서 Random access를 줄임으로 Disk를 효율적으로 사용 209 | - Disk IO가 병목이 되기보다는 CPU나 RAM 용량이 병목이 되는 경우가 많음 210 | ``` 211 | 212 | ### ☞ ElasticSearch Cluster 213 | - 전체 데이터를 저장하고 모든 노드를 포괄하는 통합 색인화 및 NRT(Near Realtime) 검색 기능을 제공 214 | 215 | ```js 216 | - Cluster + Master-eligible/Data/Ingest/Tribe Node로 구성 217 | - 대용량 데이터 모두 저장을 위해서는 Storage 뿐만 아니라, Index를 유지를 위해 많은 메모리가 요구되어 좋은 성능의 Node들이 필요 -> 많은 비용 발생 218 | - 데이터 유실 발생 가능 -> 많은 운용 능력 요구됨 219 | - 비교적 적은 양의 데이터를 처리하는데 알맞음 220 | 221 | 1. 컬럼 지향 ( column - stride ) 222 | 2. 분산 데이터 스토어 223 | 3. 비공유 모델 ( shared-nothing ) 224 | 4. 검색에 용이한 인덱스 포맷. 역색인 구조 ( 검색 엔진에서 사용하고 있는 ) 225 | ``` 226 | 227 | ### ※ 분산/컬럼 지향 DB에서 TSDB 및 OLAP DB로 전환 및 통합 추세 228 | 229 | ### ☞ Time Series Database (TSD) 230 | 231 | #### ■ InfluxDB [![influxdb](https://img.shields.io/badge/TSD-InfluxDB-brightgreen)](https://www.influxdata.com/)  232 | 233 | ```js 234 | - 2013 년 InfluxData에 의해 구축, 대부분 Grafana와 함께 사용 235 | - No Schema, NoSQL 특징을 기반으로 하며 빠른 데이터베이스 스키마 수정이 가능 236 | - InfluxDB와 직접 바인딩하는 데이터 처리 엔진 및 많은 수의 실시간 Metric을 수집할 수 있는 50 개 이상의 Agent Set를 제공 237 | ``` 238 | 239 | ### ☞ OpenTSDB [![opentsdb](https://img.shields.io/badge/TSD-OpenTSDB-brightgreen)](https://www.opentsdb.net)  240 | 241 | - OpenTSDB는 Hbase 위에서 작성된 분산, 확장 가능한 TSD(Time Series Database) 242 | 243 | ```js 244 | - 수집 대상인 server 또는 network 장비들에 설치된 collector 클라이언트가 TSD서버로 전송하면 TSD가 HBase에 저장 245 | - OpenTSDB는 HTTP API, Web UI, Telnet을 통한 읽기/쓰기를 지원 246 | - openTSDB는 HBase 기반으로 작동을 하기 때문에 HBase가 이미 설치 되어 있어야 됨 (Hadoop 실행 -> hbase 실행 -> openTSDB 실행) 247 | ``` 248 | 249 | [Data Format] 250 | 251 | - Metric name 252 | - Unix timestamp(Epoch) 253 | - a Value(int64, float, JSON) 254 | - A set of tags 255 | 256 | [OpenTSDB Architecture] [![Sources](https://img.shields.io/badge/출처-OpenTSDB-yellow)](http://opentsdb.net/overview.html) 257 | 258 | ![OpenTSDB](images/opentsdb_architecture.png) 259 | 260 | ```js 261 | - 시계열 데이터를 매우 큰 규모로 저장해야 하는 필요성을 해결 262 | - Apache HBase에 구축 된 스키마 없는 Column 기반인 NoSQL의 데이터베이스 263 | - 분산 TSD 서버 인스턴스에 수억 개의 데이터 행 저장 가능 264 | ``` 265 | 266 | ### ☞ Apache Druid (incubating project) [![druid](https://img.shields.io/badge/Apache-Druid-blue)](https://druid.apache.org/)  267 | - A Scalable Timeseries Online Analytical Processing(OLAP) Database System 268 | 269 | [Druid Architecture] [![Sources](https://img.shields.io/badge/출처-Druid-yellow)](https://druid.apache.org/) 270 | 271 | ![druid](images/druid_architecture.png) 272 | 273 | ```js 274 | - Real-time/Historical/Broker/Coordinator/Deep/MySQL/Zookeeper Node로 구성 275 | 276 | - 대용량 데이터에 대한 실시간 집계 (Real Time Aggregations) <- 대용량 Spark Cluster 필요 277 | - 페타 바이트 크기의 데이터 세트에 대한 빠른 집계 쿼리를 위한 데이터웨어 하우징 솔루션 278 | - Druid는 대기 시간이 매우 짧은 쿼리에 중점을 두고 있으며, 수천 명의 사용자가 사용하는 응용 프로그램에 적합 279 | - Real-time, Multi-Tenancy, 컬럼 지향, 쿼리 속도 보장을 위해 만들어 짐 280 | - Lambda-Architecture : 실시간으로 들어오는 데이터(실시간 뷰)와 이전 데이터(배치 뷰)를 합해 쿼리 결과를 보여준다 281 | - Druid는 모든 데이터를 완전히 색인화 함 (Full Indexing) 282 | ``` 283 | 284 | #### ★ Lambda-Architecture 285 | 286 | ![lambda](images/lambda_architecture.png) 287 | 288 | [Batch Layer] 289 | 290 | ``` 291 | - Batch를 이용하여 데이터를 미리 계산 292 | - Batch Layer의 저장소에는 Raw Data 보관 293 | - Batch View의 데이터 부정확할 때 복구 가능 294 | - 새로운 View를 제공하고자할 때 기존 원본 데이터로 새로운 View의 통계 분석 가능 295 | - 일반적으로 Apache Hadoop 사용 296 | ``` 297 | 298 | [Speed Layer] 299 | 300 | ``` 301 | - Batch Layer 간격 사이의 데이터 Gap을 채우기 위한 실시간 집계 302 | - 주로 Apache Storm, Apache Spark 사용 303 | ``` 304 | 305 | [Serving Layer] 306 | 307 | ``` 308 | - Batch/Speed Layer의 Output을 저장 309 | - Client에서는 이 Layer에서 미리 계산된 데이터를 조회하기 때문에 빠른 응답이 가능 310 | ``` 311 | 312 | #### <설계/고려사항> 313 | ```js 314 | - Business Logic과 External dependency를 분리해야 함 315 | ex) Batch Layer에서 데이터를 가져오는 부분과 DB에 Insert하는 부분 분리... 316 | - Business Logic 및 외부 Service API 조회 부분에 Test Code 작성 317 | - 장애에 대한 영향도 전파가 없도록 구성 318 | - Shards, Replica 전략 319 | ``` 320 | 321 | #### ★ Kappa-Architecture 322 | 323 | ![kappa](images/kappa_architecture.png) 324 | 325 | ``` 326 | - Lambda 아키텍처의 단점인 다른 프레임워크를 사용하는 실행 부하 과다 경로와 실행 부하 미달 경로의 두 위치에서의 중복된 계산 논리와 두 경로의 아키텍처 관리에 따른 복잡성 문제를 해결 327 | - Lambda 아키텍처와 동일한 기본 목표가 있지만 중요한 차이점은 스트림 처리 시스템을 사용하여 단일 경로를 통한 모든 데이터 흐름을 처리 328 | - Event Data 변경 불가능하며, 일부가 아닌 전체가 수집되어 람다 아키텍처의 일괄 처리 계층과 약간 유사 329 | - Lambda 아키텍처의 Speed Layer와 비슷하게, 모든 이벤트 처리가 입력 스트림에서 수행되고 real-time view로 유지 330 | - 전체 데이터 집합을 다시 계산해야 하는 경우(Batch Layer가 수행하는 것과 동일), Stream을 재생하기만 하면 병렬화를 통해 적절하게 계산 완료 331 | ``` 332 | 333 | --- 334 | 335 | ### ■ Amazon S3, Azure ADLS & WASB, Google Cloud GCS 336 | - Cloud Connector를 사용하여 Cloud Storage에 저장된 데이터에 액세스하고 작업 가능 337 | 338 | [Cloud Storage Architecture] 339 | 340 | ![cloud_storage](images/cloud_storage.png) 341 | 342 | ```js 343 | - 분석할 데이터를 수집 후, Cloud Storage 서비스에서 직접 Hive 또는 Spark와 같은 Hadoop Echo System Application에 Load 344 | - 클러스터 외부에서 사용할 수 있도록 데이터를 클라우드 스토리지 서비스에 유지 345 | - 클라우드 스토리지 서비스에 저장된 데이터를 분석을 위해 HDFS로 복사한 다음 완료되면 클라우드로 다시 복사 346 | ``` 347 | 348 | #### <설계/고려사항> 349 | ```js 350 | - 데이터 사용에 대한 고가용성 보장 351 | - 압축 파일 포맷에 대한 고민 352 | - 장애에 대한 영향도 전파가 없도록 구성 353 | - Shards, Replica 전략 354 | ``` 355 | 356 | --- 357 | 358 | ## [Data 처리] 359 | 360 | #### ☞ Hadoop MapReduce (분산데이터 병렬배치 처리) 361 | 362 | [MapReduce Architecture] 363 | 364 | ![mapreduce](images/mapreduce.jpg) 365 | 366 | ```js 367 | - MapReduce는 Hadoop클러스터에서 대규모 데이터 세트를 병렬로 처리하기 위한 프레임워크로 데이터 분석에는 Map Process와 Reduce Process 단계가 사용됨 368 | - MapReduce에서는 반복적 애플리케이션과 대화형 애플리케이션 모두 병렬 작업 간에 더 빠른 데이터 공유가 요구되는데 복제/직렬화/디스크 I/O 등으로 인해 상당한 Overhead가 발생하여 데이터 공유 속도가 느림 369 | ``` 370 | 371 | [작동원리] 372 | 373 | ```js 374 | - MapReduce에서의 작업의 최상위 단위는 Work. work에는 일반적으로 map과 reduce 단계가 있지만 reduce 단계는 생략 가능 375 | - Map 단계에서 입력 데이터는 입력 분할로 나뉘어 Hadoop클러스터에서 병렬로 실행되는 맵 작업별로 분석 376 | - Reduce 단계에서는 병렬로 입력되는 맵 작업의 결과를 사용, reduce task는 데이터를 최종 결과로 통합 377 | ``` 378 | 379 | **[Data Warehouse]** 380 | 381 | - Hive : Hadoop에서 동작하는 data warehouse infra architecture, SQL을 MapReduce로 변환 382 | - Tajo : Hadoop 기반의 대용량 data warehouse 383 | 384 | ### ☞ Apache Spark™ [![spark](https://img.shields.io/badge/Apache-Spark-yellow)](https://spark.apache.org/)  385 | - 대규모 데이터 처리 및 라이브러리 세트 (Spark SQL/MLlib/GraphX)를 위한 통합 분석 엔진 386 | - 보다 빠르고 효율적인 MapReduce를 수행하기 위해 기본 데이터 구조로 RDD(Resilient Disributed Data)를 사용 : Immutable (Read-Only) 387 | - Spark = RDD (Resilient Disributed Data) + Scala Interface 388 | - Spark는 Hadoop을 저장과 처리 두 가지 방법으로 사용하는데 자체 클러스터 관리 연산을 갖고 있기 때문에 Hadoop은 저장 용도로만 사용 389 | 390 | [Apache Spark Stack] [![Sources](https://img.shields.io/badge/출처-Spark-yellow)](https://www.tutorialspoint.com/apache_spark/apache_spark_introduction.html) 391 | 392 | ```js 393 | - In-Memory 기반 오픈 소스 클러스터 컴퓨팅 프레임워크, 실시간 데이터 처리에 적합 394 | - 메모리를 활용한 아주 빠른 데이터 처리, Scala를 사용하여 코드가 매우 간단, interactive shell을 사용 395 | - Spark는 실시간 처리를 위한 독립적인 처리엔진으로 Hadoop과 같은 모든 분산 파일 시스템에 설치 가능 396 | - Spark는 스트리밍 데이터로의 전환을 편리하게 할 수 있다는 장점 397 | ``` 398 | 399 | ![spark_stack](images/spark.png) 400 | 401 | ```js 402 | - Infra Layer : spark가 독립적으로 기동할 수 있는 Standalone Scheudler가 존재(spark만 OS위에 설치하여 사용), Hadoop platform인 YARN (Yet Another Resource Negotiator) 위에서 기동되거나 Docker 가상화 플랫폼인 Mesos 위에서 기동 가능 403 | - Spark Core : Memory 기반의 분산 클러스터 컴퓨팅 환경인 Standalone Scheudler 위 에 올라감 404 | - Spark Library : 특정한 기능에 목적이 맞추어진 각각의 라이브러리가 동작되는데 빅데이타를 SQL로 핸들링할 수 있게 해주는 Spark SQL, 실시간으로 들어오는 데이타에 대한 real-time streaming 처리를 해주는 Spark Streaming, machine-learning을 위한 MLib, graph data processing이 가능한 GraphX가 있음 405 | ``` 406 | 407 | [Spark RDD] 408 | 409 | ![spark_rdd](images/spark_rdd.jpg) 410 | 411 | ```js 412 | - 중간 결과를 안정적 저장장치(디스크) 대신 분산 메모리에 저장해 시스템 속도를 높힘 413 | - 분산 메모리(RAM)가 중간 결과(JOB의 상태)를 저장하기에 충분하지 않으면 디스크에 그 결과를 저장 414 | ``` 415 | 416 | ### ■ Spark Streaming [![Sources](https://img.shields.io/badge/출처-SparkStreaming-yellow)](https://spark.apache.org/docs/latest/streaming-programming-guide.html) 417 | 418 | ![spark_streaming](images/spark_streaming.png) 419 | 420 | - 실시간 데이터 스트림의 확장 가능하고 높은 처리량, 오류 허용 스트림 처리를 가능하게 하는 핵심 스파크 API의 확장 421 | - 데이터는 Kafka, Flume, Kinesis 또는 TCP소켓과 같은 많은 소스로부터 수집 422 | - 실시간 입력 데이터 스트림을 수신하고 데이터를 배치로 나눈 다음 스파크 엔진에 의해 처리되어 최종 결과 스트림을 일괄적으로 생성 423 | 424 | ![streaming_flow](images/streaming_flow.png) 425 | 426 | - 연속적인 데이터 스트림을 나타내는 불연속 스트림 또는 DStream이라고 하는 높은 수준의 추상화를 제공 427 | - DStreams은 Kafka, Flume, Kinesis와 같은 소스로부터의 입력 데이터 스트림에서 또는 다른 DStreams에 높은 수준의 연산을 적용하여 생성 가능 428 | - Spark RDD와 사용 방법이 거의 유사하여 Lambda Architecture 구성에 좋음 429 | 430 | ### ■ Apache Flink [![Sources](https://img.shields.io/badge/출처-Flink-yellow)](https://flink.apache.org/) 431 | - 분산, 고성능, 항상 사용 가능한 정확한 데이터 스트리밍 애플리케이션을 위한 스트림 처리 프레임워크 432 | - Streaming model이 batch가 아닌 native 방식으로 스트림 처리에 대해 low latency 특성을 가짐 433 | - 아직 Immature Level... 434 | 435 | ![apache_flink](images/apache_flink.png) 436 | 437 | ### ■ Apache Ignite [![Sources](https://img.shields.io/badge/출처-Ignite-yellow)](https://ignite.apache.org/) 438 | - 노드 클러스터 전반에 걸쳐 대량의 데이터를 저장하고 계산하도록 설계된 오픈 소스 분산 데이터베이스, 캐싱 및 처리 플랫폼 439 | 440 | ![apache_ignite](images/ignite_architecture.png) 441 | 442 | 443 | #### <설계/고려사항> 444 | 445 | ```js 446 | - 데이터 처리 후 정합성 체크를 위한 원본 데이터 보관 447 | ``` 448 | 449 | --- 450 | 451 | ## [Data 분석] 452 | 453 | ### [Query] 454 | 455 | #### ■ Apache Impala [![impala](https://img.shields.io/badge/Apache-Impala-yellowgreen)](https://impala.apache.org)  456 | - Apache Impala는 Apache Hadoop을 실행하는 컴퓨터 클러스터에 저장된 데이터를위한 오픈 소스 MPP (대규모 병렬 처리) SQL 쿼리 엔진 457 | - MapReduce 기반의 Hive의 느린 응답성을 개선, 현재는 거의 사용하지 않음 458 | 459 | #### ■ Presto [![presto](https://img.shields.io/badge/Apache-Presto-yellowgreen)](http://prestodb.github.io)  460 | - Presto는 기가 바이트에서 페타 바이트에 이르는 모든 크기의 데이터 소스에 대해 대화 형 분석 쿼리를 실행하기위한 오픈 소스 분산 SQL 쿼리 엔진 461 | 462 | ### ☞ Apache Lucene [![lucene](https://img.shields.io/badge/Apache-Lucene-yellowgreen)](https://lucene.apache.org)  463 | - Apache Lucene은 무료 오픈 소스 검색 엔진 소프트웨어 라이브러리로 Doug Cutting이 Java로 작성 464 | 465 | [Apache Lucene Architecture] 466 | 467 | ![apache_lucene](images/lucene_architecture.png) 468 | 469 | ```js 470 | - 색인과 검색 기능 제공, 자바 기반 검색 Library 471 | - Lucene Core : 맞춤법 검사, 적중 강조 표시 및 고급 분석/토큰화 기능뿐만 아니라 Java 기반 색인 및 검색 기술을 제공 472 | - Solr는 XML/HTTP 및 JSON/Python/Ruby API와 함께 Lucene Core를 사용하여 구축된 고성능 검색 서버로, hit highlighting, faceted search, caching, 복제 및 웹 관리 Interface 473 | - PyLucene은 Core Project를 중심으로 한 Python Wrapper 474 | ``` 475 | 476 | ### ☞ Elasticsearch [![elasticsearch](https://img.shields.io/badge/Elasticsearch-v7.4-yellowgreen)](https://www.elastic.co/kr/)  477 | 478 | [Elasticsearch Context View] 479 | 480 | ![elasticsearch](images/elasticsearch.png) 481 | 482 | ```js 483 | - Lucene기반, 사이즈가 작은 데이터에 대한 속성검색/연관검색/실시간 검색에 용이함 (주요 커머스검색 용) 484 | - 자체 Master Node에서 관리, 강력한 API (RESTful 검색 및 분석 엔진) 485 | ``` 486 | 487 | **■ Apache Solr(솔라)** 488 | 489 | ```js 490 | - Lucene기반, 사이즈가 큰 데이터 검색에 용이에 문서 검색에 적합하나 색인주기가 느림 (주로 문서검색 용) 491 | - Apache ZooKeeper로 관리 492 | ``` 493 | 494 | **■ Scruid (Scala+Druid)** 495 | 496 | ```js 497 | - Scala에서 Druid Query를 쉽게 작성할 수있는 Open Source Library 498 | - Library는 Query를 JSON으로 변환하고 사용자가 정의한 Case Class의 결과를 구문 분석 499 | ``` 500 | 501 | ### [Tools] 502 | 503 | #### ☞ R 504 | - R은 통계 계산과 그래픽을 위한 프로그래밍 언어이자 소프트웨어 환경 505 | - R은 통계 소프트웨어 개발과 자료 분석에 널리 사용, 패키지 개발이 용이하여 통계학자들 사이에서 통계 소프트웨어 개발에 많이 쓰임 506 | - 방대한 양의 패키지와 즉시 사용 가능한 테스트 SET을 제공 507 | - R을 활용해서 데이터 마이닝(Data Mining)이 가능 508 | - R은 Google 'Visualization Chart API'로 google과 통신하여 데이터 고급 분석이 가능하고, 그 외에 Spotfire, Qlik View 등의 상업용 데이터 시각화 프로그램과 연동이 가능 509 | 510 | ### ☞ Python 511 | - 파이썬(Python)은 C 언어를 기반으로 한 오픈소스 고급 프로그래밍 언어로 데이터 분석에 사용되던 기존 C/C++ library를 흡수 512 | - 파이썬은 바로 사용할 수 있는 라이브러리(Library)와 통합 개발 환경(IDE, Integrated Development Environment)이 배포판과 함께 제공 513 | - 대표적인 라이브러리로는 Numpy와 Pandas가 있다. Numpy는 대형, 다차원 배열 및 행렬 등 이러한 배열에서 작동할 수 있는 높은 수준의 수학 함수 모음을 제공하며, Pandas는 관계형 또는 레이블이 있는 데이터 작업을 쉽고 직관적으로 처리할 수 있도록 설계된 라이브러리이다. 514 | 515 | --- 516 | 517 | ## [Data 시각화] 518 | 519 | #### ■ Apache Zeppelin [![zepplin](https://img.shields.io/badge/Apache-Zeppelin-ff69b4)](https://zeppelin.apache.org)  520 | 521 | ```js 522 | - 국내에서 주도하고 있는 오픈소스 프로젝트로써, Spark를 훨씬 더 편하고 강력하게 사용할 수 있게 해주는 도구 523 | - 분석 코드 작성, 작업 스케쥴링, 데이터 시각화, 대시보드 524 | - 여러 시스템에 대한 실행 결과를 얻기 위한 Interpreter들을 통해 Query 결과를 수집/시각화 525 | ``` 526 | 527 | ### ☞ Kibana [![kibana](https://img.shields.io/badge/ELK-Kibana-ff69b4)](https://www.elastic.co/kr/products/kibana)  528 | - Kibana는 로그 및 시계열 분석, 응용 프로그램 모니터링 및 운영 인텔리전스 사용 사례에 사용되는 오픈 소스 데이터 시각화 및 탐색 도구 529 | 530 | ```js 531 | - 로그 데이터 탐색에 사용되는 ELK Stack의 일부 532 | - Elasticsearch 클러스터에 저장된 로그 데이터를 기반으로 대시 보드를 탐색, 시각화 및 구축 할 수있는 도구 533 | - 주로 로그 메시지를 분석하는 데 사용 534 | - YAML 구성 파일 535 | - Elasticsearch에서만 작동하도록 설계되어 다른 유형의 데이터 소스를 지원 안함 536 | - 즉시 사용 가능한 경고 기능이 제공되지 않으며, noti를 추가하려면 Logz.io와 같은 호스팅된 ELK 스택을 선택하거나 ElastAlert를 구현하거나 X-Pack을 사용해야 함 537 | ``` 538 | 539 | ### ☞ Grafana [![grafana](https://img.shields.io/badge/OpenSource-Grafana-ff69b4)](https://grafana.com)  540 | - Grafana는 모든 데이터베이스를위한 오픈 소스 분석 및 모니터링 솔루션 541 | 542 | ```js 543 | - Graphite 또는 InfluxDB와 같은 시계열 데이터베이스와 함께 메트릭 분석에 사용되는 조합 544 | - Graphite, InfluxDB 및 Elasticsearch 및 Logz.io와 함께 가장 많이 사용되는 오픈 소스 시각화 도구 545 | - 시스템 CPU, 메모리, 디스크 및 I / O 사용률과 같은 메트릭을 분석하고 시각화하도록 설계 546 | - 전체 텍스트 데이터 쿼리를 허용하지 않음 547 | - .ini 구성 파일 548 | - 여러 시계열 데이터 저장소에서 작동 가능 549 | - 내장 된 사용자 제어 및 인증 메커니즘을 제공하여 외부 SQL 또는 LDAP 서버 사용을 포함하여 대시 보드에 대한 액세스를 제한하고 제어 가능 550 | - 사용 된 구문이 데이터 소스에 따라 다름 551 | - 버전 4.x부터 사용자가 선택한 알림 엔드 포인트(예: 이메일,Slack,PagerDuty,사용자정의 웹 후크)에 대해 경고를 트리거하는 조건부 규칙을 대시 보드 패널에 첨부 가능한 내장 경고 엔진을 제공 552 | ``` 553 | 554 | [Kibana vs. Grafana] 555 | 556 | ![google_trend](images/kabana_vs_grafana.png) 557 | 558 | --- 559 | 560 | ## [Data 관리] 561 | 562 | #### ■ Apache Oozie [![oozie](https://img.shields.io/badge/Apache-Oozie-blueviolet)](https://oozie.apache.org)  563 | - Hadoop의 Job을 관리하기 위한 서버 기반의 Workflow Scheduler System 564 | 565 | #### ■ Azkaban [![azkaban](https://img.shields.io/badge/LinkedIn-Azkaban-blueviolet)](https://azkaban.github.io)  566 | - Azkaban은 Hadoop job을 실행하기 위해 LinkedIn에서 만든 Batch Workflow Job Scheduler 567 | 568 | #### ■ Apache Ambari [![ambari](https://img.shields.io/badge/Apache-Ambari-blueviolet)](https://ambari.apache.org)  569 | - 시스템 관리자가 Hadoop 클러스터를 프로비저닝, 관리 및 모니터링하고 Hadoop을 기존 엔터프라이즈 인프라와 통합 할 수 있게 해 줌 570 | 571 | [Ambari Screenshot] 572 | 573 | ![ambari](images/ambari.png) 574 | 575 | ``` 576 | - RESTful API가 지원하는 직관적이고 사용하기 쉬운 Hadoop 관리 웹 UI를 제공 577 | - 여러 호스트에 Hadoop 서비스를 설치하기 위한 단계별 마법사를 제공 578 | - 클러스터에 대한 Hadoop 서비스 구성을 처리 579 | - 전체 클러스터에서 Hadoop 서비스를 시작, 중지 및 재구성하기위한 중앙 관리를 제공 580 | - Hadoop 클러스터의 상태 및 상태를 모니터링하기위한 대시 보드를 제공 581 | ``` 582 | 583 | ### ☞ Apache Airflow [![airflow](https://img.shields.io/badge/Apache-Airflow-blueviolet)](https://airflow.apache.org)  584 | - Airflow는 프로그래밍 방식으로 Workflow를 작성, 예약 및 모니터링 할 수 있는 Platform 585 | 586 | [Airflow Screenshot] 587 | 588 | ![airflow](images/airflow.png) 589 | 590 | ``` 591 | - Apache Airflow는 배치 스케쥴링(파이프라인) 플랫폼 592 | - Python 기반으로 실행할 Task(Operator)를 정의하고 순서에 등록 & 실행 & 모니터링 593 | - DAG(Directed Acyclic Graph, 비순환 방향 그래프)로 각 배치 스케쥴 관리 594 | ``` 595 | 596 | #### ■ Apache NiFi [![nifi](https://img.shields.io/badge/Apache-NiFi-blueviolet)](https://nifi.apache.org)  597 | - Process와 Process간 Data Flow Monitoring Tool 598 | 599 | ``` 600 | - Dataflow를 쉽게 개발할 수 있고, 시스템 간의 데이터 이동과 내용을 볼 수 있는 기능과 UI를 제공, 데이터의 input/output을 볼 수 있음 601 | ``` 602 | 603 | --- 604 | 605 | ## [Data 통합 서비스/솔루션] 606 | 607 | ### ■ Amazon Elasticsearch Service [![aws](https://img.shields.io/badge/AWS-Elasticsearch-lightgrey)](https://aws.amazon.com/ko/elasticsearch-service)  608 | 609 | ``` 610 | - 손쉽게 Elasticsearch를 배포, 보호, 운영 및 확장이 가능한 가동 중단이 없는 완전 관리형 서비스 611 | - 사용하는 만큼만 비용을 지불하며 사전 비용이나 사용 요건이 없음 612 | ``` 613 | 614 | [Amazon Elasticsearch Service Architecture] [![Sources](https://img.shields.io/badge/출처-Amazon-yellow)](https://aws.amazon.com/ko/blogs/aws/category/amazon-elasticsearch-service/) 615 | 616 | ![AES_architecture](images/aes_architecture.png) 617 | 618 | ### ■ Cloudera [![cloudera](https://img.shields.io/badge/Solution-Cloudera-lightgrey)](https://kr.cloudera.com/)  619 | 620 | ``` 621 | - Hadoop 기반 빅데이터 벤처기업의 대표적인 선두주자로 야후, 오라클 출신 등의 사람들에 의해 2008년 설립 622 | - CDH(Cloudera Distribution Including Apache Hadoop)라는 하둡 배포판이 아파치 하둡 배포판보다 훨씬 더 많이 사용됨 623 | - Hadoop System을 이용하려면 데이터 수집/저장/가공/분석/관리 tool들을 전부 일일히 설치 해야하는데, CDH는 이런 것들을 자동으로 설치해주고 GUI Interface로 관리 가능 624 | ``` 625 | 626 | [Cloudera Architecture] [![Sources](https://img.shields.io/badge/출처-Cloudera-yellow)](https://www.cloudera.com/documentation/enterprise/5-6-x/topics/cdh_intro.html) 627 | 628 | ![cloudera_architecture](images/cloudera_architecture.png) 629 | 630 | ### ■ Splunk [![splunk](https://img.shields.io/badge/Solution-Splunk-lightgrey)](https://www.splunk.com/ko_kr)  631 | - 로그 데이터, 실시간 이벤트 데이터 및 다양한 장비 데이터를 수집하고 모니터링하며 검색, 분류, 분석할 수 있는 엔진을 제공하는 통합 솔루션 632 | - Splunk Enterprise 8.0을 발표하면서 E2E Pipeline 구축을 위한 여러 솔루션들을 발표하였다. [Splunk Forum Korea 2019, 2019/12/11] 633 | [Forum Data](DIRECTORY.md). 634 | - 왠지 스플렁크의 파이프라인 구축을 위한 사업 확장이 더 빠르게 느껴진다. 커스터마이징만 잘 된다면 더 없이 좋은 솔루션이 될 듯... 635 | 636 | [Splunk Architecture] 637 | 638 | ![splunk_architecture](images/splunk_architecture.png) 639 | 640 | #### Splunk Core 641 | 642 | - DFS (Data Fabric Search) : 여러 다른 data store들을 연계하여 대용량 데이터 분석 가능 643 | - DSP (Data Stream Processor) : real-time streaming을 millisecond 안에 수집, 처리, splunk와 다른 목적지로의 배포 가능 644 | - Investigate : 쿼리, 데이터 세트 및 대시보드에 대한 팀 지식을 파악하여 신속하게 문제 해결 가능 645 | 646 | #### IT Operations 647 | 648 | - ITSI (IT Service Intelligence) : 모니터링 및 분석 솔루션을 사용하여 운영을 간소화하고, 문제 해결의 우선 순위를 지정하고, IT를 비즈니스에 맞게 조정 649 | - SignalFx : 클라우드 네이티브 전환의 모든 단계에 맞게 설계하여 클라우드 인프라 및 마이크로서비스의 모든 이점을 신속하게 실현 가능 650 | - VictorOps : 자동화되고 통찰력 있는 사고 대응 라우팅, 협업 및 리뷰를 통해 온콜 팀이 문제를 더 빠르게 발견하고 해결할 수 있도록 지원 651 | 652 | #### Business Flow 653 | 654 | - 빠르고 유연하며 직관적인 프로세스 마이닝을 통해 비즈니스 운영을 지속적으로 개선 655 | 656 | #### Security 657 | 658 | - Phantom : Phantom 보안 자동화를 통해 보안 작업 강화, 반복 작업을 자동화 659 | -------------------------------------------------------------------------------- /files/splunk_forum_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/files/splunk_forum_1.pdf -------------------------------------------------------------------------------- /files/splunk_forum_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/files/splunk_forum_2.pdf -------------------------------------------------------------------------------- /files/splunk_forum_3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/files/splunk_forum_3.pdf -------------------------------------------------------------------------------- /files/splunk_forum_4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/files/splunk_forum_4.pdf -------------------------------------------------------------------------------- /images/aes_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/aes_architecture.png -------------------------------------------------------------------------------- /images/airflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/airflow.png -------------------------------------------------------------------------------- /images/ambari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/ambari.png -------------------------------------------------------------------------------- /images/apache_flink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/apache_flink.png -------------------------------------------------------------------------------- /images/apache_kafka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/apache_kafka.png -------------------------------------------------------------------------------- /images/apache_kafka1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/apache_kafka1.png -------------------------------------------------------------------------------- /images/apache_spark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/apache_spark.png -------------------------------------------------------------------------------- /images/cloud_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/cloud_storage.png -------------------------------------------------------------------------------- /images/cloudera_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/cloudera_architecture.png -------------------------------------------------------------------------------- /images/druid_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/druid_architecture.png -------------------------------------------------------------------------------- /images/elasticsearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/elasticsearch.png -------------------------------------------------------------------------------- /images/hadoop_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/hadoop_architecture.png -------------------------------------------------------------------------------- /images/hdfs_architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/hdfs_architecture.jpg -------------------------------------------------------------------------------- /images/ignite_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/ignite_architecture.png -------------------------------------------------------------------------------- /images/kabana_vs_grafana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/kabana_vs_grafana.png -------------------------------------------------------------------------------- /images/kappa_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/kappa_architecture.png -------------------------------------------------------------------------------- /images/lambda_architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/lambda_architecture.jpg -------------------------------------------------------------------------------- /images/lambda_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/lambda_architecture.png -------------------------------------------------------------------------------- /images/lucene_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/lucene_architecture.png -------------------------------------------------------------------------------- /images/mapreduce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/mapreduce.jpg -------------------------------------------------------------------------------- /images/mapreduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/mapreduce.png -------------------------------------------------------------------------------- /images/opentsdb_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/opentsdb_architecture.png -------------------------------------------------------------------------------- /images/pipeline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/pipeline.jpg -------------------------------------------------------------------------------- /images/spark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/spark.png -------------------------------------------------------------------------------- /images/spark_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/spark_architecture.png -------------------------------------------------------------------------------- /images/spark_rdd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/spark_rdd.jpg -------------------------------------------------------------------------------- /images/spark_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/spark_stack.png -------------------------------------------------------------------------------- /images/spark_streaming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/spark_streaming.png -------------------------------------------------------------------------------- /images/splunk_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/splunk_architecture.png -------------------------------------------------------------------------------- /images/streaming_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mincloud1501/BigData/d1ee2d588f52c1afb93bc77e8fbac62642641464/images/streaming_flow.png --------------------------------------------------------------------------------