'데이터베이스'에 해당되는 글 57건

데이터베이스/Elasticsearch

Elasticsearch에서 synonyms.txt로 동의어 필터 만들어서 사용하기

elasticsearch에서 검색기능을 넣다가 2080이라는 키워드를 검색 했을때와 이공팔공이라는 검색어를 입력했을 때 두개 모두 동일한 데이터를 출력하도록 지정하고 싶었다.

그래서 synonyms 필터를 만들기로 했다.

우선 synonyms 필터를 만들어서 사용하기 위해서는 동의어에 대한 정리가 되어있는 사전을 만들어야 한다.

사전 생성 방법은 다음과 같고 아래 링크를 참조해서 간단하게 사전을 만들었다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-tokenfilter.html

파일명은 synonyms.txt이고 내용은 다음과 같다.

synonyms.txt

노레바,noreva,노래바
airpods,에어팟,airpod,airpot
2080,이공팔공

 

동의어 정리 사전을 elasticsearch에 넣어줘야하고 경로는 다음과 같다.

/usr/share/elasticsearch/config/analysis



나는 docker를 사용하기 때문에 생성한 파일을 다음 명령어를 통해 위치시켰다.

docker cp synonyms.txt elastic6.4:/usr/share/elasticsearch/config/analysis



그럼 이 필터를 사용하기 위해서 인덱스를 만들 때 설정을 달아서 추가해주자.
간단하게 keyword 하나만 존재하는 인덱스를 만들고 synonyms filter를 사용하게 해보자

여기서 사용하 tokenizer는 nori_tokenizer를 사용했다.
간단한 예제니 보면 바로 이해할 수 있다.

PUT synonyms_test
{
  "settings": {
      "index" : {
          "analysis" : {
              "analyzer" : {
                  "synonym" : {
                      "tokenizer" : "nori_tokenizer",
                      "filter" : ["synonym"]
                  }
              },
              "filter" : {
                  "synonym" : {
                      "type" : "synonym",
                      "synonyms_path" : "analysis/synonyms.txt"
                  }
              }
          }
      }
  },
  "mappings": {
    "_doc": {
      "dynamic": "false",
      "properties": {
        "keyword": {
          "type": "text",
          "analyzer": "synonym",
          "search_analyzer": "synonym",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

데이터를 2080과 이공팔공 두개를 삽입했다.

POST synonyms_test/_doc
{
  "keyword":"2080"
}

POST synonyms_test/_doc
{
  "keyword":"이공팔공"
}

그럼 이 두개의 키워드가 동일하게 하나의 명령어로 검색이 되는지 확인해보자.

GET synonyms_test/_search
{
  "query": {
    "match": {
      "keyword": "이공팔공"
    }
  }
}

2080과 이공팔공으로 검색한 결과

데이터베이스/Nosql

redis cluster로 구성하여 실행 시켜보기

redis를 사용하면서 cluste로 구성해봐야하는 일이 있었다.

그래서 찾아보던 중 redis문서에서 방법을 찾았다. https://redis.io/topics/cluster-tutorial

 

Redis cluster tutorial – Redis

*Redis cluster tutorial This document is a gentle introduction to Redis Cluster, that does not use complex to understand distributed systems concepts. It provides instructions about how to setup a cluster, test, and operate it, without going into the detai

redis.io

따라서 구성해보자.

 

redis 다운로드

https://redis.io/download

 

다운 받고 압축을 풀고 make, make install 명령어를 사용해서 빌드한다.

tar xvfz redis-5.0.4
cd redis-5.0.4
make
make install

 

redis 클러스터 생성

redis 클러스터 구성을 위해서는 다음과 같이 6개의 노드가 필요하다. 이유는 아래의 내용과 같다.

** ERROR: Invalid configuration for cluster creation.** Redis Cluster requires at least 3 master nodes.
** This is not possible with 2 nodes and 1 replicas per node.** At least 6 nodes are required.

 

그럼 각 노드 생성을 위해서 필요한 설정을 담을 cluster-test 폴더를 먼저 만들자.

그리고 6700 ~ 6705까지의 폴더를 만든다.

jeongcheol-ui-MacBookPro:redis-5.0.4 wedul$ mkdir cluster-test
jeongcheol-ui-MacBookPro:redis-5.0.4 wedul$ cd cluster-test
jeongcheol-ui-MacBookPro:cluster-test wedul$ mkdir $(seq 6700 6705)
jeongcheol-ui-MacBookPro:cluster-test wedul$ ls
6700	6701	6702	6703	6704	6705

그리고 src 폴더에 make를 통해 생성된 redis-server 파일을 모든 폴더에 넣어주고 다음 설정이 들어간 redis.conf 파일까지 같이 넣어준다.

port 6700
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

그럼 모든 서버를 실행시켜보자.

./redis-server redis.conf &

이제 6개의 인스턴스가 실행중인것을 확인 할 수 있다. 그럼 이 인스턴스를 특별한 설정을 통해 cluster를 구성해야한다.

cluster설정은 redis 3, 4에서는 redis-trib.rb를 사용했지만 5부터는 redis-cli에 다 포함되어 있다.

그럼 아래 명령어를 사용해서 cluster를 구성해보자.

redis-cli --cluster create 127.0.0.1:6700 127.0.0.1:6701 127.0.0.1:6702 127.0.0.1:6703 127.0.0.1:6704 127.0.0.1:6705 --cluster-replicas 1

여기서 사용된 cluster-replicas는 각 인스턴스의 replica 노드를 하나씩 구성하겠다는 뜻으로 마스터노드 3개 slave노드 3개가 만들어진다.

그러면 아래 보는것과 같이 서버가 3대 3대로 마스터와 슬레이브가 구성이되고 yes를 누르면 그에 맞게 클러스터가 구성된다.

 

그럼 이렇게 구성된 클러스터를 사용해서 redis에 접속해보자.

cluster모드에 redis 접속을 위해서는 -c 옵션을 달아서 실행시킨다.

 

이렇게 레디스의 클러스터를 구성해봤다.

이를 사용해서 이제 업무에 적용해보자.

데이터베이스/Elasticsearch

elasticsearch 7.0 docker 설치 후 변경사항 확인

엘라스틱서치 7.0이 출시했다.

엘라스틱서치 7.0에는 kibana UI변경과 multi mapping type 제거 등의 이슈가 있다.

우선 달라진점을 확인하기 위해 docker에 설치해보자.

설치

elasticsearch

docker run --name elastic7.0 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.0.0

 

kibana

docker run -d --rm --link elastic7.0:elastic-url -e "ELASTICSEARCH_HOSTS=http://elastic-url:9200" -p 5601:5601 --name kibana7.0 docker.elastic.co/kibana/kibana:7.0.0

설치가 끝나고 프로세스를 확인해보면 elastic과 kibana가 올라가 있는 것을 확인할 수있다.

 

kibana UI 확인

키바나에 접속해 보니 엄청 깨끗하다. 몬가 되게 플랫해진 요새 디자인을 하고 있다. 5부터 6까지 변할때도 몬가 키바나가 멋있어졌다고 느꼈는데 이번에 7버전은 더 멋진 것 같다.

그리고 더 대단한 건 요새 대세인 다크모드가 지원된다.

다크모드는 setting > kibana > advanced settings > dark mode 위치에 가면 다음과 같은 설정 하는 부분이 있다.

설정 후 새로고침을 하면 적용되는데 화면이 멋있다.

 

그리고 멀티 맵핑 타입이 제거되고 등등 다른 변경사항이 있는데 아래 링크를 확인하면 된다.

근데 릴리즈하면서 마지막 글에 보면 기존에 elastic을 6버전 이상 사용하고 있으면 굳이 업데이트 할 필요는 없다고 한다 ㅋㅋ

 

변경사항

https://www.elastic.co/blog/elastic-stack-7-0-0-released

데이터베이스/Nosql

[번역] Redis partitioning

파티셔닝 공부를 위해 아래 페이지의 내용을 번역하며 정리해봤다.

https://redis.io/topics/partitioning


Redis Partitioning: 여러 레디스 인스턴스로 데이터 분배하기


파티셔닝은 데이터를 여러 레디스 인스턴스로 분할하여 모든 인스턴스가 자기가 소유한 키의 집합들만 소유하도록 하는 프로세스이다. 먼저 파티셔닝 개념에 대해 설명하고 레디스 파티셔닝에 대한 대안을 소개한다.

파티셔닝이 효율적인 이유

레디스에서 파티셔닝을 하기는 다음 두개의 이점이 있다.
1. 하나의 컴퓨터로 메모리의 양이 제한되는 경우에 파티셔닝을 사용하여 더 큰 데이터베이스와 메모리를 가질 수 있다.
2. 여러 개의 코어와 여러 대의 컴퓨터에 연산 능력을 확장하고 네트워크 대역폭을 여러 대의 컴퓨터와 네트워크 어댑터로 확장할 수 있다.

기본 파티셔닝 방법 (range partitioning)

파티셔닝에는 여러 기준이 있다. Redis 인스턴스 R0, R1, R2, R3 그리고 많은 사용자를 대표하는 키인 user:1, user:2와 같은 존재한다고 가정해보자. 이때 해당 키들을 어느 인스턴스에 어떻게 넣어야 하는지에 대한 여러 방법을 가지고 있다. 다른말로 말하면 주어진 키들을 주어진 인스턴스에 어떻게 매핑 할것인지에 대한 여러 방법이 있다.

가장 간단한 방법으로 range partitoning이 있다. 이 방법은 특정 범위에 있는 데이터는 특정 인스턴스에 매핑시켜서 데이터를 분배한다. 예를 들면 1 ~ 10000 까지의 데이터는 R0, 10001 ~ 20000 까지는 R1 식으로 저장 할 수 있다. 이 방식은 어떤 범위에 키를 어느 인스턴스로 매핑할지에 대한 정리가 되어있는 테이블이 필요하다.

이 테이블은 관리가 필요하고 모든 번위에대한 정리가 되어있어야 한다. 그래서 매우 불편하여 다른 파티셔닝 기법을 사용하여 이 번거로움을 대체한다.

해시 파티셔닝 Hash Partitioning

이 방식은 키와 함께 동작하고 object_name:<id>형식으로 키를 만들어서 사용하지 않아도 된다. 동작방식은 간단하다. 우선 키 이름을 crc32 해시 함수를 이용해서 숫자로 변경한다. 예를 들면 foobar라는 키는 93024922로 변경한다. 그리고 인스터스 개수 만큼 % 연산을 진행한다. 만약 인스턴스가 4개라면 93024922 % 4는 2이기 때문에 2번째 인스턴스에 들어간다.

다른 파티셔닝 종류

몇몇의 레디스 클라이언트와 프록시로 부터 hash function을 향상시켜서 만든 파티셔닝으로 consistent hashing라고 불린다.

Client side 파티셔닝
- 클라이언트에서 직접적으로 키를 가지고 읽고 기록할 노드를 선택한다. 많은 레디스 클라이언트는 이 파티셔닝을 구현한다.

Proxy assisted 파티셔닝
- 레디스 클라이언트가 바로 레디스 인스턴스에 요청을 보내지 않고 프록시에게 전송한다.
이 프록시는 적절하게 설정된 파티셔닝 스키마 대로 레디스 인스턴스에 저장하고 클라이언트에게 응답한다. 레디스와 Memcached에 대표적으로 Twemproxy가 존재한다.

Query 라우팅
- 임의의 인스턴스로 전달된 쿼리가 올바른 노드로 리다이렉션 되는 것을 말한다. redis cluster는 클라이언트에 도움을 받아서 하이브리드 형태의 쿼리 라우팅을 구현한다.

여러 파티셔닝이 있지만 기본 베이스는 기폰 파티셔닝과 해시 파티셔닝에서 구현된것이기 때문에 이 두가지가 기본이다.

Data store or Cache?

레디스에서 파티셔닝은 개념적으로 데이터 스토어와 캐시로 사용할 때 동일하지만 사실 데이터스토어로써 파티셔닝을 사용할 때는 약간의 제약이 존재한다. 레디스가 데이터 스토어로 사용될 때 키는 항상 같은 레디스 인스턴스에 있어야한다. 하지만 레디스가 캐시로 사용될 때 주어진 노드를 사용할 수 없을 때 다른 노드를 사용한다고 해서 큰문제가 되지 않는다. 이 경우에는 인스턴스 맵을 변경하여 수정할 수 있다. 위에서 제시되었던 파티셔닝에서 기존에 가야할 노드가 사용불가능할 경우 다른 노드로 저장될 수 있다. 비슷하게 만약 새로운 노드가 추가되면 새로운 키의 일부는 새로운 노드에 저장될 수 있다.

정리된 컨셉은 다음과 같다.
- 레디스를 캐시로 사용할 경우 scaling up and down이 자유롭다.
- 레디스를 데이터 ㅈ장소로 써 사용할 경우에는 고정된 키-인스턴스 맵이 존재해야하고 인스턴수의 개수는 그렇게 크지 않게 고정되어 있어야 한다. 그렇지 않으면 인스턴스가 추가되거나 제거 될 때 인스턴스간에 키를 리밸런싱 할 수 있는 시스템이 필요하다. 현재는 redis cluster만 이 기능을 제공한다.


PreSharding

위에 본거와 같이 레디스를 캐시로써 사용하지 않는이상 파티셔닝에 단점이 있느 것을 확인 할 수 있다.

하지만 데이터 스토어는 매일 많이 사용된다. 오늘 10개의 레디스 인스턴스 노드를 사용한다고 해도 다음날 50개가 필요할 수도 있다. 그렇기 때문에 고정된 인스턴스로 키-인스턴스 맵으로 관리하는 방식으로는 데이터 스토어로써 레디스를 사용하는데 어려움이 있다.

레디스가 필요 리소스가 적기 때문에 이 문제에 대한 간단한 접근방법은 애초에 많이 생성하는 것 입니다. 만약 하나의 서버로 서비스를 시작한다면 하나의 서버안에서 파티셔닝을 통해 여러 레디스를 구동할 수 있다. 그래서 처음부터 32개 또는 64개의 인스턴스를 만들어서 충분하게 사용자들이 사용할 수 있도록 설계할 수 있다. 이러한 방식으로 인스턴스를 크게 늘리고 만약 데이터 저장소가 더 필요하고 레디스 서버가 더 필요하다면 간단하게 인스턴스를 다른 서버로 이동 시킬 수 있따. 만약 부가적인 서버가 추가된다면 레디스 인스턴스 반을 추가된 서버로 이동 시킬 수 있다.
Redis 복제를 사용하면 사용자를위한 중단 시간이 거의 없거나 전혀 없을 때 이동을 수행 할 수 있다.


레디스 파티셔닝 사용

이론을 공부했다. 이제 어떻게 사용해야하는지 보자.

Redis Cluster
redis cluster는 자동으로 샤딩을 하고 높은 가용성을 가지는것을 선호한다. 2015년 4월 1일 부터 redis cluster를 사용할 수 있다. redis cluster는 query routing과 client side 파티셔닝을 섞어놓은 방식으로 진행된다.

Twemproxy
Twemproxy는 memcached ASCII와 redis 프로토콜을 위해서 트위터에서 개발된 프록시 이다. 싱글스레드이고 C로 개발되어 전적으로 빠르다. 여러 레디스 인스턴스에서 자동으로 샤딩이 되는 것을 지원하며 하나의 인스턴스가 사용이 불가능하면 다른 인스턴스로 전환되는 것을 지원한다.


주의사항
http://www.zdnet.co.kr/view/?no=20131119174125
여기에 보면 주의사항이 나오는데 핵심은 redis의 경우 싱글 스레드로 돌아가기 때문에 작업이 오래 발생되는 keys나 flushall은 사용하지 말아라. 1만건 이하에 데이터를 조작하는 경우에는 사용해도 되는데 그 이상 사용하는 경우에는 주의하라는 뜻.

데이터베이스/Elasticsearch

docker logstash 설치 및 log 파일 elasticsearch에 기록

ELK에서 logstash를 제외하고는 모두 경험해봤다.

이제 logstash를 사용해서 log파일을 elasticsearch에 기록해보자.


설치

elasticseach도 kibana도 pc에 직접 설치하고 싶지 않아서 docker에 설치해서 사용했다. logstash도 docker에 설치해서 사용해보자.


물론 logstash를 사용하기전에 elasticseach와 kibana가 설치되어 있어야한다. 설치법은 저번 게시물에 올려놨다.


logstash를 이름을 지정해서 background에서 동작하도록 실행시킨다.

1
docker run --name logstash -d docker.elastic.co/logstash/logstash:6.4.0
cs


설정파일

logstash를 설치하면 내부에 다음과 같은 설정파일이 존재한다.

 이름

 설명

logstash.yml 

 logstash 구성 플래그가 들어있다. 이곳에 설정하면 command에 직접 설정할 필요가 없다. 그래도 command명령이 logstash.yml 파일의 우선순위보다 높다.

 pipelines.yml

 single logstash 인스턴스에서 파이프라인을 실행시키기 위한 설정내용을 담고 있다. input, filter, output등을 설정한다,

 jvm.options

 jvm 설정을 포함하고 있어서 힙사이즈 조절이 가능하다.

 log4j2.properties

log4j 설정을 할 수있다. 


설치가 완료된 후 logstash를 기존에 설치된 elasticsearch에 연동해서 상태를 보려고 할때 오류가 발생한다. config/logstash.yml에서 호스트 네임을 설정해주면 정상적으로 연결이 되고 monitoring까지 할 수 있다.



파이프라인

logstash에서 파이프라인은 input, output, filter가 존재한다. input과 output은 데이터 입출력을 위해 필수값이고 filter는 정재하기 위한 설정으로 선택값이다.

파이프라인 설정은 /pipieline 내부에 conf파일을 생성하여 설정할 수있다.


로그기록

그럼 설치된 logstash에서 특정 로그파일을 읽어서 elasticsearch에 기록해보자. pipeline.yml 파일을 수정해서 다음과 같이 기록한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
input {
  file {
    path => "/wedul.log"
    start_position => "beginning"
    sincedb_path => "/dev/null"
  }
}
 
output {
  elasticsearch {
    hosts => "http://we.local:9200"
    index=>"wedulpos"
  }
}
cs


위 내용은 파일을 읽고 elasticsearch wedulpos인덱스에 저장하라는 내용이다. start_position이 beginning이면 처음부터 읽으라는 것이고 sincedb는 내부적으로 어디까지 읽었는지 확인하기위해 저장하는 db이다. 현재 테스트할때 sincedb 설정이 제대로 되지 않아 No sincedb_path set, generating one based on the "path" setting 오류가 발생하여 우선적으로 /dev/null로 진행했다.

설정이 끝나고 logstash를 실행시키면 다음과 같이 저장되는걸 알 수있다.


모니터링에서도 해당 로그 기록 상황을 볼 수있다.


이 밖에도 input, output을 jdbc, cloudwatch등으로 설정해서 진행할수도 있다.




푸터바

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

  • Today : 13
  • Yesterday : 460
  • Total : 82,704