Schema on Write vs Schema on Read
Schema on Write : Schema on Read :
NoSQL 이란?
Schemaless, Schema-Free O(1) Unlimited Scale-out : 제약없는 확장이 가능하도록
key-value : String-Json 구조 document : 한 장의 데이터를 전부 JSON 으로 구조화 한 경우 Column-Family : 컬럼 기준으로 데이터를 가지고 있는 경우 - HBase, cassandra Graph : 그래프DB
DHT : Distributed Hash Table
어떤 데이터가 어떤 서버에 있는지를 파악해서 가져오는 것이 핵심이므로 데이터가 어디 분산되어 있는지 아는것이 중요하다. CAP 이론 : 모든 데이터베이스는 CAP에서 최대 2가지를 만족시킬 수 있다. DB가 새로 들어왔을때, DHT가 어던 방식으로 동작하지는지 를 파악한다면 그 DB가 어떤 특성을 가지는 지 대략적으로 알 수 있다.
HADOOP
HADOOP : 더그 커팅이 시작(루신과 너치의 창시자), 검색엔진에 특화된 상태로 제작하기 시작했다.
크롤링한 데이터가 워낙 컷기때문에 unlimited size, parallel 가 필수가 되었다.
Search Engine : 역인덱싱을 통해 문서의 위치를 파악한다. 추가로, 정배열인지 여부, 단어들이 떨어진 정도(GAP) 등을 검색 키워드와 비교해 우선순위로 나열한다.
-> Object Storage + Processing Engine(Data Locality) : 네크워크 I/O를 발생시키지 않고 데이터가 있는 곳에 로직이 가서 부하를 최소화시키겠다는 목표를 가지고 시작되었다.
Object 특징 : Immutable(Updata에 약함), No Directory, Metadata, Grouping
HDFS
하나의 블럭이 2GB라고 하면, 2GB - 256Mbyte x 8 Data Node 에 분산하여 저장한다. Name Node 에서 원 데이터에 대한 순서 정보등의 메타정보를 저장한다.
이 각 DataNode 에서 Mapper를 통해 파일조각마다 로직을 돌린다.(이 예제에서는 8개) 이후 Reducer를 통해 로직의 결과를 취합한다.
현재의 관점에서 보면 오히려 속도가 느리다(과거에는 빨랐으나!) -> 그래서 Hive -> Impala 등을 계속해서 학습해야 한다.
HDFS 디자인 오류
메차정보를 관리하는 NameNode에서는 데이터를 메모리에서 관리하는데, 데이터의 용량이 커저버리면 데이터를 넣기가 힘들다.
SPARK
HADOOP 에 비해 심플한 스택으로 구성하여 내부적으로 Java 기반 Scala를 통해 Java, Python, Scalar 를 통해 쉽게 구현할 수 있다.
RDD(Resilient Distributed DataSet) : 내부적으로는 분산되어 있는 데이터셋 -> Lazy - 느긋한 실행 (실제 작업이 바로 수행되는 것이 아니라, 일단 계획만 세워두고 명령이 들어오면 실행한다)
-> Data Frame 코드를 통해 작성 할 수도 있다.
-> Spark SQL 을 통해 SQL문으로 사용할 수 있다.
결국 다양한 레벨, 다양한 성능으로 할 수 있다. 쿠버네티스에 대한 지원이 많아지고 있다. 결국 Resource Manager는 YARN 에서 Kubernetes 로 점차 넘어가고 있다.
Data LakeHouse
Data Catalog + DataLake + Data House + Data Lineage Data Fabric : 모든 데이터를 하나의 공간(분산시스템)에 데이터를 모아놓아야 데이터를 제대로 분석할 수 있다 (= Data Lake) -> 이를 좀 더 구조화 한 것이 Data House 이다. -> Data Mesh : 원하는 시간에 원하는 공간에 데이터를 보내는 집합(data pipeline 의 집합) / 유툽 영상 하나
-> 결국 목표는 잘 만들어진 RDW(Real Time DW)를 만드는 것이 목표이다.
Elastic LoadBalancing 제품
ALB (Application Load Balancer) : NLB (Network Load Balancer) :
CLB (Classic Load Balanacer : 이전세대)
Auto Scaling
Auto Scaling 용 CloudWatch
EBS 볼륨
EC2 인스턴스를 위한, 사용자 지정 가능한 영구 블록 스토리지
RDS
AWS 관리형으로 지원되는 데이터베이스 서비스. 이런 서비스는 Private Subnet 에 올려두고, Public Subnet에 bastion 서버를 띄워서 이를 통해 접속한다.
다중 AZ를 통한 고가용성
Amazon DynamoDB
NoSQL 데이터베이스 테이블로, 캐시 서버처럼 많이 사용한다. 내부적으로 파티셔닝을 사용한다. 한 서버에는 여러 파티션 키가 있을 수 있지만, 파티션 키가 같다면 반드시 같은 서버에 저장돠어 있다.
AWS Lambda
서버를 프로비저닝하거나 관리하지 않고 코드를 실행할 수 있는 컴퓨팅
Exadata 특징
MPP InfraStructure : 분산키를 통해 여러 Node 에 균등 분산 저장된다. 데이터베이스를 디자인 할 때 MPP 에 대한 고민을 해야한다.
RedShift (Red:Oracle 은 비켜!)
columna
glue 에서 migration 하여 redshift 로 보낸다. mysql heatwave : mysql 에 대용량 인메모리 엔진을 붙였다.
Leader Node 에 쿼리가 인입되면 Compute-Node 에서 연산이 진행된다.
분산
- EVEN 분산
- KEY 분산
- ALL 분산
정렬
- Zone Map : 각 Block 에 대한 최대값 및 푀소값
MySQL, MySQL HeatWave
HeatWave : MySQL 네이티브 고성능 인메모리 분석기능 기존 OLTP 트랜젝션을 처리하는 공간은 그대로 있는 상태에서, 대용량 트랜젝션이 들어왔을 떄(옵티마이저에서 비용을 계산해서 OLTP 옵티마이저에서 돌지 분석쿼리 옵티마이저에서 돌릴 지 판단한다.) 최소한의 비용으로 옮겨 실행시킬 수 있는 VM(인메모리 서버)이 최대 250대까지 추가할 수 있다.
결국 OLTP 와 OLAP 의 기능을 동시에 수행할 수 있다.
Kafka
- schema registry : 정형 데이터 등을 강제한다. schema registry 에 데이터 형태를 저장해서 확인한다.
- kafka connect :
kafka streaming :
특징 1. Page Cache
- 특징 2. Heap Memory
- 굉장히 작은 메모리로도 띄울 수 있따.
- 특징 3. 파티션 별로 하나의 컨슈머만 바라볼 수 있다. 반대로 컨슈머는 여러 파티션에서 데이터를 가져올 수 있다.
- key 가 같으면 같은 파티션에 저장되며, 같은 파티션에 저장되면 순서가 보장된다.
- 이를 위해, 일반적으로 파티션의 개수와 컨슈머의 개수를 1:1로 맞춘다.
- replica & partition
- replica : 데이터 안정성을 의미, replica 의 개수는 broker 의 개수를 넘을 수 없다
- partition : 병렬성을 의미, partition 의 개수는 broker 개수와 관련없음
실습 1. kafka broker 간단하게 생성 후 컨슘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1. 서버 생성
2. java & kafka 설치
- sudo yum install -y java-1.8.0-openjdk-devel.x86_64
- wget https://downloads.apache.org/kafka/3.4.0/kafka_2.13-3.4.0.tgz
- tar xvf ./kafka_2.13-3.4.0.tgz
- ln -s kafka_2.13-3.4.0 kafka
3. Kafka Broker & Zookeeper 서버 시작
- cd ~
- cd kafka
- nohup ./bin/zookeeper-server-start.sh config/zookeeper.properties > zookeeper.log &
- nohup ./bin/kafka-server-start.sh config/server.properties > kafka.log &
4. 서버 상태 확인
- sudo netstat -anp | egrep "9092|2181"
5. Kafka Topic 생성
- ./bin/kafka-topics.sh --create --bootstrap-server 127.0.0.1:9092 --replication-factor 1 --partitions 1 --topic demotopic
- ./bin/kafka-topics.sh --list --bootstrap-server 127.0.0.1:9092
6. (새 터미널) Kafka Producer 에서 Topic 으로 메세지 전송
- cd ~
- kafka/bin/kafka-console-producer.sh --broker-list 127.0.0.1:9092 --topic demotopic
- (데모 메세지 입력)
7. (새 터미널) Kafka Comsumer 에서 Topic 메세지 컨슘
- cd ~
- kafka/bin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic demotopic --from-beginning
Kinesis
- 자유롭게, 방향성을 가지고 움직이는 유기물에 대한 메타포어
- app log, metric, clickstreams 등 greate for real-time big data
- automatically replicated synchronously to 3 AZ
Kinesis Streams Kinesis Analytics Kinesis Firehose : Fluentd, Logstash 등 과 같이 데이터를 이동시켜 적재하는 수단
- kafka의 partition(kinesis 에서는 shard)과 같이, shard 내에서는 순서를 보장한다.
AWS Kinesis vs AWS SQS
- AWS SQS는 Push 기반이므로, 타겟이 명확한 경우에 주로 사용한다.
- AWS Kinesis는 Pulling 기반, 타겟이 명확하지 않은 경우에 주로 사용한다.
- Kinesis 가 Kafka 와 유사하다고 볼 수 있다.
Kinesis Streams OverView
Kinesis Data Firehose
- fully managed service for delivering real-time streaming data to destinations
실습 2. AWS Kinesis
Kinesis Data Streams Collect streaming data with a data stream. Kinesis Data Firehose Process and deliver streaming data with data delivery stream. Kinesis Data Analytics Analyze streaming data with data analytics application.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
1. CLI(혹은 UI)통해 stream 생성하기
- aws kinesis create-stream --stream-name {STREAM_NAME} --shard-count {num}
- aws kinesis create-stream --stream-name kbi-0127-stream-03 --shard-count 3
- (생성확인) aws kinesis describe-stream-summary --stream-name kbi-0127-stream-03
2. kinesis stream 정보 확인 (UI를 통해 만든 경우)
- aws kinesis describe-stream --stream-name {STREAM_NAME}
- aws kinesis describe-stream --stream-name kbi-0127-stream-03
{
"StreamDescription": {
"KeyId": null,
"EncryptionType": "NONE",
"StreamStatus": "ACTIVE",
"StreamName": "kbi-0127-stream-03",
"Shards": [
{
"ShardId": "shardId-000000000000",
"HashKeyRange": {
"EndingHashKey": "113427455640312821154458202477256070484",
"StartingHashKey": "0"
},
"SequenceNumberRange": {
"StartingSequenceNumber": "49639752596900128308494528728222215180928912481501315074"
}
},
{
"ShardId": "shardId-000000000001",
"HashKeyRange": {
"EndingHashKey": "226854911280625642308916404954512140969",
"StartingHashKey": "113427455640312821154458202477256070485"
},
"SequenceNumberRange": {
"StartingSequenceNumber": "49639752596922429053693059351363750899201560843007295506"
}
},
{
"ShardId": "shardId-000000000002",
"HashKeyRange": {
"EndingHashKey": "340282366920938463463374607431768211455",
"StartingHashKey": "226854911280625642308916404954512140970"
},
"SequenceNumberRange": {
"StartingSequenceNumber": "49639752596944729798891589974505286617474209204513275938"
}
}
],
"StreamARN": "arn:aws:kinesis:ap-northeast-2:606693741204:stream/kbi-0127-stream-03",
"EnhancedMonitoring": [
{
"ShardLevelMetrics": []
}
],
"StreamCreationTimestamp": 1681264698.0,
"RetentionPeriodHours": 24
}
}
- stream list만 조회 시 : aws kinesis list-streams
3. 각 파티션 별로 데이터 주입하기
- aws kinesis put-record --stream-name {STREAM_NAME} --partition-key {KEY_VALUE} --data testdata1
- aws kinesis put-record --stream-name kbi-0127-stream-03 --partition-key 1 --data test-data-1
- aws kinesis put-record --stream-name kbi-0127-stream-03 --partition-key 2 --data test-data-2
- aws kinesis put-record --stream-name kbi-0127-stream-03 --partition-key 3 --data test-data-3
{
"ShardId": "shardId-000000000002",
"SequenceNumber": "49639737451705838649598369085240331161649542381053149218"
}
4. 데이터 iterator 가져오기 : 서버에 데몬을 띄워서 그 데몬으로부터 데이터를 가져온다.
- aws kinesis get-shard-iterator --shard-id {SHARD_ID} --shard-iterator-type TRIM_HORIZON --stream-name {STREAM_NAME}
- aws kinesis get-shard-iterator --shard-iterator-type TRIM_HORIZON --stream-name kbi-0127-stream-03 --shard-id shardId-000000000002
{
"ShardIterator": "AAAAAAAAAAF8Miy1L9tqmGs4XSD6JLnduPqN/jrjyLZ4wVi9Gi8PLlHlCDUjcA9peWWu7yXE3S00sfwwe5eeCdHuG/6OAL2+RX4XMNofXtyvUre1EfYPKzVkd5TzG+B+M+Qa1nN4Dh0ecshNN8k224RYJuOW+CKveXPabEXxBuzcvOzvoPeWoAF4AC28DVlkevnjKYn+gXbGjo3/72l+MxXpW7myRpV4ZJWaw6bDocwudlqLu2BIdw=="
}
+ {TRIM_HORIZON} : ShardIteratorType
+ TRIM_HORIZON 가장 오래된 레코드 부터 읽기 시작
+ LATEST 가장 최근부터 읽기 시작
5. 데이터 가져오기
- aws kinesis get-records --shard-iterator {ITERATOR_VALUE}
- aws kinesis get-records --shard-iterator AAAAAAAAAAF8Miy1L9tqmGs4XSD6JLnduPqN/jrjyLZ4wVi9Gi8PLlHlCDUjcA9peWWu7yXE3S00sfwwe5eeCdHuG/6OAL2+RX4XMNofXtyvUre1EfYPKzVkd5TzG+B+M+Qa1nN4Dh0ecshNN8k224RYJuOW+CKveXPabEXxBuzcvOzvoPeWoAF4AC28DVlkevnjKYn+gXbGjo3/72l+MxXpW7myRpV4ZJWaw6bDocwudlqLu2BIdw==
{
"Records": [
{
"Data": "dGVzdC1kYXRhLTE=",
"PartitionKey": "1",
"ApproximateArrivalTimestamp": 1681264829.537,
"SequenceNumber": "49639752596944729798891590010729539876406966935099539490"
},
{
"Data": "dGVzdC1kYXRhLTI=",
"PartitionKey": "2",
"ApproximateArrivalTimestamp": 1681264838.71,
"SequenceNumber": "49639752596944729798891590010730748802226582182749536290"
},
{
"Data": "dGVzdC1kYXRhLTM=",
"PartitionKey": "3",
"ApproximateArrivalTimestamp": 1681264846.113,
"SequenceNumber": "49639752596944729798891590010734375579685426620029468706"
}
],
"NextShardIterator": "AAAAAAAAAAF+59Knd41zsPBYBEJ+p0KcGZ0aeboeFocFinZQMjyFvIpLNooceStWtU7LCKxUuMjAjXgZ5W8KDQaII2ZDmCBzhI/aLG43DRaoPpbYv4AxgIsM3wFBrTrY+3/ycTcG4FhNR7QVqgpIKS+n6zOrof7CvicmEtdcBOa+9Tx1bHn7jCjmfXO49AbV03hp0VtlVmFeoumpwqai1FdfPVowawIkLXDkh7komA7UQCJdNT1lgw==",
"MillisBehindLatest": 0
}
6. kinesis 모니터링 활성화
- aws kinesis enable-enhanced-monitoring --shard-level-metrics ALL --stream-name {STREAM_NAME}
7. kinesis 데이터 스트림 삭제
- aws kinesis delete-stream --stream-name {STREAM_NAME}