주요글: 도커 시작하기
반응형


Esper는 이벤트 시점을 기준으로 출력 결과를 발생시킨다. 이벤트가 들어오거나 타임 윈도우에서 이벤트가 벗어나거나 할 때 관련된 이벤트 처리 결과를 리스너에 전달한다. 예를 들어, 아래 EPL을 생각해보자.


select avg(cost) from StockEvent


위 EPL을 실행하면 StockEvent가 발생할 때 마다 cost의 평균값을 리스너를 통해 받게 된다. 그런데, 단순히 평균의 추이를 알고 싶은 거라면 모든 이벤트마다 평균값을 받는 것 보다 10초, 1분과 같이 주기적으로 그 시점의 평균값을 확인해도 문제가 없을 것이다. 이렇게 출력 자체를 제어하고 싶을 때 output 절을 사용할 수 있다.


관련 시리즈:


output 을 이용한 출력 시점 제어


output은 출력 시점을 제어하기 위해 사용된다. 예를 들어, 10초 마다 출력을 받고 싶다거나, 이벤트 5개 당 첫 번째에 대해 결과를 받고 싶다거나 할 때 output을 사용한다.


output의 기본 사용 방법은 다음과 같다.


select ... from ...

output [all | first | last | snapshot ] every N [seconds | events]


every N에서 N은 숫자이며, seconds는 초를 events는 이벤트 개수를 뜻한다. 즉, "every 10 seconds"는 매 10초마 결과를 리스너에 전달하게 된다.


output 뒤에 all, first, last, snapshot는 다음의 의미를 갖는다.

  • all: 출력 주기에 발생한 모든 이벤트 출력
  • first: 출력 주기에 발생한 첫 번째 이벤트 기준 출력
  • last: 출력 주기에 발생한 마지막 이벤트 기준 출력
  • snapshot: 현재 시점의 출력 결과. 윈도우와 함께 사용되지 않을 경우 last와 같은 결과 출력.

예를 들어, 아래 목록에 첫 번째 EPL은 매 2초 간격으로 출력을 발생시키는데, 출력 주기(2초) 범위에 발생한 모든 이벤트에 대한 출력을 발생시킨다.

  • select avg(cost) as avg from StockTick output all every 2 seconds
  • select avg(cost) as avg from StockTick output first every 2 seconds
  • select avg(cost) as avg from StockTick output last every 2 seconds
  • select avg(cost) as avg from StockTick output snapshot every 2 seconds

위 EPL에 대해 실제 리스너에 전달된 출력 결과를 시간대 별로 출력해보면 아래 그림과 같다.



위 그림에서 상위 두 개는 code1 및 code2 이벤트의 발생 시점이다. 그리고, 회색 화살표는 2초 간격을 표시한 것이다. 녹색 삼각형으로 표시된 output all의 경우, 매 2초 간격마다 발생한 모든 이벤트 처리 결과가 리스너에 전달되는 것을 알 수 있다.


위 그림에서 회색 X 표시가 output first에 의해 발생한 이벤트 발생 시점을 표시한 부분이다. output first의 경우는 약간 특이하게 동작한다. output first의 경우 현재 주기에서 발생한 이벤트가 없으면, 다음 주기가 시작할 때 현재 시점 기준으로 마지막 결과를 리스너에 전달하고, 그 다음 주기에서 새로운 이벤트가 발생하면 그 시점의 결과를 리스너에 다시 전달한다.


group by와 output


group by와 output이 만나면 약간 다른 방식으로 동작한다. group by와 output이 만나면 다음과 같은 방식으로 동작한다.

  • first: 그룹 별 출력 주기에 발생한 첫 번째 이벤트를 기준으로 출력 결과 생성. 그룹 별 첫 번째 이벤트 발생 시점에 출력 생성. 출력 주기에 이벤트가 없으면 출력 결과를 생성하지 않음.
  • last: 그룹 별 출력 주기에 발생한 마지막 이벤트를 기준으로 출력 결과 생성. 출력 주기 종료 시점에 마지막 출력 결과 생성. 출력 주기에 이벤트가 없으면 출력 결과를 생성하지 않음.
  • all: 출력 주기 종료 시점에 마지막 출력 결과 생성. 출력 주기에 이벤트가 없어도 출력 결과 생성.
  • 키워드 없음: 출력 주기에 발생한 모든 출력 결과 생성. 출력 주기 종료 시점에 출력 결과 생성. 출력 주기에 이벤트가 없으면 출력 결과를 생성하지 않음.

아래 쿼리는 작성 예이다.

  • select code, avg(cost) as avg from StockTick group by code output first every 2 sec
  • select code, avg(cost) as avg from StockTick group by code output last every 2 sec
  • select code, avg(cost) as avg from StockTick group by code output all every 2 sec
  • select code, avg(cost) as avg from StockTick group by code output every 2 sec

위 쿼리를 실행해 보면 이벤트 발생 시점에 따라 아래와 같이 출력 결과가 발생한다.




윈도우와 snapshot의 동작 방식


윈도우와 output snapshot을 함께 사용하면 윈도우를 기준으로 마지막 값이 출력된다. 아래 그림은 다음의 세 쿼리를 실행한 결과를 정리한 것이다.

  • select avg(cost) as avg from StockTick.win:time_batch(3 sec) output snapshot every 1.5 sec
  • select avg(cost) as avg from StockTick.win:time_batch(3 sec)
  • select avg(cost) as avg from StockTick.win:time(3 sec) output snapshot every 1.5 sec



출력 주기를 1.5초로 지정했는데, 그 출력 결과를 보면 시간 배치 윈도우와 시간 윈도우에서 output snapshot이 다르게 동작하는 것을 확인할 수 있다. 시간 배치 윈도우와 output snapshot을 함께 사용한 결과를 보면 세 번째 출력 결과가 5000인데, 그 이유는 다음과 같다.

  • 시간 배치 윈도우에 적용된 output snapshot의 세 번째 출력 결과 시점은 약 8.5초
  • 시간 배치 윈도우의 처리 구간은 7초~9초
  • 따라서, 아직 현재 시간 배치 윈도우의 결과가 없으므로, 이전 배치의 결과인 5000을 값으로 출력
시간 윈도우의 경우는 항상 결과가 있기 때문에 현재 출력 시점을 기준으로 시간 윈도우 크기 범위의 결과를 출력한다.


추가 내용


출력 주기를 크론탭을 이용해서 표현 가능하다. 다음은 매 15분 주기로 결과를 출력하는 예이다.

  • select avg(cost) as avg from StockTick.win:time_batch(30 minutes) output snapshot at(*/15, *, *, *, *)

after를 사용해서 최초 일정 시간 동안 결과를 출력하지 않도록 지정할 수 있다.

  • select avg(cost) as avg from StockTick output after 4 sec last every 1.5 sec


+ Recent posts