주요글: 도커 시작하기
반응형
앞서 시간 윈도우와 개수 윈도우에 대해 알아봤었는데, Esper는 이 외에도 다양한 종류의 뷰를 제공하고 있다. 이번 글에서는 몇 가지 뷰를 정리해보았다.

이전 글
Esper에서는 뷰는 이벤트를 유지하는 공간이다. EPL에서 사용중인 뷰에 담긴 이벤트 목록을 구하고 싶다면 다음의 코드를 사용하면 된다.

SafeIterator<EventBean> iter = eps.safeIterator(); // eps는 EPStatement
while (iter.hasNext()) {
    EventBean bean = iter.next();
    SomeEvent event = (SomeEvent)bean.getUnderlying());
}
iter.close();

1. 윈도우 뷰


앞서 EPL 기초 글에서 4개의(시간, 시간 배치, 길이, 길이 배치) 윈도우 뷰를 설명했었다. 여기선 몇 개의 윈도우 뷰를 추가로 설명하겠다.


외부 시간 윈도우(externally-timed window)


시간 윈도우가 이벤트의 발생 시점과 엔진 시간을 기준으로 윈도우에 포함될 이벤트를 결정한다면, 외부 시간 윈도우는 계산된 시간을 기준으로 윈도우에 포함될 이벤트를 결정한다. 다음은 설정 예이다.


select avg(responseTime) as avg from AccessLog.win:ext_timed(accessTime, 3 seconds)


win:ext_timed의 첫 번째 파라미터는 시간을 계산할 때 사용할 표현식으로 밀리초 단위의 값을 사용한다. 위 EPL에서는 AccessLog의 accessTime 값을 사용하였다. 위 EPL을 실행하면 win:ext_timed는 다음과 같은 방식으로 동작한다.

  • 새로운 AccessLog 이벤트 n이 들어오면, n.accessTime 값을 기준으로 이전 이벤트 x에 대해 x.accessTime 값이 3초 지난 x를 찾는다.
  • 윈도우에 x를 제거한다.

예를 들어, 신규 이벤트가 발생하는 순서에 따라서 윈도우에 보관되는 이벤트는 다음과 같이 달라진다.


신규 이벤트 

윈도우에서 제거되는 이벤트 

윈도우에 포함된 이벤트

N1 (accessTime=100)

-

N1 

N2 (accessTime=2500)

N1,N2 

N3 (accessTime=3400) 

N1 (3400 - 100 > 3000) 

N2,N3 

N4 (accessTime=3700)

-

N2,N3,N4  

N5 (accessTime=5300)

-

N2,N3,N4,N5

N6 (accessTime=5700) 

N2 (5700 - 2500 > 3000) 

N3,N4,N5 

* 새로운 이벤트가 들어와야 윈도우에서 제거되므로, 이 점에 유의해서 사용해야 한다.


외부 시간 배치 윈도우(externally-timed batch window)

외부 시간 배치 윈도우는 이벤트 발생 시점에 표현식을 기준으로 배치를 처리한다. 

select avg(responseTime) as avg from AccessLog.win:ext_timed_batch(accessTime, 2 seconds)


win:ext_timed_batch의 첫 번째 파라미터는 타임 배치를 처리할 기준 시간이다. 다음은 위 EPL을 실행할 때 이벤트 순서에 따라 배치 윈도우에 들어가는 이벤트와 결과 생성을 보여주고 있다.


신규 이벤트 

배치 윈도우

결과 생성

N1 (accessTime=100)

N1


N2 (accessTime=2500)

N2 

N1의 결과

N3 (accessTime=3400) 

N2,N3


N4 (accessTime=3700)

N2,N3,N4


N5 (accessTime=5300)

N5

N2,N3,N4의 결과

N6 (accessTime=5700) 

N5,N6


N7 (accessTime=7400)

N7 

N5,N6의 결과 

* 새로운 이벤트가 들어와야 윈도우에서 제거되므로, 이 점에 유의해서 사용해야 한다.


시간 누적 윈도우(time-accumulating window)


시간 누적 윈도우는 지정한 시간 안에 이벤트가 들어오지 않으면 윈도우에서 이벤트를 제거한다. 예를 들어, 아래 코드는 마지막 이벤트가 들어온지 2초 동안 이벤트가 들어오지 않으면 윈도우에서 이벤트를 제거한다.


select rstream * from AccessLog.win:time_accum(2 sec)


최초 길이/시간 윈도우(first length, first time)


최초 n개의 이벤트만 윈도우에 유지하거나 시작 이후 지정한 시간 동안의 이벤트만 윈도우에 유지하고 싶다면, 다음의 두 윈도우를 사용한다.


select * from AccessLog.win:firstlength(10)


select * from AccessLog.win:firsttime(2 sec)



2. 표준 뷰


Unique 뷰 / Firstunique 뷰

Unique 뷰는 지정한 식을 기준으로 단일 값을 보관한다. 예를 들어, 아래 코드를 보자.

select * from StockTick.std:unique(code)

위 EPL은 같은 code 값을 가지는 이벤트 중 가장 마지막 이벤트를 포함하는 뷰를 생성한다. 예를 들어, 이벤트의 code 값에 따라 뷰에 포함되는 이벤트는 다음과 같이 달라진다.

발생 이벤트 

뷰에 포함된 이벤트 

S1(code='1')

S1 

S2(code='1')

S2

S3(code='2')

S1,S3

S4(code='1')

S3,S4

S5(code='2')

S4,S5

S6(code='2')

S4,S6


Firstunique 뷰는 지정한 식을 기준으로 단일 값 중 최초 이벤트를 보관한다. (Unique 뷰는 단일 값 중 마지막 이벤트를 보관하는 것과 다르다.)


select * from StockTick.std:firstunique(code)



그룹 데이터 윈도우

그룹 데이터 윈도우는 지정한 표현식을 기준으로 그룹핑 된 데이터 윈도우를 생성한다. 앞서 살펴본 뷰와 차이점이 있다면 반드시 다른 뷰를 서브 뷰로 조합해서 사용해야 한다는 점이다. 예를 들어, 다음의 뷰를 보자.

select code, avg(cost) as avg from StockTick.std:groupwin(code).win:length(3)

위 EPL은 code 프로퍼티를 이용해서 이벤트를 그룹핑한다. 그리고, 각 그룹별로 길이가 3인 서브 뷰를 만든다. 즉, 각 code 별로 길이가 3인 뷰가 만들어지는 것이다. 그런데, 위 EPL에서 주의할 점은 뷰만 그룹으로 생성된다는 거지, avg 연산자 그룹별로 되는 것은 아니라는 점이다.

실제 그룹별로 값을 구하려면 다음과 같이 group by 를 함께 사용해줘야 한다. 

select code, avg(cost) as avg from StockTick.std:groupwin(code).win:length(3)
group by code


3. 통계 뷰

단변량(Univariate) 통계

단변량 통계 뷰는 숫자 프로퍼티에 대한 통계 데이터를 제공하는 뷰다. 다음은 사용 예이다.

select average from StockTick.stat:uni(cost)

stat:uni()는 숫자 식을 첫 번째 파라미터로 갖는다. 위 코드의 경우 cost 프로퍼티를 값으로 갖는다. 위 EPL에서 select 절에 있는 average는 stat:uni 뷰가 제공하는 프로퍼티로서, 평균 값을 제공하는데 사용된다. average 프로퍼티 외에 stat:uni 뷰가 제공하는 프로퍼티는 다음과 같다.

  • datapoints: 값의 개수
  • total: 값의 합
  • average: 값의 평균
  • variance: 분산
  • stddev: 샘플 표준편차
  • stddevpa: 표준편차

단변량 통계 뷰는 다른 뷰와 함께 사용될 수 있다. 예를 들어, 다음 코드는 code로 그룹핑 한 뷰의 서브 뷰로 stat:uni 뷰를 사용했는데, 이 경우 average는 code 그룹 별로 cost의 평균이 된다.


select average from StockTick.std:groupwin(code).stat:uni(cost)


stat:uni가 제공하는 프로퍼티 외에 다른 프로퍼티(예, 이벤트의 프로퍼티)를 사용하려면 다음과 같다. stat:uni 뷰에 파라미터를 추가로 지정해주면 된다.


select avergae, code from StockTick.std:groupwin(code).stat:uni(cost, code)

select * from StockTick.std:groupwin(code).stat:uni(cost, code, price)


select 절에서 '*'을 사용하면 stat:uni가 제공하는 프로퍼티 및 두 번째 이후에 지정한 파라미터를 선택한다.


회귀Regression 뷰


stat:linest 뷰를 이용하면 두 식의 선형회귀를 구할 수 있다. 다음 식은 price와 total의 회귀 연산을 해서 회귀선의 기울기를 구한다.


select slope from StockTick.win.time(30 min).std:linest(cost, total)


std:linest()는 slope를 포함해서 다음의 프로퍼티를 제공한다.

  • slope: 기울기
  • YIntercept: Y 절편
  • XSum, YSum, sumX, sumY: X, Y의 합
  • sumXY: X*Y의 합
  • sumXSq, sumYSq: X 제곱의 합, Y 제곱의 합
  • XAverage, YAverage: X, Y 평균
  • XVariance, YVariance: X, Y 분산
  • XStandardDeviationPop, YStandardDeviationPop: X, Y 표준 편차
  • XStandardDeviationSample, YStandardDeviationSample: X, Y 샘플 표준 편차

상관계수 뷰


stat:correl 뷰는 두 식 간의 상관계수를 구한다.


select correlation from StockTick.stat:correl(cost, total)


4.확장 뷰


정렬 윈도우 뷰


특정 식을 기준으로 정렬 기준으로 상위 n개의 이벤트만 유지하고 싶을 때 ext:sort 뷰를 사용한다. 다음은 ext:sort 뷰의 예이다.


select sum(total) from StockTick.ext:sort(10, total desc)

select sum(total) from StockTick.ext:sort(10, total desc, timestamp asc)


ext:sort() 첫 번째 파라미터로 정렬된 상태로 보관할 이벤트 개수를 지정하고, 두 번째 이후로는 정렬 기준으로 지정한다. 위 코드에서 첫 번째 EPL은 total 프로퍼티 값이 큰 상위 10개 StockTick 이벤트를 기준으로 sum(total)을 생성하게 된다. 정렬 기준으로 두 개 이상 지정하고 싶다면, 각 정렬 기준을 콤마로 구분해서 지정하면 된다.


랭킹 뷰


랭킹 뷰는 정렬 윈도우 뷰와 유사하다. 차이점이 있다면, 랭키 뷰는 유일식을 기준으로 한 개의 이벤트만 유지한다는 점이다. 예를 들어, 다음 EPL을 보자.


select sum(total) from StockTick.ext:rank(code, 10, price desc)


이 EPL은 price 기준으로 상위 10개의 StockTicke 이벤트를 뷰에 보관한다. 그런데, code 값이 같은 이벤트는 한 개만 보관한다. 예를 들어, 다음의 순서로 이벤트가 발생했다고 하면,

  • S1(code='C1', price=1000) -> S2(code='C2', price=800) -> S3(code='C1', price=1200)
뷰에 남는 이벤트는 S2와 S3가 된다. S1의 price 값이 S2보다 크지만, S3와 S1이 같은 code 값을 갖기 때문에 랭킹 뷰에는 S3만 남게 된다.


+ Recent posts