이 페이지에서는 빈 벡터 검색 엔드포인트를 식별하고 삭제하는 방법을 설명합니다. Vector Search 엔드포인트는 작업 영역별 리소스이므로 각 작업 영역에 대해 이 프로세스를 별도로 반복해야 합니다.
요구 사항
- Python용 Databricks SDK(
databricks-sdk). - Databricks Vector Search Python SDK(
databricks-vectorsearch). - 구성된 인증(OAuth, PAT 또는 구성 프로필).
-
CAN_MANAGE대상 작업 영역의 벡터 검색 엔드포인트에 대한 사용 권한입니다.
Databricks Notebook 또는 로컬 Python 환경에 필요한 SDK를 설치하려면 다음을 수행합니다.
# In a Databricks notebook
%pip install databricks-sdk databricks-vectorsearch
# In local Python environment
# pip install databricks-sdk databricks-vectorsearch
빈 엔드포인트 식별
Databricks UI에서 벡터 검색 엔드포인트는 컴퓨팅 화면의 벡터 검색 탭에 표시됩니다. 연결된 인덱 스가 없는 엔드포인트를 표시하려면 빈 엔드 포인트 확인란을 전환합니다. 빈 엔드포인트도 표시된 것처럼 경고 삼각형 아이콘으로 표시됩니다.
Authentication
이 섹션에서는 인증 옵션에 대해 설명합니다.
옵션 1. Databricks Notebook 내에서 실행
Databricks 작업 영역 Notebook에서 코드를 실행하면 인증이 자동으로 수행됩니다.
from databricks.vector_search.client import VectorSearchClient
# Credentials are picked up automatically from notebook context
client = VectorSearchClient()
옵션 2. PAT(개인용 액세스 토큰)
외부 환경의 경우 명시적 자격 증명을 제공합니다.
from databricks.vector_search.client import VectorSearchClient
client = VectorSearchClient(
workspace_url="https://<your-instance>.cloud.databricks.com",
personal_access_token="dapiXXXXXXXXXXXXXXXXXXXXXXXX"
)
옵션 3. 구성 프로필 사용(여러 작업 영역에 권장)
.databrickscfg 홈 디렉터리에 파일을 만들고 각 작업 영역에 대한 프로필을 포함합니다.
[DEFAULT]
host = https://workspace1.cloud.databricks.com
token = dapiXXXXXXXXXXXXXXXXXXXXXXXX
[PRODUCTION]
host = https://workspace2.cloud.databricks.com
token = dapiYYYYYYYYYYYYYYYYYYYYYYYY
[DEVELOPMENT]
host = https://workspace3.cloud.databricks.com
token = dapiZZZZZZZZZZZZZZZZZZZZZZZZ
구성 프로필을 사용하지 않으려는 경우 자격 증명을 직접 지정할 수 있습니다.
# Define workspaces with explicit credentials
workspace_configs = [
{
'workspace_url': 'https://workspace1.cloud.databricks.com',
'token': 'dapiXXXXXXXXXXXXXXXXXXXXXXXX'
},
{
'workspace_url': 'https://workspace2.cloud.databricks.com',
'token': 'dapiYYYYYYYYYYYYYYYYYYYYYYYY'
}
]
# Run cleanup, set `dry_run=False` to perform actual deletion
results = cleanup_multiple_workspaces(workspace_configs, dry_run=True)
단일 작업 영역에서 엔드포인트 삭제
벡터 검색 엔드포인트는 작업 영역별입니다. 다음은 단일 작업 영역에서 빈 엔드포인트를 찾아 삭제하는 기본 스크립트입니다. 여러 작업 영역에서 빈 엔드포인트를 정리하려면 여러 작업 영역에서 엔드포인트 삭제를 참조하세요.
중요합니다
엔드포인트 삭제는 되돌릴 수 없습니다. 이 옵션을 dry_run=True 사용하여 삭제할 엔드포인트 목록을 볼 수 있습니다. 목록이 올바른지 확인한 후에는 다음을 사용하여 스크립트 dry_run=False를 실행합니다.
from databricks.vector_search.client import VectorSearchClient
def cleanup_empty_endpoints(client, dry_run=True):
"""
Find and delete empty Vector Search endpoints.
Args:
client: VectorSearchClient instance
dry_run: If True, only print what would be deleted without actually deleting
Returns:
List of deleted endpoint names
"""
deleted_endpoints = []
# List all Vector Search endpoints
endpoints = client.list_endpoints()
for endpoint in endpoints["endpoints"]:
# List indexes in this endpoint
indexes = list(client.list_indexes(name=endpoint["name"])['vector_indexes'])
if len(indexes) == 0:
if dry_run:
print(f"[DRY RUN] Would delete empty endpoint: '{endpoint["name"]}'")
else:
print(f"Deleting empty endpoint: '{endpoint["name"]}'")
try:
client.delete_endpoint(endpoint["name"])
deleted_endpoints.append(endpoint["name"])
print(f"✓ Successfully deleted: {endpoint["name"]}")
except Exception as e:
print(f"✗ Failed to delete {endpoint["name"]}: {str(e)}")
else:
print(f"Endpoint '{endpoint["name"]}' has {len(indexes)} indexes - keeping")
return deleted_endpoints
# Example usage
client = VectorSearchClient() # Uses default authentication
# Set `dry_run=False` when you are ready to delete endpoints
deleted = cleanup_empty_endpoints(client, dry_run=True)
print(f"\nTotal endpoints deleted: {len(deleted)}")
여러 작업 영역에서 엔드포인트 삭제
여러 작업 영역에서 빈 엔드포인트를 정리하려면 구성 프로필을 반복합니다.
중요합니다
엔드포인트 삭제는 되돌릴 수 없습니다. 이 옵션을
dry_run=True사용하여 삭제할 엔드포인트 목록을 볼 수 있습니다. 목록이 올바른지 확인한 후에는 다음을 사용하여 스크립트dry_run=False를 실행합니다.많은 작업 영역을 처리할 때 API 속도 제한을 염두에 두어야 합니다. 필요한 경우 지연을 추가합니다.
import time for config in workspace_configs: # Set `dry_run=False` to perform actual deletion result = cleanup_workspace(**config, dry_run=True) time.sleep(2) # Add delay between workspaces
from databricks.sdk import WorkspaceClient
from databricks.vector_search.client import VectorSearchClient
import logging
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def cleanup_workspace(profile_name=None, workspace_url=None, token=None, dry_run=True):
"""
Clean up empty endpoints in a specific workspace.
Args:
profile_name: Name of configuration profile to use
workspace_url: Direct workspace URL (if not using profile)
token: PAT token (if not using profile)
dry_run: If True, only show what would be deleted
Returns:
Dict with cleanup results
"""
try:
# Initialize client based on authentication method
if profile_name:
# Use Databricks SDK to get credentials from profile
w = WorkspaceClient(profile=profile_name)
workspace_url = w.config.host
client = VectorSearchClient(
workspace_url=workspace_url,
personal_access_token=w.config.token
)
logger.info(f"Connected to workspace using profile '{profile_name}': {workspace_url}")
elif workspace_url and token:
client = VectorSearchClient(
workspace_url=workspace_url,
personal_access_token=token
)
logger.info(f"Connected to workspace: {workspace_url}")
else:
# Use default authentication (notebook context)
client = VectorSearchClient()
logger.info("Connected using default authentication")
# Perform cleanup
deleted = cleanup_empty_endpoints(client, dry_run=dry_run)
return {
'workspace': workspace_url or 'default',
'success': True,
'deleted_count': len(deleted),
'deleted_endpoints': deleted
}
except Exception as e:
logger.error(f"Failed to process workspace: {str(e)}")
return {
'workspace': workspace_url or profile_name or 'default',
'success': False,
'error': str(e)
}
def cleanup_multiple_workspaces(workspace_configs, dry_run=True):
"""
Clean up empty endpoints across multiple workspaces.
Args:
workspace_configs: List of workspace configurations
dry_run: If True, only show what would be deleted
Returns:
Summary of cleanup results
"""
results = []
for config in workspace_configs:
logger.info(f"\n{'='*60}")
result = cleanup_workspace(**config, dry_run=dry_run)
results.append(result)
logger.info(f"{'='*60}\n")
# Print summary
total_deleted = sum(r['deleted_count'] for r in results if r['success'])
successful = sum(1 for r in results if r['success'])
failed = sum(1 for r in results if not r['success'])
logger.info("\n" + "="*60)
logger.info("CLEANUP SUMMARY")
logger.info("="*60)
logger.info(f"Workspaces processed: {len(results)}")
logger.info(f"Successful: {successful}")
logger.info(f"Failed: {failed}")
logger.info(f"Total endpoints deleted: {total_deleted}")
if failed > 0:
logger.warning("\nFailed workspaces:")
for r in results:
if not r['success']:
logger.warning(f" - {r['workspace']}: {r['error']}")
return results
# Example: Clean up using configuration profiles
workspace_configs = [
{'profile_name': 'DEFAULT'},
{'profile_name': 'PRODUCTION'},
{'profile_name': 'DEVELOPMENT'}
]
# Set `dry_run=False` to do actual deletion.
results = cleanup_multiple_workspaces(workspace_configs, dry_run=True)
사용자 지정 필터링
다음과 같이 삭제에서 특정 엔드포인트를 제외하는 사용자 지정 논리를 추가할 수 있습니다.
def should_delete_endpoint(endpoint, indexes):
"""
Custom logic to determine if an endpoint should be deleted.
Args:
endpoint: Endpoint object
indexes: List of indexes in the endpoint
Returns:
Boolean indicating if endpoint should be deleted
"""
# Don't delete if it has indexes
if len(indexes) > 0:
return False
# Don't delete endpoints with specific naming patterns
protected_patterns = ['prod-', 'critical-', 'do-not-delete']
for pattern in protected_patterns:
if pattern in endpoint.name.lower():
logger.warning(f"Skipping protected endpoint: {endpoint.name}")
return False
# Add more custom logic as needed
return True
결과 내보내기
감사를 위해 정리 결과를 파일에 저장하려면 다음을 수행합니다.
import json
from datetime import datetime
def export_results(results, filename=None):
"""Export cleanup results to JSON file."""
if not filename:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f'vector_search_cleanup_{timestamp}.json'
with open(filename, 'w') as f:
json.dump({
'timestamp': datetime.now().isoformat(),
'results': results
}, f, indent=2)
logger.info(f"Results exported to: {filename}")
Troubleshooting
인증 문제
- PAT 토큰이 유효하고 만료되지 않았는지 확인합니다.
- 구성 프로필의 형식이 올바르게 지정되었는지 확인합니다.
- 토큰에 필요한 권한이 있는지 확인합니다.
권한 오류
사용자 또는 서비스 주체에게 CAN_MANAGE Vector Search 엔드포인트에 대한 권한이 있는지 확인합니다.
네트워크 문제
프록시 요구 사항이 있는 환경의 경우 SDK를 적절하게 구성합니다.
import os
os.environ['HTTPS_PROXY'] = 'http://your-proxy:po
다음 단계
- Lakeflow 작업을 사용하여 주기적으로 실행되도록 이 스크립트를 예약합니다.
- 코드로서의 인프라 파이프라인과 통합합니다.
- 정리 요약을 위한 전자 메일 또는 Slack 알림을 추가합니다.
- 작업 영역에서 엔드포인트 사용량을 추적하는 대시보드를 만듭니다.