Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

지속적인 예측 정확성 보장:Redis를 사용한 도커화된 시계열 모델의 상태 유지

지속적인 예측 정확성 보장:Redis를 사용한 도커화된 시계열 모델의 상태 유지

매출이나 주가를 예측할 수 있는 훌륭한 시계열 모델을 구축했지만 현실 세계에서는 실패하는 것을 지켜본 적이 있습니까? 음, 이것은 일반적인 좌절입니다. 귀하의 모델은 컴퓨터에서 완벽하게 작동하지만 Docker 컨테이너에 배포하는 순간 기억 상실증이 발생하는 것 같습니다. 어제 알고 있던 모든 것을 잊어버리고 내일에 대한 예측을 쓸모없게 만듭니다.

걱정하지 마세요. 이는 모델의 결함이 아닐 가능성이 높습니다. 이는 시계열 모델과 Docker 컨테이너의 작동 방식이 충돌하는 것입니다.

시계열 모델은 모두 메모리에 관한 것입니다. 미래를 예측하려면 과거를 기억해야 합니다. 그러나 Docker 컨테이너는 상태 비저장 및 망각성을 갖도록 구축되어 다시 시작할 때마다 메모리를 깨끗하게 지웁니다. 이러한 근본적인 갈등은 강력한 모델을 생산 과정에서 무가치한 모델로 만들 수 있습니다.

이 글에서는 그 문제를 해결해보겠습니다. 우리는 시계열 모델에 영구 메모리를 제공할 것입니다. Redis를 외부 브레인으로 사용하고 Docker 볼륨을 사용하여 다시 시작해도 메모리가 유지되도록 보장하는 프로덕션용 예측 서비스를 구축하는 방법을 알아봅니다. 실제 사례를 단계별로 살펴보며 지능적이고 믿을 수 없을 만큼 안정적인 시스템을 구축하는 방법을 배울 수 있습니다.

우리가 다룰 내용:

  • 이 가이드는 누구를 위한 것인가요?

  • 문제 이해

    • 그렇다면 시계열 모델이란 무엇인가요?

    • 1. 컨테이너는 일시적으로 설계되었습니다

    • 2. 예측 간의 맥락 상실

    • 3. 재시작 시 기억상실 모델

  • 해결책:외부 상태 저장소

  • 실제 구현

    • 잘못된 접근 방식부터 시작하세요

    • 볼륨 문제를 해결하는 방법

    • 코드가 상태를 처리하는 방법

    • 상태 엔드포인트 테스트

  • 스케일링은 어떻습니까?

    • Redis 클러스터를 사용한 수평 확장

    • Redis Sentinel을 통한 고가용성

    • 관리형 Redis 서비스 사용

  • 피해야 할 일반적인 함정

    • 볼륨이 작동한다고 가정하지 마세요

    • Redis 메모리 제한을 무시하지 마세요

    • 모니터링을 건너뛰지 마세요

  • 결론

이 가이드는 누구를 위한 것인가요?

이 튜토리얼을 최대한 활용하려면 몇 가지 사항을 숙지해 두는 것이 도움이 될 것입니다. 몇 가지 코드와 명령줄 작업을 자세히 살펴보게 되므로 조금만 준비하면 큰 도움이 될 것입니다.

  • 이 프로젝트의 주요 도구는 Docker와 Docker Compose입니다. 컴퓨터에 해당 프로그램이 설치되어 실행되고 있는지 확인하세요.

  • 또한 Docker, Python 및 Flask 웹 프레임워크의 기본 사항에 익숙하다면 따라하기가 더 쉬울 것입니다. 약간의 명령줄 경험도 튜토리얼의 명령을 실행하는 데 유용할 것입니다.

  • 하지만 이전에 Redis를 사용해 본 적이 없더라도 걱정하지 마세요. 당신이 알아야 할 것은 그것이 빠른 메모리 내 데이터베이스라는 것입니다. 나머지는 그 과정에서 처리하겠습니다.

이것을 가이드 투어라고 생각하세요. 호기심이 많고 기본 도구만 준비되어 있다면 좋은 결과를 얻을 수 있을 것입니다.

문제 이해

솔루션을 시작하기 전에 먼저 시계열 모델이 무엇인지 명확히 한 다음 이를 컨테이너화하는 것이 왜 그렇게 까다로운지 살펴보겠습니다.

그럼 시계열 모델이란 무엇인가요?

간단히 말하면, 시계열 모델은 시간에 따라 수집된 데이터 포인트를 분석하여 미래 가치를 예측하는 모델 유형입니다. 날씨를 예측하는 것과 같다고 생각하세요. 기상학자는 지금 하늘만 보는 것이 아니다. 그들은 지난 몇 시간과 며칠 동안의 온도, 기압, 바람 패턴을 살펴보고 내일 무슨 일이 일어날지 예측합니다.

시계열 모델은 웹사이트 트래픽, 주가, 에너지 소비 등 데이터에 대해 동일한 작업을 수행합니다. 중요한 점은 역사가 중요하다는 것입니다. 일련의 과거 사건은 미래에 대한 지능적인 예측을 내리는 데 필요한 맥락을 제공합니다.

이제 이러한 모델을 Docker에 넣으면 문제가 발생합니다.

1. 컨테이너는 일시적으로 설계되었습니다.

Docker 컨테이너는 상태 비저장을 의미합니다. 이는 대부분의 API에 적합합니다. 사용자 프로필 엔드포인트? 무국적. 감정 분석 모델? 무국적. 그들은 입력을 받고 출력을 반환하고 그 사이의 모든 것을 잊어버립니다.

시계열 모델은 이런 방식으로 작동하지 않습니다. 이전 예측의 맥락이 필요합니다. 그것이 없으면 모델은 본질적으로 시각 장애인입니다.

2. 예측 간의 맥락 상실

각 예측은 개별적으로 발생합니다. 모델은 단일 데이터 포인트를 수신하고 이전에 어떤 일이 일어났는지 알지 못한 채 추측합니다. 이는 시계열 모델링의 전체 목적을 무효화합니다.

"요청할 때마다 모든 기록 데이터를 로드하겠습니다."라고 생각할 수도 있습니다. 그러나 이러한 접근 방식은 두 가지 이유로 실패합니다:

  • 느리다. 수천 개의 데이터 포인트가 있으면 정말 느립니다

  • 확장되지 않습니다. 여러 시리즈가 있거나 요청량이 많은 경우 성능의 벽에 빠르게 도달하게 됩니다.

3. 재시작 시 모델 기억상실

새 버전을 배포하거나 컨테이너가 충돌할 때마다 누적된 상태가 모두 사라집니다. 모델이 처음부터 시작됩니다. 프로덕션 환경에서는 이는 용납될 수 없는 일입니다.

해결책:외부 상태 저장소

컨테이너 내부에 상태를 유지하는 대신 컨테이너 외부로 이동하겠습니다. Redis는 모델의 메모리가 됩니다.

패턴은 다음과 같습니다:

Client Request → Flask API → Redis → Prediction with Context

컨테이너는 상태 비저장 및 교체 가능 상태로 유지됩니다. 하지만 시스템 전체는 Redis를 통해 상태를 유지합니다.

직접 구현

이것을 만들어 봅시다. 데모 저장소를 복제하세요:

git clone https://github.com/ag-chirag/docker-redis-time-series
cd docker-redis-time-series

깨진 접근 방식으로 시작

docker-compose.initial.yml 파일에는 하지 말아야 할 일이 표시됩니다:

services:
 api:
 build: ./flask-api
 ports:
 - "5000:5000"
 redis:
 image: redis:alpine

무엇이 빠졌는지 알아차리셨나요? 볼륨이 없습니다. Redis는 컨테이너의 파일 시스템에 데이터를 저장합니다. 즉, 데이터는 일시적입니다.

실행하세요:

docker compose -f docker-compose.initial.yml up

몇 가지 예측을 해보세요:

curl -X POST http://localhost:5000/predict \
 -H "Content-Type: application/json" \
 -d '{
 "series_id": "demo",
 "historical_data": [
 {"timestamp": "2024-01-01T12:00:00", "value": 10},
 {"timestamp": "2024-01-01T12:01:00", "value": 20},
 {"timestamp": "2024-01-01T12:02:00", "value": 30}
 ]
 }'

Redis가 작동 중이라는 응답을 받게 됩니다:

{
 "data_points_used": 3,
 "prediction": 40,
 "redis_connected": true
}

이제 서비스를 다시 시작하세요:

docker compose down
docker compose -f docker-compose.initial.yml up

또 다른 예측을 해보세요. data_points_used을 확인하세요. 필드. 재설정되었습니다. 모든 과거 데이터가 사라졌습니다. 이것이 바로 우리가 피하려고 하는 것입니다.

볼륨 문제를 해결하는 방법

올바른 docker-compose.yml 지속성을 추가합니다:

services:
 api:
 build: ./flask-api
 ports:
 - "5000:5000"
 environment:
 - REDIS_HOST=redis
 redis:
 image: redis:alpine
 command: redis-server --appendonly yes
 volumes:
 - redis_data:/data
volumes:
 redis_data:

그럼 볼륨이란 무엇이고 어떻게 작동하나요?

Docker 볼륨을 컨테이너 전용 외부 하드 드라이브로 생각하세요. 기본적으로 컨테이너가 데이터를 쓸 때 컨테이너가 제거될 때 파괴되는 임시 레이어에 데이터를 씁니다. 볼륨은 해당 데이터를 영구적으로 저장하는 방법을 제공합니다.

작동 방식은 다음과 같습니다:

  1. Docker는 컨테이너의 파일 시스템과 완전히 분리된 호스트 시스템에 특수 저장 영역을 생성하고 관리합니다. docker-compose.yml에서 volumes: redis_data: 하단 섹션은 Docker에게 redis_data이라는 명명된 볼륨을 생성하도록 지시합니다. .

  2. Redis 컨테이너가 시작되면 volumes: - redis_data:/data 줄은 Docker에게 이 외장 하드 드라이브를 "연결"하라고 지시합니다. redis_data을 연결합니다. 볼륨을 /data로 컨테이너 내부의 디렉터리입니다.

  3. 이제 컨테이너 내부의 Redis 프로세스가 /data에 데이터를 쓸 때마다 디렉토리(우리가 구성한), 실제로는 redis_data에 쓰고 있습니다. 호스트 컴퓨터의 볼륨입니다.

  4. docker compose down을 실행하면 Redis 컨테이너가 파괴되지만 redis_data 볼륨은 건드리지 않았습니다. 이는 외장 하드 드라이브를 분리하는 것과 같으며 데이터는 여전히 안전합니다. 다음에 docker compose up을 실행하면 새로운 Redis 컨테이너가 생성되고 볼륨이 다시 연결되며 Redis는 남아 있던 모든 이전 데이터를 바로 찾습니다.

이 메커니즘은 상태 저장 서비스에 재시작 후에도 유지되는 메모리를 제공하는 열쇠입니다.

수정된 버전을 실행하세요:

docker compose up --build

상태를 구축하기 위해 여러 가지 예측을 보냅니다:

for i in {1..5}; do
 curl -X POST http://localhost:5000/predict \
 -H "Content-Type: application/json" \
 -d "{
 \"series_id\": \"demo\",
 \"historical_data\": [{\"timestamp\": \"2024-01-01T12:0$i:00\", \"value\": $((i*10))}]
 }"
done

이제 시험이 다가옵니다. 모든 것을 다시 시작하세요:

docker compose down
docker compose up

또 다른 예측을 해보세요. data_points_used를 보세요 . 여기에는 이전 항목이 모두 포함됩니다. 모델은 중단된 부분부터 정확하게 다시 시작합니다.

이는 볼륨이 컨테이너 수명주기와 독립적으로 존재하기 때문에 가능합니다.

코드가 상태를 처리하는 방법

flask-api/app.py의 Flask API 정렬된 세트를 사용하여 Redis에 각 데이터 포인트를 저장합니다:

def store_data_point(series_id, timestamp, value):
 key = f"ts:{series_id}"
 redis_client.zadd(key, {json.dumps({"ts": timestamp, "val": value}): timestamp})

예측을 할 때 최근 기록을 검색합니다:

def get_recent_data(series_id, limit=100):
 key = f"ts:{series_id}"
 data = redis_client.zrange(key, -limit, -1)
 return [json.loads(d) for d in data]

Redis 정렬 세트는 자동 시간 순서를 제공합니다. 볼륨은 이 데이터가 재시작 후에도 유지되도록 보장합니다.

상태 엔드포인트 테스트

모든 것이 제대로 연결되어 있는지 확인하세요.

curl http://localhost:5000/health

다음 내용을 확인하세요:

{
 "model_loaded": true,
 "redis_connected": true,
 "status": "healthy"
}

redis_connected인 경우 false인 경우 Docker 로그를 확인하세요. 일반적인 문제는 네트워크 구성이나 Redis가 제대로 시작되지 않는 것입니다.

확장은 어떻습니까?

이 설정은 단일 인스턴스 배포에 적합합니다. 트래픽이 증가하면 몇 가지 옵션이 있습니다.

Redis 클러스터를 사용한 수평 확장

높은 처리량을 위해 여러 Redis 노드에 데이터를 배포하세요. Redis 클러스터는 자동으로 샤딩을 처리합니다.

Redis Sentinel을 통한 고가용성

상태 저장소가 단일 실패 지점이 되지 않도록 장애 조치 기능을 추가하세요. Sentinel은 Redis 인스턴스를 모니터링하고 기본 인스턴스에 장애가 발생하면 복제본을 승격합니다.

관리형 Redis 서비스 사용

AWS ElastiCache, Azure Cache for Redis 또는 Google Cloud Memorystore가 운영 부담을 처리합니다. 모델에 집중하면 Redis 안정성이 처리됩니다.

주요 통찰력:API 컨테이너는 상태 비저장 상태로 유지됩니다. 상태 저장소를 독립적으로 확장합니다.

피해야 할 일반적인 함정

아무리 강조해도 지나치지 않습니다. 프로덕션에 배포하기 전에 지속성을 테스트해 보세요.

볼륨이 효과가 있다고 가정하지 마세요

실제로 컨테이너를 다시 시작하고 상태가 지속되는지 확인하세요. 누군가가 프로덕션 환경에서 볼륨을 마운트하는 것을 잊어버렸기 때문에 배포가 실패하는 경우를 보았습니다.

Redis 메모리 제한을 무시하지 마세요

Redis는 모든 것을 메모리에 보관합니다. 메모리 사용량을 모니터링하세요. 워크로드에 적합한 maxmemory 정책을 설정하세요. 메모리가 부족해지면 Redis는 키 제거를 시작하거나 쓰기를 거부합니다.

모니터링을 건너뛰지 마세요

상태 확인을 추가합니다. Redis 연결 상태를 모니터링합니다. 예측 대기 시간을 추적합니다. 화난 사용자로부터 배우기보다는 문제가 언제 발생하는지 알고 싶을 것입니다.

결론

시계열 모델에는 메모리가 필요합니다. Docker 컨테이너는 기본적으로 메모리를 잃습니다. 해결책은 간단합니다. 상태를 컴퓨팅과 분리하는 것입니다.

Redis를 외부 상태 저장소로 사용합니다. 해당 상태를 유지하려면 Docker 볼륨을 사용하세요. 모델은 스마트하게 유지되고, 컨테이너는 교체 가능하며, 배포가 안정적입니다.

전체 작업 코드는 github.com/ag-chirag/docker-redis-time-series에서 확인할 수 있습니다. 복제하고, 실행하고, 중단하고, 교훈을 얻으세요.

그리고 기억하세요:작동하는 가장 간단한 솔루션이 일반적으로 올바른 솔루션입니다. Kubernetes와 StatefulSet가 항상 필요한 것은 아닙니다. 때로는 Docker Compose와 볼륨만으로 충분할 때도 있습니다.

무료로 코딩을 배우세요. freeCodeCamp의 오픈 소스 커리큘럼은 40,000명 이상의 사람들이 개발자로 취업하는 데 도움을 주었습니다. 시작하세요