💡 chromaDB 

= FastAPI + ClickHouse 데이터베이스

 

FastAPI 문서에서 제공하는 방법을 통해 ClcikHouse 데이터베이스에 직접 접근하지 않고

chromaDB를 사용해 데이터를 관리


 

FastAPI 기반

ClickHouse와 상호작용하기 위한 REST API를 제공하는 역할

chromaDB 서버를 실행하기 위해 Uvicorn 사용

 

ClickHouse 데이터베이스

실제 데이터 저장 공간

chromaDB 내부에서 사용되는 DB 엔진

클러스터 환경에서 사용할 수 있는 분산 데이터베이스 시스템

클러스터는 여러 개의 노드로 구성

각 노드는 데이터를 저장하고 처리하는 역할을 수행

노드 간의 통신은 ClickHouse의 TCP 인터페이스를 통해 이루어짐

클러스터의 노드들은 서로 TCP 연결을 맺고 데이터를 주고 받음

각 노드는 분산 데이터 처리 및 병렬 쿼리 실행을 위해 통신하여 작업을 분산하고 결과를 조합

 


 

설치

구성하려는 환경은 다음과 같다.

1. chromaDB

2. chromaDB client (python 개발 환경)

 

 

✔ chromaDB git hub clone (https://github.com/chroma-core/chroma)

해당 repo를 clone하면 docker-compose.yml 파일을 볼 수 있다.

version: '3.9'

networks:
  net:
    driver: bridge

services:
  server:
    image: server
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/chroma
      - index_data:/index_data
    command: uvicorn chromadb.app:app --reload --workers 1 --host 0.0.0.0 --port 8000 --log-config log_config.yml
    environment:
      - CHROMA_DB_IMPL=clickhouse
      - CLICKHOUSE_HOST=clickhouse
      - CLICKHOUSE_PORT=8123
    ports:
      - 8000:8000
    depends_on:
      - clickhouse
    networks:
      - net

  clickhouse:
    image: clickhouse/clickhouse-server:22.9-alpine
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - CLICKHOUSE_TCP_PORT=9000
      - CLICKHOUSE_HTTP_PORT=8123
    ports:
      - '8123:8123'
      - '9000:9000'
    volumes:
      - clickhouse_data:/var/lib/clickhouse
      - clickhouse_logs:/var/log/clickhouse-server
      - backups:/backups
      - ./config/backup_disk.xml:/etc/clickhouse-server/config.d/backup_disk.xml
      - ./config/chroma_users.xml:/etc/clickhouse-server/users.d/chroma.xml
    networks:
      - net

volumes:
  clickhouse_data:
    driver: local
  clickhouse_logs:
    driver: local
  index_data:
    driver: local
  backups:
    driver: local

앞서 언급한대로 FastAPI와 ClickHouse 데이터베이스를 컨테이너로 띄운다.

✔ 여기서 실제 chromaDB를 조작하기 위해 client를 설치해야 한다.

 

몇 가지 방법이 있는데

1. server 컨테이너 내에 client 설치

2. python 컨테이너를 따로 띄워 network 연결

3. docker-compose 파일에 python service 추가

 

1번이 가장 쉽겠지만 운영 단계에서는 적합하지 않다.

나는 한 번에 실행하고 싶었기에 3번을 선택했다.

version: '3.9'

networks:
  net:
    driver: bridge

services:
  server:
    image: server
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/chroma
      - index_data:/index_data
    command: uvicorn chromadb.app:app --reload --workers 1 --host 0.0.0.0 --port 8000 --log-config log_config.yml
    environment:
      - CHROMA_DB_IMPL=clickhouse
      - CLICKHOUSE_HOST=clickhouse
      - CLICKHOUSE_PORT=8123
    ports:
      - 8000:8000
    depends_on:
      - clickhouse
    networks:
      - net

  clickhouse:
    image: clickhouse/clickhouse-server:22.9-alpine
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - CLICKHOUSE_TCP_PORT=9000
      - CLICKHOUSE_HTTP_PORT=8123
    ports:
      - '8123:8123'
      - '9000:9000'
    volumes:
      - clickhouse_data:/var/lib/clickhouse
      - clickhouse_logs:/var/log/clickhouse-server
      - backups:/backups
      - ./config/backup_disk.xml:/etc/clickhouse-server/config.d/backup_disk.xml
      - ./config/chroma_users.xml:/etc/clickhouse-server/users.d/chroma.xml
    networks:
      - net

  gpt_python_dev:
    image: python:3.8.16-slim-buster
    stdin_open: true
    tty: true
    volumes:
      - ../VectorDB/:/vectorDB_client
    networks:
      - net

volumes:
  clickhouse_data:
    driver: local
  clickhouse_logs:
    driver: local
  index_data:
    driver: local
  backups:
    driver: local

 

처음엔 stdin_open과 tty 옵션을 정의하지 않았다.

 

docker-compose up -d --build 명령어를 통해 컨테이너를 실행시키자 gpt_python_dev 컨테이너가 실행되자마자 죽었다.

원인은 python service에는 'command' 또는 'entrypoint' 등 실행할 명령이나 프로세스가 지정되어 있지 않아서다.

이로 인해 컨테이너가 시작되고 바로 종료되는 현상이 발생하게 된다.

 

컨테이너는 컨테이너 내에서 실행할 프로세스 또는 명령이 필요한데

서비스가 시작되면 컨테이너 내에서 해당 프로세스 또는 명령이 실행되고,

해당 프로세스 또는 명령이 종료되지 않는 한 컨테이너는 계속 실행된다.

 

어떠한 스크립트를 실행해도 스크립트가 종료되면 컨테이너도 종료된다.

이를 막기 위해 Dockerfile을 만들고 스크립트를 while문으로 돌리는 방법이 있다.

# Dockerfile

FROM python:3.8.16-slim-buster

WORKDIR /app
COPY . /app

# 필요한 의존성 설치 등의 작업 수행

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

CMD ["/bin/bash", "/entrypoint.sh"]
# entrypoint.sh

#!/bin/bash

# 추가적인 초기화 작업 수행

while true; do
  python my_script.py
done

하지만 나는 stdin_open과 tty옵션을 사용했다.

  • stdin_open: true 
    • 컨테이너의 표준 입력을 열어놓음
    • 이 옵션을 통해 컨테이너 내부에서 키보드 입력을 받을 수 있게 됨
  • tty: true
    • 컨테이너의 TTY(터미널)을 활성화 함
    • 이 옵션을 사용하면 컨테이너 내부에서 터미널 명령을 실행하고 출력을 확인할 수 있게 됨

 

해당 옵션들을 통해 컨테이너가 종료되지 않고 계속해서 상호작용할 수 있도록 했다.

 

잘 안보이긴 하지만.. chroma_server_1, chroma_clickhouse_1, chroma_gpt_python_dev_1 컨테이너 실행 중

 

이어서 chromaDB client 코드를 살펴보자.