[Home-K8S] #22 FluxCD 계층과 분리 / 다중 클러스터 리소스 공유와 설정 분리
FluxCD - yaml 앞서 fluxcd 를 이용해서 helm chart 를 구성했습니다. 그 외에 일반적인 yaml
C와 비교하면 Python은 매우 느립니다.
아주 희귀하게 C보다 빠르게 할 수 있다고 하긴 하는데, 잘 모르겠습니다.

시계열 데이터를 처리할 때 대부분 numpy의 벡터화 연산을 사용하여 진행합니다.
벡터화 연산은 아주 큰 데이터도 견딜만한 시간을 사용하여 for문에 비해서 아주 효율적인 연산을 제공합니다.
하지만 가끔 어쩔 수 없이 for문을 사용해야 하는 경우가 있습니다. (아니면 제 머리가 좀 부족해서 벡터화를 못하는 걸 수도 있지만...)
그렇게 벡터화를 쓰다가 for문을 한번 쓰면 속도가 매우 차이가 납니다. 그 때, python에서 c를 사용하면 빠르게 진행할 수 있습니다.
그러면 원하는 연산을 가진 C 파일을 만들어 줍니다.
x의 현재 값에서 특정 %만큼 오르고 내릴 때의 걸리는 기간을 y에 넣습니다.
(현재부터 5개 뒤에 현재가의 ±per%만큼 변동이 있다 -> 5 O(n²))
c는 배열의 길이를 저장해놓지 않기에 따로 길이도 변환해서 넘겨줘야 합니다.
#include <stdio.h>
void pred_period(const int len, int*x, int*y, const float per)
{
unsigned long upper,lower;
printf("len: %d\n",len);
printf("x first/last: %d / %d\n",x[0],x[len-1]);
printf("y first/last: %d / %d\n",y[0],y[len-1]);
printf("per: %f\n",per);
for (int i=0;i<len;i++){
upper = (unsigned long)(x[i] * (1+per));
lower = (unsigned long)(x[i] * (1-per));
for (int j=i+1;j<len;j++){
if (upper < x[j]){
y[i] = j-i;
break;
}
else if (lower > x[j]){
y[i] = i-j;
break;
}
}
}
}app.c
이 c 파일을 compile해야 python에서 사용할 수 있습니다만, Dockerfile로 컴파일을 진행하겠습니다.
python과 c의 데이터가 다르기 때문에, ctypes의 c 변수로 변환해줘야 합니다.
import ctypes
import pandas as pd
import numpy as np
_dll = ctypes.cdll.LoadLibrary('app.so')
func = getattr(_dll,'pred_period') # c 함수
x = pd.read_csv(file).to_numpy(dtype=np.int32,copy=True).flatten()
x_len = len(x)
per = ctypes.c_float(0.0025) # per
c_len = ctypes.c_int(x_len) # 배열 길이
c_x = x.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)) # x array
y = np.zeros(x_len,dtype=np.float32)
c_y = y.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)) # y array
func(c_len,c_x,c_y,per) # c함수 실행
y_np = np.ctypeslib.as_array(c_y,shape=(x_len,)) # numpy 변환
y_df = pd.DataFrame({'period':y_np}) # pandas 변환
y_df.index = df.indexso는 gcc로 로컬에서 변환 후에 넣어줘도 되지만, docker를 사용하면 docker에서 같이 해줘야죠.
gcc 이미지를 사용해서 so 파일을 생성하고, so 파일만 이미지로 복사합니다.
그 후 python으로 생성합니다.
FROM gcc:latest
WORKDIR /app
COPY target.c .
RUN gcc -shared -o libtarget.so -fPIC target.c
FROM python:3.9-slim
ENV PYTHONUNBUFFERED=1
WORKDIR /source
COPY --from=0 /app/libtarget.so .
COPY requirements.txt .
RUN pip --no-cache-dir install -r ./requirements.txt
COPY app.py .
CMD ["python","app.py"]내용은 간단하고 cpython에 args를 동적으로 생성해서 넘겨줄 수도 있어서 생각보다 편하지만, 최대한 python에서 하려고 하는 게 맞다고 생각합니다. c 로 변수를 변환하면서 생기는 문제도 많고, 원인 찾기도 힘들어요.
Comments