반응형

Elasticsearch Rest API 형태로 데이터를 조회하기 위해 쿼리를 던지는데, 기존 몽고 DB 필드가 모두 string 형태라 elasticsearch로 넘어오면서 text field로 인식되면서 range를 통해 조건 검색이 안되는 모습을 보였다.

 

해당 필드를 검색되도록 변경하기 위해 mapping 쿼리를 처리해보았는데, 아래처럼 에러가 발생했다.

>PUT http://118.37.186.231:9200/egoviot.usercollection

{
  "mappings": {
    "egoviot.usercollection": {
      "properties": {
        "accessDate": {
          "type":   "date",
          "format": "yyyy-MM-dd"
        }
      }
    }
  }
}

"type": "resource_already_exists_exception"

"reason": "index [egoviot.usercollection/J42yGfwSSOWqNj3bLk5W_g] already exists",

 

결론은 존재하는 index가 이미 존재해서 변경이 불가하다였다.

 

특정 필드 데이터값을 변경하고, 아래와 같이 reindex를 처리하였다.

>POST http://주소값/_reindex

{
	"source": {     
		"index": "egoviot.usercollection"
	},   
	"dest": {     
		"index": "egoviot.usercollection2"
	}
}

 

이후 변경된 인덱스를 통해 조회하면 정상적으로 조회되는 모습을 볼 수 있다.

>POST http://주소값/egoviot.usercollection2/_search

{
  "query": {
    "range": {
      "accessDate": {
        "gte": "2021-03-07",
        "lte": "2021-03-20"
      }
    }
  }
}

 조회가 된다!

반응형
반응형

팀원끼리 몇 일간에 삽질끝에 설정이 완료되어 내용을 공유해보고자 합니다.

다들 몽고만 써보고 도커나 엘라스틱서치는 써본적이 없었고 이번에 환경 구성을 위해 도커를 사용하면서 엘라스틱서치와 몽고DB 레플리카셋 설정을 시작해보았습니다.

 

 

엘라스틱서치와 몽고 DB 환경 구성하기

(OS는 CentOs에서 진행되었으며, 먼저 docker와 docker-compose가 설치되어 있어야 합니다.)

 

몽고 DB와 엘라스틱서치 환경 구성을 위해서는 몽고 DB를 레플리카셋으로 구성해야하는데, (안정성때문이라고 합니다.) 이를 위해 몽고DB간에 연결을 위한 이미지를 먼저 docker-compse를 통해 생성해야 합니다.

 

setup-rspl 이미지 생성하기

파일구성

 

docker-compose.yml

version: '4'
services:
  mongo1:
    image: "mongo"
    ports:
      - "27020:27017"
    volumes:
      - /home/psw/mongodb/mongo1:/home/psw/data
    networks:
      - mongo-networks
    command: mongod --replSet replication
  mongo2:
    image: "mongo"
    ports:
      - "27021:27017"
    volumes:
      - /home/psw/mongodb/mongo2:/home/psw/data
    networks:
      - mongo-networks
    command: mongod --replSet replication
    depends_on:
      - mongo1
  mongo3:
    image: "mongo"
    ports:
      - "27022:27017"
    volumes:
      - /home/psw/mongodb/mongo3:/home/psw/data
    networks:
      - mongo-networks
    command: mongod --replSet replication
    depends_on:
      - mongo2
  mongosetup:
    image: "setup-rspl"
    depends_on:
      - mongo1
    networks:
      - mongo-networks

networks:
  mongo-networks:
    driver: bridge

 

replicaSet.js

config = {
  _id: "replication",
  members: [
    { _id: 0, host: "mongo1:27017" },
    { _id: 1, host: "mongo2:27017" },
    { _id: 2, host: "mongo3:27017" }
  ],
}

rs.initiate(config)

rs.conf()

 

setup.sh

#!/bin/bash

sleep 10 | echo Sleeping

mongo mongodb://mongo1:27017 replicaSet.js

 

Dockerfile

FROM mongo

WORKDIR /usr/src
RUN mkdir configs
WORKDIR /usr/src/configs

COPY replicaSet.js .
COPY setup.sh .

RUN chmod +x ./setup.sh

CMD ["./setup.sh"]

여기까지 세팅이 되었다면 Dockerfile이 있는 위치에서 이미지를 생성한다.

> docker build -t setup-rspl .

 

위 명령어를 날리면 이미지가 생성됩니다.

docker build -t setup-rspl .

 

Elasticsearch + 몽고DB + Monstache 환경구성하기

먼저 만들고 있던 디렉토리 상위로 올라와서 docker-compose.yml과 config, elasticsearch 디렉토리를 구성합니다.

구성할 환경

 

config내부에는 monstache설정파일이 위치하며, elasticsearch디렉토리에는 data디렉토리가 존재하고 비워둡니다.(필요없어보이긴한다...)

아래처럼 다시 환경 구성을 시작합니다.

 

docker-compose.yml

version: "3"

services:
  elasticsearch:
    restart: always
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.14
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      - ES_JAVA_OPTS=-Xms2048m -Xmx2048m
      - discovery.type=single-node
    healthcheck:
      test: "wget -q -O - http://localhost:9200/_cat/health"
      interval: 1s
      timeout: 30s
      retries: 300
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./elasticsearch/data:/home/psw/elasticsearch/data
    networks:
      - monstache-network

  kibana:
    restart: always
    image: docker.elastic.co/kibana/kibana:6.8.14
    expose:
      - 5601
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch
    environment:
      - SERVER_PORT=5601
      - SERVER_NAME=kibana.example.org
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    networks:
      - monstache-network

  monstache:
    restart: always
    image: rwynn/monstache:rel5
    command: -f /home/monstache.config.toml &
    volumes:
      - /home/psw/config/monstache.config.toml:/home/monstache.config.toml
    depends_on:
      - elasticsearch
      - mongo1
      - mongo2
      - mongo3
    links:
      - elasticsearch
    ports:
      - "8080:8080"
    networks:
      - monstache-network

  mongo1:
    image: "mongo"
    ports:
      - "27020:27017"
    volumes:
      - /home/psw/mongodb/mongo1:/home/psw/data
    networks:
      - monstache-network
    command: mongod --replSet replication
  mongo2:
    image: "mongo"
    ports:
      - "27021:27017"
    volumes:
      - /home/psw/mongodb/mongo2:/home/psw/data
    networks:
      - monstache-network
    command: mongod --replSet replication
    depends_on:
      - mongo1
  mongo3:
    image: "mongo"
    ports:
      - "27022:27017"
    volumes:
      - /home/psw/mongodb/mongo3:/home/psw/data
    networks:
      - monstache-network
    command: mongod --replSet replication
    depends_on:
      - mongo2
  mongosetup:
    image: "setup-rspl"
    depends_on:
      - mongo1
    networks:
      - monstache-network

networks:
  monstache-network:
    driver: bridge

 

/config/monstache.config.toml

mongo-url = "mongodb://mongo1:27017,mongo2:27017,mongo3:27017/test?replicaSet=replication"
elasticsearch-urls = ["http://elasticsearch:9200"]
elasticsearch-max-conns = 4
elasticsearch-max-seconds = 5
elasticsearch-max-bytes = 8000000
dropped-collections = false
dropped-databases = false

namespace-regex = "^test"
direct-read-namespaces = ["book","log"]

환경 구성이 완료되면 docker-compose를 통해 서비스를 시작합니다.

> docker-compose up -d

 

-d는 백그라운드로 구동하겠다는 뜻입니다.

  • docker-compose 명령어 정리
docker-compse up 설정된 서비스 컨테이너를 생성 및 시작
docker-compose down 설정된 서비스 컨테이너 덩어리를 삭제(제거)
docker-compose start 설정된 서비스 컨테이너 구동
docker-compose stop 설정된 컨테이너 멈춤

서비스를 종료하고자 할때는 위에 명령어를 적어놨지만 stop으로 종료하고, 완전히 정보를 날리고자 할때는 down으로 컨테이너를 제거할 수 있다.(down은 데이터가 소멸된다. remove효과)

 

 

> docker ps

명령어를 통해 서비스들이 잘 올라왔는지 확인해봅니다.

docker를 설치하면서 시각화 서비스인 포트테이너가 있다면 웹에서 확인해도 좋다. 설정이 잘 못되어 정상적으로 올라오지 않은 경우 쉽게 로그 확인이 가능합니다.

▲ 포트테이너를 통해 확인한 서비스중인 컨테이너 리스트
▲ 동작중인 컨테이너의 로그를 확인 할 수 있다.

 

동작 확인하기

엘라스틱서치까지 healthy로 올라오면 postman이나 브라우저를 통해 9200으로 데이터를 확인해봅니다.

 

처음에는 DB에 데이터가 없을텐데 접속정보의 mongo1로 접속하여 데이터를 삽입해봅니다.

test 데이터베이스를 생성하고, book Collections에 간단하게 두 줄을 넣어봤습니다.

 

 

자 데이터를 넣었으니 조회가 되는지 확인해보겠습니다~

▲ GET > http://IP:PORT/_cat/indices?v

_cat/indices를 통해 엘라스틱서치에 등록된 index정보 리스트를 볼 수 있습니다.

test.book이 추가된 걸 볼 수 있네요.

 

 

특정 인덱스의 데이터 전체 검색

전체 검색을 해보겠습니다.

▲ GET > http://IP:PORT/test.book/_search  index/_search를 통해 검색

 

 

특정 인덱스의 특정 컬럼 조회

이번엔 특정 데이터를 받아보겠습니다.

▲ GET > http://IP:PORT/test.book/_search?q=name:"왜 나는 너를 사랑하는가"

 

 

like 검색해보기

이번에는 like문 검색방법입니다.

POST 방식으로 요청하고 body안에 raw형태로 아래의 형태로 전송을 해봅니다.

  • POST method
  • Headers : Content-Type : application/json
  • Body :
{
  "query" : {
      "bool": {
        "must": {
          "wildcard": {
            "name": "*나는*"
          }
        }
      }
  }
}

 

▲ POST > http://IP:PORT/test.book/_search

 

잘 검색된다!




  

반응형
반응형

데이터 제어하기

엘라스틱서치에 데이터를 넣고 조회해보기 전에 저장 구조를 먼저 파악해야합니다.

기존의 RDB와는 용어가 조금 다릅니다.

브라우저에서 http를 통해 확인한것 처럼 http프로토콜을 통해 데이터를 삽입하거나 조회, 수정, 삭제 CRUD 작업을 할 수 있습니다. 사이트중에 http통신을 지원하는 사이트를 통해 진행하거나 크롬 확장앱인 Postman등을 사용하시면 되겠습니다. (물론 자바나 언어로 짜셔도 됩니다!)

 

먼저 포맷은 요청하는 아래처럼 맞춰주셔야 합니다.

http:// IP : port / Index / Type / id값

ex) http://localhost:9200/test/dog/1

 

 

데이터 삽입하기(PUT)

 

제가 키우고 있는 강아지의 정보를 넣어봤습니다.

 

PUT으로 전송을 하면 아래와 같이 생성 및 여러가지 정보를 응답 받을 수 있습니다.

result에는 created라고 값이 들어간 것을 볼 수 있습니다.

인덱스값으로 test가 입력되었습니다.

타입값으로 dog가 입력되었습니다.

 

한번 더 전송해보겠습니다.

 

값 추가하기(PUT)

이번에는 result에 updated라고 나오는것을 볼 수 있습니다. 맨끝은 id값인데 최초에 create되면서 추가된 ggome데이터가 삭제되고 gamja 데이터로 수정되었기 때문입니다.

 

이런 현상을 방지하기 위해 dog위치에 _create를 넣어서 전송하게 되면 에러코드를 반환하여 수정되는 것을 방지 할 수 있습니다.

 

 

데이터 조회(GET)

GET을 통해 도큐먼트의 내용을 가져옵니다.

GET http://localhost:9200/test/dog/1

GET http://localhost:9200/test/dog/2

 

 

삭제하기(DELETE)

DELETE 메서드를 통해 요청하면 됩니다.

도큐먼트나 인덱스 단위로 삭제가 가능합니다.

 

도큐먼트 삭제하기

DELETE http://localhost:9200/test/dog/1

먼저 id값이1이던 gamja 데이터를 삭제했습니다. 결과로 deleted를 받았습니다.

 

데이터 조회시 found속성에 false가 나오면서 찾을 수 없다는 결과를 받았습니다.

 

인덱스 전체 삭제하기

DELETE http://localhost:9200/test

acknowledged속성이 true값으로 전달 받고 이후에 조회시에는  found속성의 false값이 아닌 index자체를 찾을 수 없다는 결과와 함께 404에러코드를 받습니다.

 

 

수정하기(POST)

post는 PUT메서드와 같이 삽입하는 기능처럼 유사하게 동작하지만 id값을 자동으로 생성시킵니다.

PUT처럼 result속성에 created로 받았지만 id가 랜덤으로 들어간 것을 볼 수 있습니다.

 

_update

수정하는 방법은 아래와 같습니다.

인덱스/_update/id

해당 명령 형태를 통해 업데이트가 가능합니다. 해당 방법을 통해 수정시 변경할 필드명의 속성 값만 넣어주면 들어간 속성만 변경이 되며 지정자로 "doc"이 꼭 있어야합니다.

 

변경된 name값을 확인 할 수 있습니다.

반응형
반응형

Elasticsearch?

검색엔진을 만들어야 할 상황을 대비하여 엘라스틱서치를 사용해보기로 했습니다.

엘라스틱서치는 일단 무료이며 모든 유형의 데이터를 분석 및 검색해주는 엔진으로 Apache Lucene을 기반으로 구축되었습니다.

빠른 속도를 통해 데이터를 수집, 분석, 시각화를 도와주는 도구입니다. 넷플리스, 마이크로소프트 등의 큰 기업들도 사용하고 있는것을 볼 수 있습니다.

 

다음으로 윈도우에 설치하고 간단하게 컨셉과 사용법을 알아보겠습니다.

 

설치하고 동작시키기

다운로드

먼저 설치를 위해 공식홈페이지로 이동합니다.

 

www.elastic.co/kr/downloads/elasticsearch

 

Free and Open Search: The Creators of Elasticsearch, ELK & Kibana | Elastic

Elasticsearch can also be installed from our package repositories using apt or yum, or installed on Windows using an MSI installer package. See Repositories in the Guide.

www.elastic.co

원하는 버전을 다운로드 받습니다. 

 

설치하기

다운로드 받으면 zip파일이 나오는데 압축을 해제하고 bin폴더의 elasticsearch.bat를 구동합니다.

정상적으로 구동되면 브라우저를 열고 localhost:9200으로 접속해봅니다.

 

이것으로 엘라스틱서치를 간단하게 설치하고 구동된 모습을 볼 수 있습니다.

반응형
반응형

기존 mysql 5.5.40에서 사용시엔 인코딩 관련 옵션만 적어서 연결을 했는데, 5.7로 올리자 연결은 되지만 한글과 같은 데이터만 전달하면 정상적으로 인식이 되지 않는 현상이 있었다.

 

 

5.7로 올라오고 SSL 옵션이 기본적으로 true로 변경되었고, 이부분을 false처리하지 않으면 정상동작하지 않으니 수정하도록 한다.

 

 useSSL=false 

jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&defaultFetchSize=1000&useSSL=false

 

반응형
반응형

insert 쿼리를 날리고 해당 쿼리의 Primary key값을 가져오고 싶은 경우가 있는데, 불필요하게 select를 날릴 필요없이 mybatis옵션을 통해 방금 insert한 값의 pk값을 가져올 수 있다.

 

useruseGeneratedKeys, keyProperty 속성을 추가하면 처리한 paramter값에 넣어주는 것을 볼 수 있다.

<insert id="inserTableData" parameterType="java.util.HashMap" useGeneratedKeys="true" keyProperty="id">
	INSERT INTO table(
      column1,
      ...
    ) VALUES (
      #{column1},
      ...
	)
	<selectKey keyProperty="lastPk" resultType="Integer" order="AFTER">
		SELECT LAST_INSERT_ID()
	</selectKey>
</insert>

hashmap parameter를 통해 insert를 처리하였고, insert dao가 끝난 후 hashmap데이터를 확인해보면 키값으로 지정한 <selectKey>를 통해 지정한 lastPk에 값이 들어간것을 볼 수 있었다.

 

 

반응형
반응형

Mysql 또는 Maria를 리눅스 서버에 설치하고 사용하다보면 테이블을 대소문자 구분하도록 설정이 되어 있는 경우가 있다.

 

해당 설정을 확인하는 방법은 아래 명령어를 통해 알 수 있다.

 

대소문자 구분상태 확인하기

show variables like 'lower_case_table_names';

Value값이 0이면 구분, 1이면 구분하지 않는 상태이다.

 

구분하지 않도록 설정하기 위해선 설정값을 변경하고 재기동이 필요하다.

 

설정 변경하기

vi, vim 등의 에디터를 통해 설정 파일을 먼저 열어준다.

vim /etc/my.cnf

 

설정 값 중에 [mysqld] 영역이 존재할텐데, 최하단에 아래의 설정값을 입력한다.

[mysqld]
lower_case_table_names=1

* [mysqld] 자체가 없다면 추가하고 입력하면 된다.

설정을 추가한다.

 

 

 

이후 서비스를 재기동하면 구분하지 않는 것을 볼 수 있다.

systemctl restart mariadb   #maria 재기동
service mysql restart       #mysql 재기동

1은 구분하지 않음

반응형
반응형

시작

systemctl start mariadb

 

종료

systemctl stop mariadb

 

재시작

systemctl restart mariadb

반응형