시계열 데이터 베이스에 대해 아시나요?
저는 모릅니다.
시계열 DB는 요즘 점점 관심이 많아지는 DB중 하나인데요.
요즘 시간에 따른 데이터의 흐름을 보기 위해 생기는 서비스들이 많습니다.
대표적으로 그라파나
같은 서비스가 있는데, 이 그라파나에도 시계열 DB가 사용됩니다.
개중에 InfluxDB
라는 시계열 DB가 있습니다.
시계열 DB중에서는 가장 성능과 인기도가 높은 DB 엔진중 하나입니다.
그리고, 저희 프로젝트에서 실시간 통계
기능을 구현하기 위하여, InfluxDB를 사용하게 됐습니다.
influxdb에서 제공하는 자바 클라이언트 중 DSL로 된 방식이 제일 깔끔하고, 가독성 좋다고 판단하여, flux-dsl 이라는 오픈소스를 사용하기로 결정했습니다.
(또한 프로젝트에 QueryDSL도 사용하기에 러닝 커브가 적다는 장점도 있었습니다.)
flux라는 쿼리언어는 influxDB3버전 부터는 공식적으로 관리하지 않습니다.
flux-dsl도 커뮤니티에 공개되어 관리합니다.
그리고 조회코드를 작성했습니다.
public Page<Data> query(Request request, Pageable pageable) {
Flux flux = Flux.from(bucket)
.range(
request.start(), request.end()
)
.filter(
Restrictions.and(
nameLike(request.name())
)
)
.limit(pageable.getPageSize())
.withOffset((int)pageable.getOffset())
.pivot(new String[] {"_time"}, new String[] {"_field"}, "_value");
List<Data> datas =
queryApi.query(flux.toString(), Data.class);
}
private Restrictions nameLike(String name) {
return isBlank(name) ? Restrictions.or() :
Restrictions.tag("name").custom("/.*" + name + ".*/", "=~");
}
계속 다음오류가 발생했습니다.
com.influxdb.exceptions.InternalServerErrorException: HTTP status code: 500; Message: type error 3:88-3:109: string != regexp
시계열 DB
도, influxDB
도 flux-dsl
도 모르는 초짜여서 이거 뭐 어쩌라고.. 하고 검색해보니 똑같은 이슈가 있었습니다.
6개월 전 이슈 가 이미 등록돼있었지만, 따로 업데이트가 없었습니다.
flux 자체가 InfluxDB팀이 관리하지 않기 때문에 더 그런것 같았습니다.
근데 생각보다 원인은 너무나 간단했습니다.
BooleanExpression
같은 존재가 있는데, 이는 Restriction
입니다.Restriction
에 체이닝을 걸어 필터를 만들 수 있습니다.Restriction
이 toString
으로 변환될때, 다음과 같이 변환되어야 합니다.r["name"] =~ 정규표현식
r["name"] =~ "정규표현식"
ColumnRestriction
코드를 보니 다음과 같이 처리됩니다.@Override
public String toString() {
String value;
if (fieldValue instanceof String) {
value = "\"" + escapeDoubleQuotes((String) fieldValue) + "\"";
} else {
value = FunctionsParameters.serializeValue(fieldValue, false);
}
return "r[\"" + escapeDoubleQuotes(fieldName) + "\"] " + operator + " " + value;
}
이는 6개월 전 이슈에도 명시됐습니다.
답답하면 니들이 뛰던지에서 답답한 놈을 맡은 놈
업데이트가 있냐고 물었고, 없을 것 같아 코드를 직접 수정해서 PR을 올렸습니다.
만약 작업이 like(~)
검색 이라면, 간단하게 escapedDoubleQuotes를 붙이면 됐습니다.
또한 간단한 테스트도 작성했습니다.
@Test
void custom (){
Restrictions restrictions = Restrictions.value().custom("/.*target.*/", "=~");
Assertions.assertThat(restrictions.toString()).isEqualTo("r[\"_value\"] =~ /.*target.*/");
restrictions = Restrictions.value().custom("1", "==");
Assertions.assertThat(restrictions.toString()).isEqualTo("r[\"_value\"] == \"1\"");
}
MR을 받아주셨습니다.
와! 내가 오픈 소스 컨트리뷰터!
괜히 엄청 들떠서 동네방네 소문내고 다녔습니다.
인류에 공헌한 나는 엄청난 개발자고 그랬습니다.
생애 첫 오픈소스 머지된 PR에 한 3일은 들떠서 시간나면 닫힌 PR 창 다시보고 그랬습니다.
그러면서 한 두가지 느낀점이 있습니다.
나도 공헌할 수 있는 바가 있다.
물경력인 저는 항상 자존감이 낮은 상태로 "나는 그렇게 나쁜 개발자가 아니야" 라고 합리화하면서 실상은 열등감에 괴로워했습니다. 아직은 개발자로서 부족한 점이 많으니까요. 그래도 실제로 나도 어떤것에 대해 기여하고, 이게 받아들여졌다는 사실이 "그렇게 나쁜 개발자가 아니다" 라는 걸 증명해주는 것 같았습니다.
또한 다른 프로젝트에 기여하며, 나도 다른 사람들에게 기술적으로 도움이 될 수도 있다는 사실에 기뻤습니다.
개발할 때 한번 더 cmd+B
버튼을 누르자
사실 그냥 다른 자바 클라이언트 라이브러리 썼으면 됐습니다. 그 와중에 "아 외않돼 난 잘못한거 없는데ㅡㅡ" 하는 생각에 좀 더 파고들었습니다. 그러다보니 Restriction
을 만드는 구조나, DSL
이 어떻게 생성되는지 내부를 알게 되면서 조금이라도 더 자바에 대해 알 수 있었습니다.
자존감도 챙기고, 다른 사람도 도울 수 있었던 좋은 경험을 했습니다. 전보다는 오픈 소스에 관심을 갖고, 기여할 수 있는 방안을 모색하게 됐으면 좋겠습니다.