# monstache
###### tags: `tech sharing`
### monstache 를 사용한 이유
- 엘라스틱 서치와 몽고디비의 동기화를 위해 여러가지 툴이 존재하였다
1. mongo Connector : 업데이트가 된지 오래되었고 6버전 이상을 지원하지 않는다는 블로그를 보았다. nori분석기를 사용하기 위해서는 6.6 버전 이후부터 적용되는데 적용할 수 없다.
[mongo connector github](https://github.com/yougov/mongo-connector)
2. Transporter : 최신 ES버전을 지원하지 않는다는 글을 보고 사용하지 않았다.
3. Monstache : 엘라스틱 서치를 최신버전까지 지원하며, go언어로 작성되어 있지만 따로 go언어를 설치하지 않아도 사용할 수 있다고 해서 사용하기로 결정했다.
[monstache를 사용하기로 결정한 참고 자료1](https://medium.com/@eldishnawy/tutorial-sync-mongodb-with-elasticsearch-fb43e9bc13ce)
[monstache를 사용하기로 결정한 참고 자료2](https://lifeinno.tistory.com/16)
### Monstache란
Monstache는 MongoDB 컬렉션들을 Elasticsearch로 지속적으로 색인하는 Go언어로 개발된 sync 데몬이다
그리고 이 녀석은 루비나 파이썬, PHP와 같이 runtime에 의존하지 않고 단일 바이너리 파일이다.
### 사용법
1. monstache를 사용하기 위해서는 mongodb가 replicaset설정이 되어 있어야한다.
2. Mongodb URL과 elasticsearch URL을 설정하는 해 주었다
```
mongo-url = "mongodb://mongo1:27018,mongo2:27019,mongo3:27020/movie?replicaSet=rp0"
elasticsearch-urls = ["http://elasticsearch:9200"]
```
3. mongodb의 어떤 collection을 가저올 것인지에 대해 change-stream-namespaces에 입력하고, 이미 몽고디비에 있는 데이터를 가져오기 위해 direct-read-namespaces를 아래와 같이 설정하였다. ( 이때 DB명 까지 적어줘야한다.)
```
change-stream-namespaces = "^carrot.posts"
direct-read-namespaces = ["carrot.posts"]
```
4. 이대로 설정하면 인덱스가 carrot.posts로 되기 때문에 mapping를 해주었다 (carrot.posts를 post인덱스로 만들어준다는 뜻)
```
[[mapping]]
namespace = "carrot.posts"
index = "post"
```
5. 필요한 필드를 가져오기 위해 아래와같이 스크립트를 작성해 주었다
```
[[script]]
namespace = "carrot.posts"
script = """
module.exports = function(doc) {
var newdoc = {
title : doc.title,
images : doc.images,
category : doc.category,
price : doc.price,
buyerId : doc.buyerId,
uploadTime: doc.uploadTime,
location: { lat: doc.location.lat, lon: doc.location.lon}
}
return newdoc;
}
"""
```
아래의 공식 문서를 보면 다양한 옵션을 설정할 수 있다.
[공식문서](https://rwynn.github.io/monstache-site/start/#usage)
연동하기 위해 참고한 문서이다
[참고 문서](https://sudarlife.tistory.com/entry/MongoDB-ElasticSearch-Monstache-%EB%8F%84%EC%BB%A4-%EA%B8%B0%EB%B3%B8-%EC%85%8B%ED%8C%85%EC%9D%84-%ED%95%B4%EB%B3%B4%EC%9E%90)
### Monstach가 몽고DB의 변화를 감지하는 방법
- 6버전 이후부터 change stream을 사용하여 실시간 데이터 변경 사항에 대해 access 할 수 있다.
### change stream
- Change Stream은 MongoDB의 변경을 애플리케이션에 실시간으로 전달해주는 기능으로, MongoDB v3.6 에 추가되었다. MongoDB가 Publisher, 애플리케이션이 Subscriber가 되는 형태이다.
### 레플리카셋이 필요한 이유
- 아래와 같이 설정을 하면 몽고디비 단일모드로 진행할 수 있다.
```
disable-change-events = true
direct-read-namespaces = ["db1.col1", "db1.col2", "db2.col1"]
exit-after-direct-reads = true
```
- 명명된 collection의 전체 동기화만 수행할 수 있다. ( 이전 시점에서 시작할 수 없기 때문 )