# Redis 메모리 & 시간 측정 스크립트

 

Python으로 redis 테스트 시 메모리와 시간 측정을 위한 스크립트

#!/bin/sh
 
### help message
function help() {
/bin/cat << EOF
Usage :
    redis_test.sh [-n/--filename] filename [-f/--flushall] [-h/--help]
EOF
}
    
### flag
INPUT_FILE=False
  
### check parameter
while (("$#")); do
    case "$1" in
        -n|--filename)
            if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
                INPUT_FILE=$2
                shift 2
            else
                echo "[Error] Argument for $1 is missing" >&2
                exit 1
            fi
            ;;
        -f|--flushall)
            FLUSHALL=True
            shift
            ;;
        -h|--help)
            help
            exit 1
            ;;
        -*|--*) # unsupported flags
            echo "[Error] Unsupported flag: $1" >&2
            echo "$0 -h for help message" >&2
            exit 1
            ;;
        *)
            echo "[Error]: Arguments with not proper flag: $1" >&2
            echo "$0 -h for help message" >&2
            exit 1
            ;;
    esac
done
   
  
### check if input filename
if [ $# -eq 0 ] && [ "$INPUT_FILE" == "False" ]
  then
    echo "[Error] Please give me test file"
    help;
    exit 1;
fi
   
 
### flushall execution
if [[ "$FLUSHALL" == True ]]
then
    ok=`redis-cli FLUSHALL`
    echo "[Info] redis memory flush all : ${ok}"
fi
 
  
### check memory and time before test
before=`redis-cli INFO memory | grep 'used_memory:' | awk -F: '{print $2}'`
b=`echo "${before//[$'\t\r\n ']}"`
StartTime=$(date +%s)
  
### test execution
echo "[Info] test start"
################################################ 테스트 실행 파일
python3 $INPUT_FILE
echo "[Info] test end"
  
### check memory and time after test
after=`redis-cli INFO memory | grep 'used_memory:' | awk -F: '{print $2}'`
a=`echo "${after//[$'\t\r\n ']}"`
EndTime=$(date +%s)
  
used=$(expr $a - $b)
  
echo ""
echo ""
echo "####################################[result]################################################"
echo "[result] redis used memory ${used}"
echo "[result] It takes $(($EndTime - $StartTime)) seconds to complete this task."

 

 

[참고문서]
https://tyanjournal.com/tips/bash-command-line-option-parsing%ED%95%98%EA%B8%B0-%EC%98%B5%EC%85%98-%EB%B0%9B%EA%B8%B0/
https://knight76.tistory.com/entry/Redis-%EB%A0%88%EB%94%94%EC%8A%A4-%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%9B%84-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%B8%A1%EC%A0%95%ED%95%98%EA%B8%B0-redis-used-memory

 

To be continued.........

 

 

Made by 꿩

'IT > Bash' 카테고리의 다른 글

[Linux] SSH 공개키 설정  (0) 2022.03.28
[Bash] 스크립트 #! 의미  (0) 2021.10.19
[Bash] 터미널 jar 파일 생성  (0) 2021.10.05
[centos] java openjdk 설치 및 삭제  (0) 2021.10.05

# Transaction과 Isolation Level

 

Transaction(트랜잭션)이란? 논리적인 작업의 최소 단위이다.

트랜잭션이 왜 필요할까?

하나의 작업이 있는데 여러번 연산을 해야하는 상황이 있다.

예를 들어, 친구에게 계좌이체를 한다고 해보자.

계좌이체라는 하나의 작업은 2가지 연산으로 구성된다.

1. 내 계좌에서 돈을 출금하는 UPDATE하는 연산

2. 친구 계좌에 돈을 입금하는 UPDATE하는 연산

 

만약 1번 작업은 수행됐는데 2번 작업에서 에러가 나면

내 계좌에서 돈이 빠져나갔는데

친구는 돈을 못받은 상황이 되는 것이다.

 

즉, 트랜잭션은 하나의 작업을 수행하는데

여러 개의 연산을 하나로 묶어서

전부 실행되야지 일부만 실행되면 안된다. "All or Nothing - 원자성"

트랜잭션이 성공적으로 수행이 되면

내 계좌에서 빠져나간 돈만큼의 돈이

친구 계좌에 들어온다. 즉, 일관성을 만족해야 하는 것이다.

 

내가 돈을 송금하는 동안 다른 친구도 그 친구에게 돈을 송금할 수 있다.

계좌이체 트랜잭션이 동시에 들어오는 경우

다른 트랜잭션이 영향을 줄 수 없게

트랜잭션의 격리성이 보장되야 한다.

 

트랜잭션이 반영된 후에도 시스템 장애가 발생하더라도

트랜잭션 작업 결과는 손실되지 않고 영구적으로 반영되야한다.

이를 지속성이라 한다.

 

정리하자면
트랜잭션은 ACID라는 4가지 특성을 만족해야 한다.
(Atomicity-원자성, Consistency-일관성, Isolation-격리성, Durability-지속성)

이 중에서 Isolation에 대해 더

자세히 알아보려고 한다.

DB에는 Isolation Level(트랜잭션 격리 수준)이라는 게 있다.

이는 하나의 트랜잭션이 조회 또는 변경 작업 중인데

다른 트랜잭션이 들어온 경우

어느 수준까지 데이터를 조회를 허용할지에 대해서 설정하는 것이다.

 

SQL 표준 Transaction Isolation Level에는 4가지가 있다.

1. Read Uncommitted

2. Read Committed

3. Repeatable Read

4. Serializable

 

1. Read Uncommitted는 커밋되지 않은 데이터도 읽을 수 있는 수준이다.

Select를 수행하는 경우 트랜잭션이 COMMIT 되지 않은 데이터를 읽을 수 있다(dirty read)

업데이트되지 않은 데이터를 읽는 것은 무결성을 깨뜨릴 위험성이 높다.

하지만 동시성이 향상되는 효과가 있기도 하다.

Oracle, PostgreSQL에서는 지원하지 않는다.

commit되지 않은 내용이 읽힌다.

 

2. Read Committed는 커밋된 데이터만 읽을 수 있다.

Select문은 이전에 커밋된 데이터만 읽을 수 있고

Write 작업은 해당 트랜잭션이 끝날 때까지 waiting하게 된다.

트랜잭션에서 select가 여러번 있을때, 다른 트랜잭션에서 커밋을 하면

커밋 후의 select는 커밋된 데이터를 참조하게 된다.(non-repeatable read)

 

3. Repeatable Read는 트랜잭션 시작 시점 데이터만 읽을 수 있다.

동일 데이터 Write 작업은 Read Committed처럼 Waiting이 되고

이미 트랜잭션이 시작됐는데 다른 트랜잭션에서 데이터가 변경된 경우

해당 데이터를 Select할 때 변경이전의 트랜잭션 시작 지점의 데이터를 읽게 된다.

select for update는 커밋된 데이터를 읽게 된다.

 

4. Serializable은 모든 읽기 작업은 shared lock을 가진다.

즉, 다른 트랜잭션은 해당 데이터를 변경하지 못한다.

 

만약 트랜잭션마다 consistency level이 다르면 어떻게 동작할까?

각 트랜잭션 특성을 생각하면 된다.

Repeatable Read 트랜잭션과 Serializable 트랜잭션이 있다고 가정하면

Serializable은 기본적으로 select만으로도 shared lock이 걸리므로

Repeatable Read 트랜잭션은 해당 데이터를 읽을 수 없다.

 

DB는 동시에 여러 client가 사용하게 되므로

성능면에서 동시성이 중요하고

데이터를 생각한다면 안정성이 중요하다.

그러나 이 두개를 모두 만족할 수는 없다.

서비스의 특성을 잘 파악하고

최적의 isolation level를 선택해서 잘 활용해야 할 것이다.

 

참고로 테스트는 MariaDB 10.2.11버전을 사용하였다.

 

[참고문서]
데이터베이스 개론(김연희 지음)
jupiny.com/2018/11/30/mysql-transaction-isolation-levels/
hyunki1019.tistory.com/111
blogs.oracle.com/oraclemagazine/on-transaction-isolation-levels
effectivesquid.tistory.com/entry/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-Isolation-Level

To be continued.........

 

 

Made by 꿩

'Database > RDBMS' 카테고리의 다른 글

[MySQL/MariaDB] my.cnf 메모리 설정  (0) 2022.06.11
[PostgreSQL] Architecture  (0) 2022.03.01
[MariaDB] mariabackup 백업 & 복구  (0) 2022.02.15
[MySQL/MariaDB] 계정 정보 추출  (0) 2021.11.11
MVCC 동시성 제어  (0) 2021.02.06

# MVCC 동시성 제어

 

데이터베이스에는 많은 사용자들이 동시에 접근할 수 있다.

여러 사용자가 데이터를 변경할 수 있고

그와 동시에 데이터를 읽을 수도 있다.

그렇다면 데이터베이스는 어떻게 동시 접근을 처리할까?

 

MVCC는 Multi Version Concurreny Control의 약자로

Lock을 사용하지 않고 데이터 읽기의 일관성을 보장해주는 방법이다.

데이터에 접근하는 사용자는 접근한 시점의 데이터베이스의 스냅샷을 읽는다.

한 사용자가 데이터를 변경을 할 경우

데이터 변경이 완료(트랜잭션 commit)되기 전까지 변경사항을 볼 수 없다.

MVCC는 2가지의 구현방식이 있다.

 

1. MGA(Multi Generation Architecture)

MGA는 PostgreSQL에서 사용하는 방식이다.

어떤 데이터에 업데이트가 일어나면

기존 데이터는 그대로 두고 새로운 데이터가 추가된다.

그리고 기존 데이터에 표시가 된다.

 

MGA방식은 기존 데이터가 지워지지 않는다는 특징을 갖고 있다.

그래서 PostgreSQL는 주기적으로 VACUUM을 해줘야 하며

VACUUM을 하지 않을 경우, 실제 데이터보다 데이터 용량이 훨씬 큰 것을 발견할 수 있다.

또한 업데이트가 발생한 데이터의 물리적 위치가 변경이 되므로

업데이트를 할때마다 인덱스 수정작업이 항상 일어날 수 밖에 없다.

2. Rollback Segment 

Rollback Segment는 Oracle에서 사용하는 방식이다.

업데이트가 실행되면 기존 데이터 블록을 새로운 데이터로 변경하고

이전 데이터는 Rollback Segment에 보관된다.

 

데이터 변경 중, Select가 수행되면

Select쿼리는 SCN(System Commit Number)라는 고유한 번호를 가지고

데이터파일의 SCN을 비교한다.

이때, Select 쿼리의 SCN 번호보다 작은 데이터 파일의 SCN만 읽는다.

데이터가 변경되면 SCN이 변경되기 때문에

해당 데이터 파일은 변경 중 혹은 변경된 파일로 인식하고

Rollback Segment에서 이전 버전의 데이터 파일을 찾아 읽게 된다.

MGA와의 차이점은 업데이트 시 데이터의 물리적인 위치가 변경되지 않는다는 것이다.

즉, 업데이트 할때마다 인덱스 파일을 수정할 필요가 없고

Replication을 수행할 때 PK를 필수로 걸어 데이터를 판단할 필요가 없다.

물리적 위치를 사용하면 되기 때문이다.

게다가 이전 데이터가 보관되는 Rollback Segment에서 주기적으로 이전 데이터들을 지우기 때문에

PostgreSQL와 달리 VACCUM 작업을 할 필요가 없다.

 

 

[참고문서]
www.datanet.co.kr/news/articleView.html?idxno=116534
mysqldba.tistory.com/335
mangkyu.tistory.com/53

 

To be continued.........

 

 

Made by 꿩

'Database > RDBMS' 카테고리의 다른 글

[MySQL/MariaDB] my.cnf 메모리 설정  (0) 2022.06.11
[PostgreSQL] Architecture  (0) 2022.03.01
[MariaDB] mariabackup 백업 & 복구  (0) 2022.02.15
[MySQL/MariaDB] 계정 정보 추출  (0) 2021.11.11
Transaction과 Isolation Level  (0) 2021.04.07

# Kafka Connect 설정

 

필자가 설정하는 Kafka Connect 설정파일은 2개이다.
하나는 connect-distributed.properties 이고,
다른 하나는 connect-log4j.properties 이다.

 

connect-distributed.properties는 kafka connect 기본 설정 파일로 다음과 같다.

bootstrap.servers={kafka-ip1}:9092,{kafka-ip2}:9092,{kafka-ip3}:9092
 
producer.max.request.size=105000000
 
group.id=source-connect-cluster
 
#key.converter=org.apache.kafka.connect.json.JsonConverter
#value.converter=org.apache.kafka.connect.json.JsonConverter
#key.converter.schemas.enable=true
#value.converter.schemas.enable=true

key.converter=io.confluent.connect.avro.AvroConverter
key.converter.schema.registry.url=http://{schema-registry-ip1}:8081
value.converter=io.confluent.connect.avro.AvroConverter
value.converter.schema.registry.url=http://{schema-registry-ip2}:8081

offset.storage.topic=source-connect-offsets
offset.storage.replication.factor=3
offset.storage.partitions=25
 
config.storage.topic=source-connect-configs
config.storage.replication.factor=3
 
status.storage.topic=source-connect-status
status.storage.replication.factor=3
status.storage.partitions=5
 
offset.flush.interval.ms=10000
 
rest.host.name={kafka-connect-ip1}
rest.port=8083
 
rest.advertised.host.name={kafka-connect-ip1}
rest.advertised.port=8083
 
plugin.path=/home/kafka/plugins 

 

1. bootstrap.servers

Kafka 서버 ip와 port를 명시하면 된다.

 

2. producer.max.request.size

producer(kafka connector)가 메세지를 생산할때 최대 메세지 크기를 설정한다.

디폴트 최대 데이터 크기는 약 1MB 정도이다. 이 크기를 더 증가할 필요가 있을 경우 설정한다.

buffer memory 디폴트 최대 크기(buffer.memory)는 약 33MB이며

max.request.size를 33MB이상 설정하면 buffer memory 제한이 걸린다.

buffer memory 제한을 더 높이면 되지만 그럴 경우는 없고 있으면 문제가 있다는 것이다.

 

3. group.id

Kafka connect도 kafka처럼 클러스터를 형성할 수 있다.

Kafka connect 클러스터의 그룹을 구별하는 id로 같은 클러스터는 동일하게 설정한다.

 

4. key.converter / value.converter

메세지의 key와 value의 변환 클래스를 입력한다.

JsonConverter가 디폴트이며, AvroConverter를 사용하는 경우도 많은 것 같다.

Json보다 Avro 형식이 압축률이 더 좋다고 한다.

 

5. key.converter.schema.registry.url / value.converter.schema.registry.url

schema registry를 사용할 경우 설정한다.

 

6. offset.storage.*

Kafka Connector offset과 관련된 설정이다.

 

7. config.storage.*

Kafka Connector config와 관련된 설정이다.

 

8. status.storage.*

Kafka Connector status과 관련된 설정이다.

 

9. offset.flush.interval.ms

task들의 Kafka Connector offset을 커밋하는 interval 값이다.

 

10. rest.host.name / rest.port

REST API의 hostname과 port를 설정한다.

 

11. rest.advertised.host.name / rest.advertised.port

다른 worker들이 연결하는데 사용될 hostname과 port를 설정한다.

 

12. plugin.path

connector plugin이 들어있는 디렉토리 경로를 설정한다.

connect-log4j.properties 파일은 kafka connect에서 생성되는 로그설정에 관한 파일이다.

log4j.rootLogger=INFO, stdout, connectAppender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 
log4j.appender.connectAppender=org.apache.log4j.RollingFileAppender
log4j.appender.connectAppender.File=${kafka.logs.dir}/connect.log
log4j.appender.connectAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.connectAppender.MaxFileSize=100MB
log4j.appender.connectAppender.MaxBackupIndex=50
log4j.appender.connectAppender.append=true
 
connect.log.pattern=[%d] %p %X{connector.context}%m (%c:%L)%n
 
log4j.appender.stdout.layout.ConversionPattern=${connect.log.pattern}
log4j.appender.connectAppender.layout.ConversionPattern=${connect.log.pattern}
 
log4j.logger.org.apache.zookeeper=ERROR
log4j.logger.org.reflections=ERROR

 

1. log4j.appender.connectAppender

첫 설치시 DailyRollingFileAppender로 설정이 되어있을 것이다.

DailyRollingFileAppender는 매시간 또는 매일 마다 로그파일이 새로 생기지만

파일 최대크기와 파일 최대개수를 지정할 수 없다는 단점이 있다.

개인적으로는 DailyRollingFileAppender을 추천한다.

 

2. log4j.appender.connectAppender.File

로그 파일이 생성되는 경로와 로그파일 이름을 설정한다.

 

3. log4j.appender.connectAppender.MaxFileSize

로그 파일의 최대 크기를 설정한다.

 

4. log4j.appender.connectAppender.MaxBackupIndex

로그 파일의 최대 개수를 설정한다.

 

5. log4j.appender.connectAppender.append

kafka connect가 restart시 로그파일에 append할 것인지에 대한 설정이다.

 

5. connect.log.pattern

로그 출력시 어떤 형식으로 나올지에 대한 설정이다.

중간에 {connector.context}를 넣으면 해당 로그가 어떤 커넥터에서 나온건지 알 수 있다.

To be continued.........

 

 

 

Made by 꿩

'CDC > Kafka Connect' 카테고리의 다른 글

[Kafka Connect/Debezium] SMT 란?  (0) 2021.10.24
Kafka Connect란?  (0) 2021.01.09

# Kafka Connect란?

 

Kafka의 구성은 Producer, Consumer, broker로 되어있다.

 

Producer는 카프카 메세지를 생산하는 주체이고,
Consumer는 카프카 메세지를 소비하는 주체이며,
Broker는 카프카 메세지를 저장하는 서버이다.

 

각 Broker는 여러개 topic을 가지고 있으며 이 topic에 메세지가 저장된다.

 

Kafka Connect는 데이터소스와 Kafka를 연결해주는 매개체이다.
Kafka Connect에는 Connector를 이용하여 데이터소스와 연결한다.
다시말해서, Kafka Connector가 Producer와 Consumer 역할을 한다고 보면 된다.

 

Producer 역할을 하는 Kafka Connector를 Source Connector라 하고,
Consumer 역할을 하는 Kafka Connector를 Sink Connector라 한다.

출처: https://debezium.io/documentation/reference/1.3/architecture.html

 

위의 그림은 kafka Source Connector 오픈소스인 Debezium 공식문서에서 가져온 그림이다.
그림을 보면, MySQL과 PostgreSQL의 데이터 소스에서 데이터가 Debezium Source Connector에 의해 Kafka에 저장이 된다. 그리고 메세지들은 Sink Connector에 의해 다양한 데이터 소스로 전달할 수 있다.

 

다음은 Kafka Connector가 만들어 내는 메세지의 구조이다.

 

Message는 Key와 Value로 구성되어 있으며,
각 Key와 Value는 Schema와 Payload로 구성되어 있다.

 

여기서 Key는 PK와 같이 데이터를 식별할 수 있는 정보가 들어있고
Value는 데이터의 전체 값이 들어있다.

 

Payload는 데이터 값이 저장이 되며, 이 데이터 값의 데이터 타입이 Schema에 명시되어 있다.

 

동일한 메세지가 계속 들어오는 경우 Schema가 중복이 되어 불필요하게 데이터 용량을 잡아먹게 된다.
이를 위해 Kafka Connect는 Schema Registry를 활용한다.

출처: https://medium.com/@gaemi/kafka-%EC%99%80-confluent-schema-registry-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EC%8A%A4%ED%82%A4%EB%A7%88-%EA%B4%80%EB%A6%AC-2-bfa96622a974

 

Schema Registry는 Key와 Value에 명시된 Schema를 따로 저장하며,
Kafka Connector는 Schema 대신 Schema Registry의 Schema 번호를 명시하여 메세지 크기를 줄인다.

 

Kafka Connect는 REST API를 이용하여 Connector를 설정할 수 있다.

# kafka connect 실행
./bin/connect-distributed.sh -daemon ./config/connect-distributed.properties

# kafka connect 실행확인
curl -s "http://{ip}:8083"           
{"version":"2.4.1","commit":"c57222ae8cd7866b","kafka_cluster_id":"nZrPY3j5SKOUwqeGk68dsg"}

# 사용할 수 있는 플러그인
curl -X GET -s "http://{ip}:8083/connector-plugins"
[{"class":"io.confluent.connect.elasticsearch.ElasticsearchSinkConnector","type":"sink","version":"5.5.1"},{"class":"io.confluent.connect.jdbc.JdbcSinkConnector","type":"sink","version":"5.5.1"},{"class":"io.confluent.connect.jdbc.JdbcSourceConnector","type":"source","version":"5.5.1"},{"class":"io.confluent.connect.s3.S3SinkConnector","type":"sink","version":"5.5.1"},{"class":"io.confluent.connect.storage.tools.SchemaSourceConnector","type":"source","version":"2.4.1"},{"class":"io.debezium.connector.mysql.MySqlConnector","type":"source","version":"1.3.1.Final"},{"class":"io.debezium.connector.postgresql.PostgresConnector","type":"source","version":"1.2.1.Final"},{"class":"org.apache.kafka.connect.file.FileStreamSinkConnector","type":"sink","version":"2.4.1"},{"class":"org.apache.kafka.connect.file.FileStreamSourceConnector","type":"source","version":"2.4.1"},{"class":"org.apache.kafka.connect.mirror.MirrorCheckpointConnector","type":"source","version":"1"},{"class":"org.apache.kafka.connect.mirror.MirrorHeartbeatConnector","type":"source","version":"1"},{"class":"org.apache.kafka.connect.mirror.MirrorSourceConnector","type":"source","version":"1"}]

# kafka connector 확인
curl -X GET -s "http://{ip}:8083/connectors"
["test-connector"]

# kafka connector 설정확인
curl -X GET -s "http://{ip}:8083/connectors/test-connector/config"

# kafka connector 상태확인
curl -X GET -s "http://{ip}:8083/connectors/test-connector/status"

# kafka connector 삭제
curl -X DELETE -s "http://{ip}:8083/connectors/test-connector"

 

Kafka Connect를 사용해보고자 한다면,

 

Source Connector 오픈소스인 Debezium을 추천한다.
Sink Connector는 Confluent사에서 개발한 Connector를 이용하자.

 

Confluent hub(https://www.confluent.io/hub/)에는 Confluent에서 개발한 다양한 Connector를 다운받을 수 있다.
각 Connector가 Source인지 Sink인지 명시가 되어 있으며 무료 라이센스일 것이다.

 

 

참고자료
debezium.io/documentation/reference/1.3/architecture.html
mongsil-jeong.tistory.com/35

 

To be continued.........

 

 

 

Made by 꿩

'CDC > Kafka Connect' 카테고리의 다른 글

[Kafka Connect/Debezium] SMT 란?  (0) 2021.10.24
Kafka Connect 설정  (0) 2021.01.09

# 관악산 등산기 (신림역~관악산공원~연주대)

 

깨끗한 가을 날씨에 이끌려 오랜만에 등산을 하기로 마음을 먹고 관악산으로 향했다.

총 산행시간은 3시간이었으며

관악산입구 - 연주대 - 관악산입구로 다시 내려오는 루트를 이용하였다.

올라가는데 1시간 반

쉬는거 + 내려가는데 1시간 반이 소요되었다.

 

관악산은 신림역에서 버스를 타고 조금 들어가야 한다.

나는 신림역 4번출구에서 조금 걸어가서 나오는 버스정류장에서

5528번 버스를 타고 관악산 입구로 향했다.

 

큰 기와 입구가 관악산 공원의 시작을 알려준다.

코로나가 한창임에도 나처럼 등산온 사람들이 생각보다 많았다.

 

서울 둘레길 표지판이 있는데

둘레길을 이용하면 사당역에서 낙성대 ~ 서울대입구 ~ 석수역까지 갈 수 있다고 나온다.

물론 관심은 없다. 단지 블로그에 사진 하나라도 넣기 위해 찍어봤다.

 

관악산 공원 초입

깨끗한 하늘과 새소리, 맑은 공기가 자연을 느끼게 해준다.

너무 컴퓨터만 하면서 피폐해진 내 정신을 회복시켜주는 것 같았다.

 

가다보면 다음의 표지판이 나오는데

어디로 가도 상관이 없어보였다.

표지판이 낡아서 교체해야할듯;;

 

아무생각없이 쭉 올라가고 있었는데

뭔가 이상한 점이 느껴졌다.

아니나다를까 나는 관악산이 아닌

삼성산을 가고 있던 것이었다.

 

다시 내려가는 길 바닥에

떡하니 연주대는 옆으로 가라는 표시가 써있었다.

나처럼 올라가다 잘못된 방향인걸 깨닫고

다시 내려가는 사람이 좀 있었나보다.

내려가는 길에 표시를 해둔 것을 보니;;

 

다음의 정자가 보이면

관악산 연주대로 제대로 가고있는 것이 맞다는 걸 의미한다.

헷갈리지 말자.

 

올라가다보면 서울대 공대 표지판이 보인다.

서울대 공대에서 올라가면 헷갈리지 않고

더욱 쉽게 관악산에 올라갈 수 있을 듯하다.

 

아무 생각없이 올라가다보면 정상에 다다른다.

사실 난 연주암이 보이는 이곳이 연주대인 줄 알았지만

조금 더 가야했었다.

 

난 혼자 올라왔기에...

혼자서 내 그림자를 찍어줄 수 밖에 없었다느ㄴ..

다들 단체 혹은 같이 등산하러 왔길래

소심하게 혼자서 찍어봤다.

 

저 멀리 보이는 기상관측소 쪽으로 가야 연주대가 나온다.

 

연주대에서 쉬고 있는 사람들

마스크는 필수이다.

 

이제 왔던 길로 다시 돌아가야 할 시간이다.

아이스크림 장수도 연주대 정상에서 볼 수 있다.

 

나는 항상 내려가는게 너무 싫다.

무릎도 아프고 재미도 없기 때문이다.

그래서 그런가 항상 내려가는 길에는 딴 생각을 하곤 한다.

지금까지 어떻게 살아왔고

내가 어떤 사람이었는지

내 자신을 성찰하게 된다.

 

이런저런 생각을 하면서 반성도 하게 되고

내 생각을 정리할 시간이 된다.

그냥 집에만 있으면 여유시간이 있어도 내 자신을 되돌아보지 않는다.

게임을 하든가 잠을 자든가 사람을 만나지

나에 대한 생각은 하지 않는다.

 

저 멀리 다시 관악산 공원 기와입구가 보인다.

생각보다 빨리 올라가서 총 소요시간이 예상보다 적게 걸렸다.

하지만 북한산이나 다른 산에 비해 재미있지는 않았다.

그래도 가까운 산이니 자주 가지 않을까 싶다.

 

나에겐 등산이란

힘들게 올라가 정상에서의 기쁨을 만끽하기 위함이기도 하지만

나 자신에 대해서 다시한번 생각을 하게 해주는 시간인 것 같다.

To be continued.........

 

 

Made by 꿩

'등산' 카테고리의 다른 글

[등산] 덕유산 등산기  (0) 2022.07.15
소백산 등산기 (희방사~연화봉~비로봉~삼가동)  (0) 2019.12.30

# 소백산 등산기 (희방사~연화봉~비로봉~삼가주차장)


가끔씩 등산을 다니며 사진을 찍지만

휴대폰에 저장되어 있는 사진보다

블로그에 남겨두는 것이 더 의미가 있을 듯하여

앞으로 남겨두려고 한다.


총 산행시간은 약 6시간이었으며

희방사역 - 희방사 - 연화봉 - 제1연화봉 - 비로봉 - 삼가주차장

9시 14분 - 10시 15분 - 11시 50분 - 12시 30분 - 13시 24분 - 15시 20분

정도가 걸렸다.


이번에 간 산은 소백산으로 당일치기로 다녀왔다.

청량리 6시 40분 기차를 타고 달려 9시 14분 희방사 역에 도착하였다.


희방사 역은 매우 작았으며

등산객이 많아서 그런지

역 자체가 깔끔하고 옛날 건물은 아니었다.


몇몇 블로그 글을 보니

어떤 분들은 희방사역에서 택시를 타고

희방사 주차장까지 올라간다고 하던데

나는 걸어올라갔다.


시골길을 걷기도 했지만

아스팔트 길을 걸어올라가야 하기도 했다.


올라가다보면 연화봉 가는길 입구가 나온다.

참고로 희방사 등산로를 이용하기 위해서는

희방사 문화재 보존요금(?)을 내야하며 어른은 2000원이다.

물론, 희방사 구경은 전혀 하지 않았다ㅎ


시원한 폭포도 만나고 자연을 느끼며 올라가다보면

어느샌가 희방사에 도착하게 된다.


점차 눈이 많아지는 것을 느꼈다.

올 겨울은 매우 따뜻해서 눈을 제대로 보지 못했는데

제대로 쌓인 눈과 고드름을 보면서

겨울다운 겨울을 느꼈다.


위로 갈수록 눈이 많이 쌓였으며

나무에도 눈이 쌓여 나뭇가지가 하얗게 보였다.


위쪽은 완전히 겨울왕국

온 세상이 하얀 눈으로 뒤덮였다.

마치 한국이 아닌 다른 나라에 온 듯한 느낌이랄까...

눈을 구경하며 허기진 배를 채웠다.


드디어 연화봉 도착!

옆에 있던 할아버지에게 사진을 찍어달라 부탁했다는;; ㅎㅎ

물론 블로그에 내 사진을 올리진 않는다.


제1연화봉으로 가보기 전 앞으로 가야할 곳을 찍어보았다.

이때 능선을 타고 가므로

별로 힘들지 않을거라 생각했지만

이때부터 비로봉까지가 너무 힘들었다.

온통 눈으로 뒤덮인 산

여기는 어디 나는 누구..

올 한해 구경할 눈은 여기서 실컷 구경한 듯


사진으론 예쁘지만

눈이 저렇게 뭉쳐있다는 것은

엄청나게 추웠다는 것을 반증한다.

다행이도 겹겹이 입고와서 춥진 않았다.


제1연화봉은 정상이라는 느낌이기보다는

비로봉을 가기 위한 중간 도착지 느낌이다.

실제로 저게 끝이다.


저 멀리 보이는 비로봉을 위해 출발

비로봉이 거의 다왔다.

하지만 너무 힘들어서 정말 한발자국씩 겨우겨우 걸어갔다.

쉬고 싶은 마음이 간절했지만

바람이 너무 거세어서 빨리 걸음을 재촉할 수 밖에 없었다.


비로봉 정상에서 보이는 산줄기

이게 백두대간일까?


이제 삼가주차장으로 내려가려고 한다.

원래는 비로봉 말고 좀 더가서 국망봉에서 초암사쪽으로 내려오려고 했다.

힘들고 춥기도 하고....

무엇보다 기차타고 집에 다시오면 시간이 밤 00시가 될 듯 싶어

아쉽지만 도중에 내려가기로 결정했다.


내려오다가 발견한 버스 시간표!!!!

택시를 타고 기차역까지 갈 필요가 없어졌다.

국립공원은 인프라가 너무 잘되어있어서

참 좋은 것 같다는 생각이 ㅎㅎ


내려오는 길은 항상 무릎이 아프다.

그래도 거센 바람은 없어서 한결 편하고 즐거웠다.


다 내려오면 삼가주차장 화장실이 보인다.

네이버 지도로 찾아보니 여기가 아니라 좀 더 밑으로 내려가서

버스를 타라고 알려줬다.


그러나.. 마음씨 좋으신 할아버지가

풍기역까지 차를 태워주셔서

더 빠른 기차를 타고

생각보다 빨리 집에 도착할 수 있었다.


소백산은 눈이 내린 것도 예쁘지만

봄에 와서 꽃 구경하는 것도 좋을 것 같아보인다.

중간중간 식물 안내 표지판도 많았고

대부분 봄과 관련된 것 같았다.


나중에 잊혀질 때 쯤 다시오지 않을까싶다.

To be continued.........




Made by

'등산' 카테고리의 다른 글

[등산] 덕유산 등산기  (0) 2022.07.15
관악산 등산기 (신림역~관악산공원~연주대)  (0) 2020.10.04

#ClickHouse 설치

 

 

ClickHouse는 오픈소스 DBMS로

일반적인 DBMS와 다르게 컬럼기반 DBMS이다.

 

컬럼기반 DBMS란?

데이터를 row 단위가 아닌 column 단위로 저장하고 관리하는 시스템을 말한다.

 

왜 기존의 DBMS를 변형한 컬럼기반 DBMS가 등장했을까?

데이터가 점점 많아지면서

 통계정보를 산출하고 자료를 분석을 하는데 시간이 많이 발생하게 되었다.

즉, 기존의 DBMS로 OLAP를 하는 경우 시간이 많이 발생하기 때문에

컬럼기반 DBMS가 등장하게 되었다.

 

컬럼기반 DBMS는 컬럼 단위로 저장이 되어있어서

동일한 컬럼 내에서 데이터를 갖고오는데 효율이 좋은 구조로

OLAP에 굉장히 잘 맞게 구성되어 있다.

 

ClickHouse는 컬럼기반 DBMS로 러시아 쪽에서 개발한 것으로 알고 있다.

이번 포스팅은 ClickHouse 설치하고

공식 문서에서 제공하는 샘플 데이터까지 설치하는 과정을 적으려 한다.

 

ClickHouse 설치

# yum install yum-utils
# rpm --import https://repo.yandex.ru/clickhouse/CLICKHOUSE-KEY.GPG
# yum-config-manager --add-repo https://repo.yandex.ru/clickhouse/rpm/stable/x86_64
# yum install clickhouse-server clickhouse-client
# /etc/init.d/clickhouse-server start
# clickhouse-client

설치는 매우 간단하다.

다음과 같이 ClickHouse 콘솔이 나오면 모두 설치가 된 것이다.

 

사용자 생성

# /etc/init.d/clickhouse-server stop
# vi /etc/clickhouse-server/user.xml

<user>
...

<사용자명>
    <password_sha256_hex> sha256 비밀번호 입력 </password_sha256_hex>
    <networks incl="networks" replace="replace">
            <ip>::1</ip>
            <ip>127.0.0.1</ip>
    </networks>
    <profile>default</profile>
    <quota>default</quota>
</사용자명>

</user>

 

서버를 잠시 멈추고

사용자 설정파일에서 사용자를 추가한다.

 

참고로 sha256 비밀번호를 생성하는 법은 다음을 참고한다.

# echo -n "비밀번호" | sha256sum | tr -d '-'
13a5c202e320d0bf9bb2c6e2c7cf380a6f7de5d392509fee260b809c893ff2f9

 

서버를 다시 시작하고 설정한 사용자로 클라이언트에 접속한다.

# /etc/init.d/clickhouse-server start
# clickhouse-client -h 127.0.0.1 -u 사용자이름 --password 비밀번호

 

SQL Editor - Tabix

ClickHouse 내부에는 SQL Editor인 Tabix가 있는데

Tabix로 ClickHouse를 실행해보자.

 

서버 설정파일에 Tabix 주석을 해제한 후 ip를 연다.

# vi /etc/clickhouse-server/config.xml
# 다음의 내용 주석 제거

<http_server_default_response><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></http_server_default_response>

<listen_host>::</listen_host>

 

서버를 재시작한 후

크롬 브라우저에서 http://ip주소:8123을 접속하면 Tabix 페이지가 나올 것이다.

사용자를 생성하지 않았다면 default로 하고 config.xml에 설정한 비밀번호를 입력한다.

 

ClickHouse 공식 홈페이지에 샘플 데이터가 있으므로

다운받아 테스트 해보는 것이 도움이 될 것이다.

 

만약 다른 DBMS와 비교를 하고 싶다면 클릭하우스 샘플 데이터를 마이그레이션해야 하는데

내 경험상 DBeaver로 쉽게 하려고 했지만 여러가지 문제로 데이터를 옮기지 못했다.

ClickHouse는 내부적으로 MySQL 엔진을 지원하고 있어서

해보진 않았지만 MySQL쪽으로 마이그레이션은 쉽지 않을까 싶다.

다른 DB로 해본다면

Tool을 사용하기보다 직접 컬럼을 수정해서 CSV나 JSON으로 하는 것이 더 빠를 것이라 생각한다.

 

클릭하우스 공식문서 - https://clickhouse.yandex/docs/en/

 

 

Made by 꿩

 

 

+ Recent posts