AlloyDB에서 하이브리드 검색 시작하기

1. 소개

이 Codelab에서는 (순위 업데이트 방법) RUM 확장 프로그램과 확장 가능한 최근접 이웃 (ScaNN) 색인을 사용하여 AlloyDB에서 하이브리드 검색을 수행하는 방법을 알아봅니다. 이 실습은 AlloyDB AI 기능을 위한 실습 모음의 일부입니다. 자세한 내용은 문서의 AlloyDB AI 페이지를 참고하세요.

기본 요건

  • Google Cloud 콘솔에 관한 기본적인 이해
  • 명령줄 인터페이스 및 Google Shell의 기본 기술

학습할 내용

  • AlloyDB 클러스터 및 기본 인스턴스를 배포하는 방법
  • Google Compute Engine VM에서 AlloyDB에 연결하는 방법
  • 데이터베이스를 만들고 AlloyDB AI를 사용 설정하는 방법
  • 데이터베이스에 데이터를 로드하는 방법
  • AlloyDB Studio 사용 방법
  • Vertex AI로 임베딩 생성
  • 벡터 검색을 강화하기 위해 ScaNN 벡터 색인을 만드는 방법
  • 전체 텍스트 검색을 위한 RUM 확장 프로그램을 사용 설정하고 사용하는 방법
  • 전체 텍스트 검색, 벡터 검색, 상호 순위 융합 (RRF)을 결합하여 하이브리드 검색 실행

필요한 항목

  • Google Cloud 계정 및 Google Cloud 프로젝트
  • 웹브라우저(예: Chrome)

2. 설정 및 요구사항

프로젝트 설정

Google Cloud 콘솔에 로그인합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

직장 또는 학교 계정 대신 개인 계정을 사용하세요.

Google Cloud 프로젝트 만들기

  1. Google Cloud 콘솔의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
  2. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

결제 사용 설정

결제를 사용 설정하는 방법에는 두 가지가 있습니다. 개인 결제 계정을 사용하거나 다음 단계에 따라 크레딧을 사용할 수 있습니다.

개인 결제 계정 설정

Google Cloud 크레딧을 사용하여 결제를 설정한 경우 이 단계를 건너뛸 수 있습니다.

개인 결제 계정을 설정하려면 Cloud 콘솔에서 여기에서 결제를 사용 설정하세요.

참고 사항:

  • 이 실습을 완료하는 데 드는 Cloud 리소스 비용은 미화 3달러 미만입니다.
  • 이 실습이 끝나면 단계에 따라 리소스를 삭제하여 추가 요금이 발생하지 않도록 할 수 있습니다.
  • 신규 사용자는 미화$300 상당의 무료 체험판을 사용할 수 있습니다.

Cloud Shell 시작

Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Cloud Shell은 Google Cloud에서 실행되는 명령줄 환경으로, 필요한 도구가 미리 로드되어 제공됩니다.

  1. Google Cloud 콘솔 상단에서 Cloud Shell 활성화를 클릭합니다.
  2. Cloud Shell에 연결되면 인증을 확인합니다.
    gcloud auth list
    
  3. 프로젝트가 구성되었는지 확인합니다.
    gcloud config get project
    
  4. 프로젝트가 예상대로 설정되지 않은 경우 설정합니다.
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

가상 머신에는 필요한 개발 도구가 모두 들어있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab의 모든 작업은 브라우저 내에서 수행할 수 있습니다. 아무것도 설치할 필요가 없습니다.

3. 시작하기 전에

API 사용 설정

출력:

AlloyDB, Compute Engine, 네트워킹 서비스, Vertex AI를 사용하려면 Google Cloud 프로젝트에서 각 API를 사용 설정해야 합니다.

API 사용 설정

터미널의 Cloud Shell 내에 프로젝트 ID가 설정되어 있는지 확인합니다.

gcloud config set project [YOUR-PROJECT-ID]

환경 변수 PROJECT_ID를 설정합니다.

PROJECT_ID=$(gcloud config get-value project)

필요한 모든 API를 사용 설정합니다.

gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com

예상 출력

student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$ 
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

API 소개

  • AlloyDB API (alloydb.googleapis.com)를 사용하면 PostgreSQL용 AlloyDB 클러스터를 만들고, 관리하고, 확장할 수 있습니다. 까다로운 엔터프라이즈 트랜잭션 및 분석 워크로드를 위해 설계된 완전 관리형 PostgreSQL 호환 데이터베이스 서비스를 제공합니다.
  • Compute Engine API (compute.googleapis.com)를 사용하면 가상 머신 (VM), 영구 디스크, 네트워크 설정을 만들고 관리할 수 있습니다. 워크로드를 실행하고 많은 관리형 서비스의 기본 인프라를 호스팅하는 데 필요한 핵심 Infrastructure-as-a-Service (IaaS) 기반을 제공합니다.
  • Cloud Resource Manager API (cloudresourcemanager.googleapis.com)를 사용하면 Google Cloud 프로젝트의 메타데이터와 구성을 프로그래매틱 방식으로 관리할 수 있습니다. 이를 통해 리소스를 구성하고, ID 및 액세스 관리 (IAM) 정책을 처리하고, 프로젝트 계층 구조 전반에서 권한을 검증할 수 있습니다.
  • Service Networking API (servicenetworking.googleapis.com)를 사용하면 가상 프라이빗 클라우드 (VPC) 네트워크와 Google의 관리형 서비스 간의 비공개 연결 설정을 자동화할 수 있습니다. AlloyDB와 같은 서비스가 다른 리소스와 안전하게 통신할 수 있도록 비공개 IP 액세스를 설정해야 합니다.
  • Vertex AI API (aiplatform.googleapis.com)를 사용하면 애플리케이션에서 머신러닝 모델을 빌드, 배포, 확장할 수 있습니다. 생성형 AI 모델 (예: Gemini) 및 맞춤 모델 학습에 대한 액세스를 비롯한 모든 Google Cloud AI 서비스의 통합 인터페이스를 제공합니다.

선택적으로 Vertex AI 임베딩 모델을 사용하도록 기본 리전을 구성할 수 있습니다. Vertex AI에 사용할 수 있는 위치에 대해 자세히 알아보세요. 이 예에서는 us-central1 리전을 사용합니다.

gcloud config set compute/region us-central1

4. AlloyDB 배포

AlloyDB 클러스터를 만들기 전에 향후 AlloyDB 인스턴스에서 사용할 수 있는 비공개 IP 범위가 VPC에 있어야 합니다. 이 계정이 없으면 계정을 만들어 내부 Google 서비스에서 사용하도록 할당해야 클러스터와 인스턴스를 만들 수 있습니다.

비공개 IP 범위 만들기

VPC에서 AlloyDB용 비공개 서비스 액세스 구성을 설정해야 합니다. 여기서는 프로젝트에 '기본' VPC 네트워크가 있고 이 네트워크가 모든 작업에 사용된다고 가정합니다.

비공개 IP 범위를 만듭니다.

gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default

할당된 IP 범위를 사용하여 비공개 연결을 만듭니다.

gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range].

student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default
Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully.

student@cloudshell:~ (test-project-402417)$

AlloyDB 클러스터 만들기

이 섹션에서는 us-central1 리전에 AlloyDB 클러스터를 만듭니다.

postgres 사용자의 비밀번호를 정의합니다. 비밀번호를 직접 정의하거나 무작위 함수를 사용하여 생성할 수 있습니다.

export PGPASSWORD=`openssl rand -hex 12`

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`

나중에 사용할 수 있도록 PostgreSQL 비밀번호를 기록해 둡니다.

echo $PGPASSWORD

나중에 postgres 사용자로 인스턴스에 연결하려면 이 비밀번호가 필요합니다. 나중에 사용할 수 있도록 적어 두거나 어딘가에 복사해 두는 것이 좋습니다.

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD
bbefbfde7601985b0dee5723

AlloyDB 클러스터 만들기

리전과 AlloyDB 클러스터 이름을 정의합니다. us-central1 리전과 alloydb-hybrid-search를 클러스터 이름으로 사용합니다.

export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search

명령어를 실행하여 클러스터를 만듭니다.

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION

예상되는 콘솔 출력:

export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION 
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

동일한 Cloud Shell 세션에서 클러스터의 AlloyDB 기본 인스턴스를 만듭니다. 연결이 해제되면 리전 및 클러스터 이름 환경 변수를 다시 정의해야 합니다.

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

예상되는 콘솔 출력:

student@cloudshell:~ (alloydb-hybrid-search)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

5. AlloyDB에 연결

AlloyDB는 비공개 연결을 사용하여 배포되므로 데이터베이스와 함께 작동하려면 PostgreSQL 클라이언트가 설치된 VM이 필요합니다.

GCE VM 배포

AlloyDB 클러스터와 동일한 리전 및 VPC에 GCE VM을 만듭니다.

Cloud Shell에서 다음을 실행합니다.

export ZONE=us-central1-a
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

예상되는 콘솔 출력:

student@cloudshell:~ (alloydb-hybrid-search)$ export ZONE=us-central1-a
student@cloudshell:~ (talloydb-hybrid-search)$ export ZONE=us-central1-a
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/zones/us-central1-a/instances/instance-1].
NAME: instance-1
ZONE: us-central1-a
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE: 
INTERNAL_IP: 10.128.0.2
EXTERNAL_IP: 34.71.192.233
STATUS: RUNNING

Postgres 클라이언트 설치

배포된 VM에 PostgreSQL 클라이언트 소프트웨어 설치

VM에 연결합니다.

gcloud compute ssh instance-1 --zone=us-central1-a

예상되는 콘솔 출력:

student@cloudshell:~ (alloydb-hybrid-search)$ gcloud compute ssh instance-1 --zone=us-central1-a
Updating project ssh metadata...working..Updated [https://www.googleapis.com/compute/v1/projects/alloydb-hybrid-search].                                                                                                                                                         
Updating project ssh metadata...done.                                                                                                                                                                                                                                              
Waiting for SSH key to propagate.
Warning: Permanently added 'compute.5110295539541121102' (ECDSA) to the list of known hosts.
Linux instance-1.us-central1-a.c.gleb-test-short-001-418811.internal 6.1.0-18-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
student@instance-1:~$ 

VM 내에 명령어를 실행할 소프트웨어를 설치합니다.

sudo apt-get update
sudo apt-get install --yes postgresql-client

예상되는 콘솔 출력:

student@instance-1:~$ sudo apt-get update
sudo apt-get install --yes postgresql-client
Get:1 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable InRelease [5146 B]
Get:2 https://packages.cloud.google.com/apt cloud-sdk-bullseye InRelease [6406 B]   
Hit:3 https://deb.debian.org/debian bullseye InRelease  
Get:4 https://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:5 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable/main amd64 Packages [1930 B]
Get:6 https://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:7 https://deb.debian.org/debian bullseye-backports InRelease [49.0 kB]
...redacted...
update-alternatives: using /usr/share/postgresql/13/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-client (13+225) ...
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+deb11u7) ...

인스턴스에 연결

psql을 사용하여 VM에서 기본 인스턴스에 연결합니다.

인스턴스-1 VM에 대해 열린 SSH 세션이 있는 동일한 Cloud Shell 탭에서

앞서 언급한 AlloyDB 비밀번호 (PGPASSWORD) 값과 AlloyDB 클러스터 ID를 사용하여 GCE VM에서 AlloyDB에 연결합니다.

export PGPASSWORD=<Noted password>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"

예상되는 콘솔 출력:

student@instance-1:~$ export PGPASSWORD=CQhOi5OygD4ps6ty
student@instance-1:~$ ADBCLUSTER=alloydb-aip-01
student@instance-1:~$ REGION=us-central1
student@instance-1:~$ INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
gleb@instance-1:~$ psql "host=$INSTANCE_IP user=postgres sslmode=require"
psql (15.6 (Debian 15.6-0+deb12u1), server 15.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

psql 세션을 닫습니다.

exit

6. 데이터베이스 준비

데이터베이스를 만들고, Vertex AI 통합을 사용 설정하고, 데이터베이스 객체를 만들고, 데이터를 가져와야 합니다.

AlloyDB에 필요한 권한 부여

AlloyDB 서비스 에이전트에 Vertex AI 권한을 추가합니다.

맨 위에 있는 '+' 기호를 사용하여 다른 Cloud Shell 탭을 엽니다.

abc505ac4d41f24e.png

새 Cloud Shell 탭에서 다음을 실행합니다.

PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-11039]
student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"
Updated IAM policy for project [test-project-001-402417].
bindings:
- members:
  - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com
  role: roles/aiplatform.user
- members:
...
etag: BwYIEbe_Z3U=
version: 1
 

탭에서 실행 명령어 'exit' 중 하나를 사용하여 탭을 닫습니다.

exit

데이터베이스 만들기

quickstart라는 데이터베이스를 만듭니다.

GCE VM 세션에서 다음을 실행합니다.

데이터베이스를 만듭니다.

psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"

예상되는 콘솔 출력:

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"
CREATE DATABASE
student@instance-1:~$  

Vertex AI 통합 사용 설정

데이터베이스에서 Vertex AI 통합 및 pgvector 확장 프로그램을 사용 설정합니다.

GCE VM에서 다음을 실행합니다.

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"

예상되는 콘솔 출력:

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"
CREATE EXTENSION
CREATE EXTENSION
student@instance-1:~$ 

데이터 가져오기

준비된 데이터를 다운로드하고 새 데이터베이스로 가져옵니다.

GCE VM에서 다음을 실행합니다.

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"

예상되는 콘솔 출력:

student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
SET
SET
SET
SET
SET
 set_config 
------------
 
(1 row)
SET
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER SEQUENCE
ALTER TABLE
ALTER TABLE
ALTER TABLE
student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
COPY 941
student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
COPY 263861
student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"
COPY 4654
student@instance-1:~$

7. 벡터 임베딩 생성

데이터를 가져온 후에는 제품에 관한 정보를 저장하는 cymbal_products 테이블, 각 매장의 상품 재고를 추적하는 cymbal_inventory 테이블, 매장 목록인 cymbal_stores 테이블이 있습니다. 제품에 대한 시맨틱 검색을 수행하려면 initialize_embeddings 함수를 사용하여 제품 설명의 벡터 임베딩을 생성해야 합니다. Vertex AI 통합을 사용하여 제품 설명을 기반으로 벡터 데이터를 계산하고 표에 추가합니다. 사용된 기술에 대한 자세한 내용은 문서를 참고하세요.

통합을 사용하려면 AlloyDB 인스턴스 IP와 postgres 비밀번호를 사용하여 VM에서 psql을 사용하여 데이터베이스에 연결합니다.

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"

google_ml_integration 확장 프로그램의 버전을 확인합니다.

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

버전은 1.5.2 이상이어야 합니다. 출력 예시는 다음과 같습니다.

quickstart_db=> SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
 extversion 
------------
 1.5.2
(1 row)

기본 버전은 1.5.2 이상이어야 하지만 인스턴스에 이전 버전이 표시되면 업데이트해야 할 수 있습니다. 인스턴스에 유지보수가 사용 중지되었는지 확인합니다.

효율성을 높이기 위해 일괄 임베딩 생성이 사용됩니다. 다양한 임베딩 생성 옵션과 기법에 대한 자세한 내용은 가이드를 참고하세요. 일괄 삽입을 사용하려면 goole_ml_integration.enable_faster_embedding_generation을 사용 설정해야 합니다.

show google_ml_integration.enable_faster_embedding_generation;

플래그가 올바른 위치에 있으면 예상 출력은 다음과 같습니다.

quickstart_db=> show google_ml_integration.enable_faster_embedding_generation;                          
 google_ml_integration.enable_faster_embedding_generation 
----------------------------------------------------------
 on
(1 row)

하지만 '사용 안함'으로 표시되면 인스턴스를 업데이트해야 합니다. 문서에 설명된 대로 웹 콘솔 또는 gcloud 명령어를 사용하여 이 작업을 수행할 수 있습니다. 다음은 gcloud 명령어를 사용하여 이 작업을 수행하는 방법을 보여줍니다.

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
   --database-flags google_ml_integration.enable_faster_embedding_generation=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY

몇 분 정도 걸릴 수 있지만 결국 플래그 값이 'on'으로 전환됩니다. 그런 다음 다음 단계를 진행할 수 있습니다.

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"

데이터베이스에 연결된 psql 세션에서 cymbal_products에 임베딩을 저장할 새 열을 만듭니다.

ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768);

예상되는 콘솔 출력:

quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768);
ALTER TABLE
quickstart_db=> 

마지막으로 함수 호출에 incremental_refresh_mode 인수를 포함하여 열 값이 변경될 때마다 임베딩이 새로고침되도록 합니다. 이로 인해 데이터베이스에 오버헤드가 발생하지만 콘텐츠와 임베딩을 자동으로 동기화하기 위한 절충안입니다. 직접 삽입을 업데이트하려면 문서에서 안내를 확인하세요.

이제 모든 것을 합쳐 임베딩을 생성합니다. initialize_embeddings 함수를 사용하고 50의 batch_size을 배치 힌트로 전달하고 incremental_refresh_modetransactional로 설정합니다.

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'cymbal_products',
    content_column => 'product_description',
    embedding_column => 'product_embedding',
    batch_size => 50,
    incremental_refresh_mode => 'transactional'
);

이제 product_embedding 열에 NULL 값을 사용하여 테이블에 새 행을 삽입하면

INSERT INTO "cymbal_products" ("uniq_id", "crawl_timestamp", "product_url", "product_name", "product_description", "list_price", "sale_price", "brand", "item_number", "gtin", "package_size", "category", "postal_code", "available", "product_embedding") VALUES ('fd604542e04b470f9e6348e640cff794', NOW(), 'https://example.com/new_product', 'New Cymbal Product', 'This is a new cymbal product description.', 199.99, 149.99, 'Example Brand', 'EB123', '1234567890', 'Single', 'Cymbals', '12345', TRUE, NULL);

이제 방금 삽입한 행을 쿼리하면 product_embedding 열이 자동으로 업데이트되는 것을 확인할 수 있습니다.

SELECT uniq_id, (product_embedding::real[])[1:5] as product_embedding  FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';

다음과 유사하게 출력됩니다.

quickstart_db=> SELECT uniq_id,(product_embedding::real[])[1:5] as product_embedding  FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
             uniq_id              |                      product_embedding                       
----------------------------------+---------------------------------------------------------------
 fd604542e04b470f9e6348e640cff794 | {0.015003494,-0.005349732,-0.059790313,-0.0087091,-0.0271452}
(1 row)

Time: 3.295 ms

8. 벡터 색인 만들기

벡터 검색 성능을 개선하기 위해 ScaNN 색인을 추가합니다.

ScaNN 색인 만들기

SCANN 색인을 빌드하려면 확장 프로그램을 하나 더 사용 설정해야 합니다. alloydb_scann 확장 프로그램은 Google의 ScaNN 알고리즘을 사용하여 ANN 유형 벡터 색인을 사용할 수 있는 인터페이스를 제공합니다.

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

예상 출력:

quickstart_db=> CREATE EXTENSION IF NOT EXISTS alloydb_scann;
CREATE EXTENSION
Time: 27.468 ms
quickstart_db=> 

색인은 MANUAL 또는 AUTO 모드로 만들 수 있습니다. MANUAL 모드는 기본적으로 사용 설정되어 있으며 다른 색인과 마찬가지로 색인을 생성하고 유지할 수 있습니다. 하지만 AUTO 모드를 사용 설정하면 유지보수가 필요하지 않은 색인을 만들 수 있습니다. 모든 옵션에 대한 자세한 내용은 문서를 참고하세요. 이 경우 AUTO 모드에서 색인을 만들기에 충분한 행이 없으므로 MANUAL로 만들고 조정 매개변수를 포함합니다. 문서에서 색인 매개변수 조정에 관해 자세히 알아볼 수 있습니다.

튜닝 매개변수를 수정할 수 있도록 scann.enable_preview_features 플래그를 사용 설정해야 합니다. Cloud Shell에서

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
   --database-flags scann.enable_preview_features=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY

몇 분 정도 걸릴 수 있지만 결국 플래그 값이 'on'으로 전환됩니다. 플래그가 설정되면 VM에서 psql 세션으로 다시 전환하여 조정 매개변수로 색인을 만들 수 있습니다.

CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
  USING scann (product_embedding cosine)
  WITH (mode='MANUAL', num_leaves=31, max_num_levels = 2);

예상 출력:

quickstart_db=> CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
  USING scann (product_embedding cosine)
  WITH (num_leaves=31, max_num_levels = 2);
CREATE INDEX
quickstart_db=>

색인 사용 검사

이제 EXPLAIN 모드에서 벡터 검색 쿼리를 실행하고 색인이 사용되고 있는지 확인할 수 있습니다.

EXPLAIN (analyze) 
WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (cp.product_embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

예상 출력 (명확히 하자면):

...
Aggregate (cost=16.59..16.60 rows=1 width=32) (actual time=2.875..2.877 rows=1 loops=1)
-> Subquery Scan on trees (cost=8.42..16.59 rows=1 width=142) (actual time=2.860..2.862 rows=1 loops=1)
-> Limit (cost=8.42..16.58 rows=1 width=158) (actual time=2.855..2.856 rows=1 loops=1)
-> Nested Loop (cost=8.42..6489.19 rows=794 width=158) (actual time=2.854..2.855 rows=1 loops=1)
-> Nested Loop (cost=8.13..6466.99 rows=794 width=938) (actual time=2.742..2.743 rows=1 loops=1)
-> Index Scan using cymbal_products_embeddings_scann on cymbal_products cp (cost=7.71..111.99 rows=876 width=934) (actual time=2.724..2.724 rows=1 loops=1)
Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,-0.00355923,0.0055611245,0.015985578,...<redacted>...5685,-0.03914233,-0.018452475,0.00826032,-0.07372604]'::vector)
...

출력에서 쿼리가 'cymbal_products의 cymbal_products_embeddings_scann을 사용한 색인 스캔'을 사용하고 있음을 명확하게 확인할 수 있습니다.

9. 전체 텍스트 검색 색인

AlloyDB는 네이티브 PostgreSQL에서 지원하는 전체 텍스트 검색의 모든 색인 유형을 지원합니다. 인덱스 선택은 검색 속도, 인덱스 빌드 시간, 업데이트 속도, 구문 검색 또는 관련성 순위와 같은 필요한 특정 검색 기능 간의 균형에 따라 달라집니다.

이 예에서는 더 나은 성능의 전체 텍스트 검색 작업을 위해 RUM 확장 프로그램을 사용합니다. RUM은 색인에 위치 정보를 직접 저장하여 표준 GIN 색인을 개선하므로 테이블 데이터에 액세스하지 않고도 더 빠른 구문 검색과 관련성 순위 지정을 실행할 수 있습니다.

AlloyDB Studio를 사용하거나 psql 클라이언트를 계속 사용하여 rum 확장 프로그램을 사용 설정할 수 있습니다.

RUM 색인 만들기

CREATE EXTENSION IF NOT EXISTS rum;

cymbal_products 테이블 내에서 제품 설명을 검색하려면 제품 설명을 tsvector로 저장하는 열을 만들어야 합니다. 이 열은 처리된 텍스트를 자동으로 저장하고 쿼리 성능을 개선합니다.

ALTER TABLE cymbal_products
ADD COLUMN product_search_vector tsvector
GENERATED ALWAYS AS (to_tsvector('english', product_description)) STORED;

이제 product_search_vector 열에 대한 새 RUM 색인을 만들 수 있습니다.

CREATE INDEX cymbal_products_rum
ON cymbal_products
USING rum (product_search_vector rum_tsvector_ops);

색인을 사용하여 테이블을 쿼리하려면 'cherry tree'와 일치하는 항목을 검색하는 다음 쿼리를 실행합니다. <=> 연산자는 색인에서 직접 문서와 쿼리 간의 관련성 점수 또는 거리를 계산합니다.

SELECT product_name, product_description
FROM cymbal_products
WHERE product_search_vector @@ to_tsquery('english', 'cherry <-> tree')
ORDER BY product_search_vector <=> to_tsquery('english', 'cherry <-> tree');

10. 하이브리드 검색 실행

google_vector_utils.hybrid_search() 기능을 사용하면 벡터 검색, 전체 텍스트 검색 등 여러 검색 유형의 결과를 결합할 수 있습니다. 이 함수는 상호 순위 융합 (RRF) 알고리즘을 사용하여 각 검색 구성요소의 순위가 지정된 결과를 단일 통합 목록으로 융합합니다. 이 방식을 사용하면 단일 검색 유형만 사용하는 것보다 관련성이 높은 결과를 얻을 수 있습니다.

hybrid_search() 함수는 단일 SQL 쿼리를 동적으로 구성하고 실행합니다. 정의한 각 검색 구성요소에 대해 공통 테이블 표현식 (CTE)을 만듭니다. 그런 다음 이 함수는 모든 CTE의 결과를 조인하고 각 문서의 최종 RRF 점수를 계산하여 통합된 순위 목록을 생성합니다.

이 함수를 사용하려면 기본 인스턴스에서 enable_preview_ai_functions를 사용 설정해야 합니다. Cloud Shell에서 다음 명령어를 실행합니다.

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
   --database-flags google_ml_integration.enable_preview_ai_functions=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY

다음 쿼리는 이전 벡터 검색 질문과 전체 텍스트 검색 질문을 결합합니다. 이는 매우 간단한 하이브리드 검색 쿼리입니다. 벡터 검색 구성요소에 '집보다 큰 나무'를 사용하고 FTS 구성요소에 '캘리포니아'를 사용하는 등 더 복잡한 검색을 시도해 볼 수 있습니다.

SELECT score, id, p.product_name
FROM ai.hybrid_search(
  search_inputs => ARRAY[
      '{
        "data_type": "vector",
        "table_name": "cymbal_products",
        "key_column": "uniq_id",
        "vec_column": "product_embedding",
        "distance_operator": "public.<=>",
        "limit": 5,
        "query_vector": "ai.embedding(''text-embedding-005'', ''cherry'')::vector"
      }'::JSONB,
      '{
        "data_type": "text",
        "table_name": "cymbal_products",
        "key_column": "uniq_id",
        "text_column": "product_search_vector",
        "limit": 5,
        "ranking_function": "<=>",
        "query_text_input": "tree"
      }'::JSONB
  ]
) JOIN cymbal_products p ON id = p.uniq_id;

예상 출력

"score","id","product_name"
"0.00819672631147241","d536e9e823296a2eba198e52dd23e712","Cherry Tree"
"0.015873015873015872","23e41a71d63d8bbc9bdfa1d118cfddc5","Apple Tree"
"0.00819672631147241","dc789a2f87b142e94e6e325689482af9","Oak Tree"
"0.008064521129029258","f5c70d62ccf3118d73863bf3b17edcbe","Cypress Tree"
"0.008064521129029258","b70c44b1a38c0a2329fa583c9109a80f","Peach Tree"

결과에는 지정된 key_columnid가 표시되고 score는 RRF에서 계산한 최종 값입니다. 상호 순위 융합 (RRF)은 각 문서에 점수를 할당하여 여러 순위가 지정된 검색 결과 목록을 단일 순위가 지정된 목록으로 결합하는 순위 기반 알고리즘입니다. 이 점수는 모든 기여 목록에서 RRF의 역수 순위를 기반으로 하며, 순위가 높은 문서가 더 많이 기여합니다. 매개변수에서 include_json_output => true를 사용하면 각 구성요소의 점수 계산 분석이 포함된 detail_json 열이 반환됩니다.

전체 텍스트 검색은 특정 용어나 정확한 일치 항목을 찾는 데 가장 적합하지만, 벡터 검색은 단어가 일치하지 않더라도 동의어와 의도를 찾는 데 탁월합니다. 이 두 가지 방법을 병합하여 하이브리드 검색은 사용자가 문자 그대로 정확하고 의미적으로 관련성이 높은 강력한 결과 집합을 얻을 수 있도록 합니다.

11. 환경 정리

실습을 마치면 AlloyDB 인스턴스와 클러스터를 폐기합니다.

AlloyDB 클러스터 및 모든 인스턴스 삭제

AlloyDB 무료 체험판을 사용한 경우 체험 클러스터를 사용하여 다른 실습과 리소스를 테스트할 계획이 있다면 체험 클러스터를 삭제하지 마세요. 동일한 프로젝트에서 다른 체험 클러스터를 만들 수 없습니다.

클러스터는 옵션 강제로 폐기되며, 클러스터에 속한 모든 인스턴스도 삭제됩니다.

연결이 끊어지고 이전 설정이 모두 손실된 경우 Cloud Shell에서 프로젝트와 환경 변수를 정의합니다.

gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export PROJECT_ID=$(gcloud config get-value project)

다음과 같이 클러스터를 삭제합니다.

gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
All of the cluster data will be lost when the cluster is deleted.

Do you want to continue (Y/n)?  Y

Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f
Deleting cluster...done.   

AlloyDB 백업 삭제

클러스터의 모든 AlloyDB 백업을 삭제합니다.

for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f
Deleting backup...done.                                                                                                                                                                                                                                                            

이제 VM을 폐기할 수 있습니다.

GCE VM 삭제

Cloud Shell에서 다음을 실행합니다.

export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
    --zone=$ZONE \
    --quiet

예상되는 콘솔 출력:

student@cloudshell:~ (test-project-001-402417)$ export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
    --zone=$ZONE \
    --quiet
Deleted

12. 축하합니다

축하합니다. Codelab을 완료했습니다.

학습한 내용

  • AlloyDB 클러스터 및 기본 인스턴스를 배포하는 방법
  • Google Compute Engine VM에서 AlloyDB에 연결하는 방법
  • 데이터베이스를 만들고 AlloyDB AI를 사용 설정하는 방법
  • 데이터를 데이터베이스에 로드하는 방법
  • AlloyDB Studio 사용 방법
  • Vertex AI로 임베딩 생성
  • 벡터 검색을 강화하기 위해 ScaNN 벡터 색인을 만드는 방법
  • 전체 텍스트 검색을 위한 RUM 확장 프로그램을 사용 설정하고 사용하는 방법
  • 전체 텍스트 검색, 벡터 검색, 상호 순위 융합 (RRF)을 결합하여 하이브리드 검색 실행