Solr backfill guide
출처: 문서
본문
Solr 백필 가이드
Apache Solr에서 OpenSearch로 문서를 마이그레이션하려면 스냅샷 기반 백필 워크플로를 사용해요. Solr 마이그레이션의 전체 아키텍처는 Solr 마이그레이션 개요를 참고하세요.
SolrCloud와 standalone Solr 비교
Migration Assistant는 SolrCloud와 standalone Solr 배포 모드를 모두 지원해요. Solr Collections API를 먼저 확인하고, 실패하면 Solr Core Admin API로 폴백하는 방식으로 모드를 자동 감지해요. 두 모드의 사전 요구 사항은 다음 표와 같이 달라요.
| Feature | SolrCloud | Standalone Solr |
|---|---|---|
| 백업 단위 | Collection | Core |
| Solr 백업 API 엔드포인트 | admin/collections?action=BACKUP |
/solr/<core>/replication?command=backup |
| 폴링 API 엔드포인트 | admin/collections?action=REQUESTSTATUS |
/solr/<core>/replication?command=details |
solr.xml 위치 |
ZooKeeper | 파일시스템 (일반적으로 /var/solr/data/solr.xml) |
| 재시작 범위 | 클러스터의 모든 노드 재시작 | 단일 Solr 노드 재시작 |
| Migration Assistant 워크플로 인자 | solrCollections: [name1, name2] |
동일한 필드, 값은 core 이름 |
1~4단계는 두 모드에서 동일해요. 5단계(solr.xml을 게시하는 방식과 노드를 재시작하는 방식)만 달라요.
역할 분담
스냅샷은 여러분의 Solr 클러스터가 생성하고(Solr의 Amazon S3 백업 플러그인이 백업 파일을 Amazon S3에 기록해요), Migration Assistant가 소비해요(이 파일들을 읽어서 OpenSearch에 벌크 인덱싱해요). Migration Assistant는 여러분의 Solr 클러스터에 접근해 플러그인을 설치하거나 설정을 수정할 수 없어요. 이 단계들은 직접 완료해야 해요. 워크플로의 create snapshot 단계를 실행하기 전에 여러분 쪽의 모든 사전 요구 사항이 갖춰져 있어야 해요.
| Responsibility | Owner | Timing |
|---|---|---|
| 모든 Solr 노드에 Solr S3 백업 플러그인 설치 | 여러분 | Migration Assistant 실행 전 |
<backup> 리포지토리를 solr.xml에 설정하고 게시 (SolrCloud는 ZooKeeper, standalone은 파일시스템) |
여러분 | Migration Assistant 실행 전 |
새 solr.xml을 로드하도록 Solr 재시작 (SolrCloud는 모든 노드, standalone은 단일 노드) |
여러분 | Migration Assistant 실행 전 |
S3 버킷 생성 및 Solr에 PutObject / GetObject / ListBucket 권한 부여 |
여러분 | Migration Assistant 실행 전 |
| Migration Assistant 파드에 동일한 버킷에 대한 읽기 권한 부여 | 여러분 | 배포 중 |
모든 collection(SolrCloud) 또는 core(standalone)에 BACKUP을 트리거하고 완료될 때까지 폴링. SolrCloud의 경우 Solr의 S3BackupRepository가 확인하는 S3 디렉터리 마커도 생성 |
Migration Assistant (create snapshot) |
워크플로 단계 |
| S3에서 백업 읽기, 스키마 변환, OpenSearch에 벌크 인덱싱 | Migration Assistant (메타데이터 + Reindex-from-Snapshot) | 워크플로 단계 |
Solr 사전 요구 사항
클러스터의 모든 Solr 노드에서 다음 다섯 단계를 완료하세요.
1단계: 모든 Solr 노드에 S3 백업 플러그인 설치
Solr 8.11 Docker 이미지(그리고 대부분의 기본 설치)에서는 S3 백업 플러그인 파일이 두 개의 디렉터리에 나뉘어 있어요.
| Path | Contents | Missing component |
|---|---|---|
/opt/solr/contrib/s3-repository/lib/ |
AWS SDK jars (의존성만 포함) | S3BackupRepository 클래스 |
/opt/solr/dist/solr-s3-repository-<VERSION>.jar |
S3BackupRepository 클래스 |
필요한 AWS SDK jars |
sharedLib이 이 디렉터리 중 하나만 참조하면 Solr는 오류 없이 시작되지만 모든 BACKUP 요청이 ClassNotFoundException: org.apache.solr.s3.S3BackupRepository(또는 AWS SDK NoClassDefFoundError)로 실패해요.
필요한 모든 파일이 같은 위치에 있도록 /opt/solr/dist/ 디렉터리의 solr-s3-repository jar를 /opt/solr/contrib/s3-repository/lib/ 디렉터리로 복사해요:
cp /opt/solr/dist/solr-s3-repository-*.jar /opt/solr/contrib/s3-repository/lib/
{% include copy.html %}
이 명령은 Solr를 시작하기 전에 모든 Solr 노드에서 실행하세요. Docker에서는 컨테이너 시작 스크립트에 이 명령을 포함하세요(이 디렉터리는 root 권한이 필요해요).
2단계: solr.xml 설정
어떤 Solr 버전에서도 런타임에 백업 리포지토리를 등록하는 API는 없어요. 리포지토리는 solr.xml에 선언하고 노드 시작 시 로드해야 해요.
두 가지 흔한 설정 오류는 눈에 띄는 경고 없이 발생해요:
- Solr 8에서
sharedLib은 단일 디렉터리여야 해요: 쉼표로 구분된 목록도 받아들여지지만 하나의 잘못된 경로로 취급되어 플러그인이 로드되지 않아요. solr.xml의 변수 치환${VAR:default}은 OpenSearch 환경 변수가 아닌 Java 시스템 프로퍼티를 읽어요: Docker 환경 변수(-e KEY=value)가 아니라SOLR_OPTS=-Dkey=value로 값을 전달하세요.
다음 예제는 최소한의 solr.xml 설정을 보여줘요:
<?xml version="1.0" encoding="UTF-8" ?>
<solr>
<str name="sharedLib">/opt/solr/contrib/s3-repository/lib</str>
<solrcloud>
<str name="host">${host:}</str>
<int name="hostPort">${jetty.port:8983}</int>
<str name="hostContext">${hostContext:solr}</str>
<bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
<int name="zkClientTimeout">${zkClientTimeout:30000}</int>
<int name="distribUpdateSoTimeout">${distribUpdateSoTimeout:600000}</int>
<int name="distribUpdateConnTimeout">${distribUpdateConnTimeout:60000}</int>
</solrcloud>
<backup>
<repository name="s3" class="org.apache.solr.s3.S3BackupRepository" default="true">
<str name="s3.bucket.name">${S3_BUCKET_NAME:}</str>
<str name="s3.region">${S3_REGION:us-east-1}</str>
<str name="s3.endpoint">${S3_ENDPOINT:}</str>
</repository>
</backup>
</solr>
{% include copy.html %}
다음 표는 설정 필드를 설명해요.
| Field | Description |
|---|---|
<str name="sharedLib"> |
Solr가 시작 시 로드하는 jar 파일이 있는 디렉터리예요. 1단계에서 AWS SDK jar 파일과 플러그인 jar를 모두 복사한 단일 디렉터리여야 해요. |
<repository name="s3"> |
논리적 리포지토리 이름이에요. 이 값은 워크플로 설정의 repoName 및 Solr의 BACKUP URL에 있는 repository= 파라미터와 대응돼요. |
s3.bucket.name |
백업을 저장하는 Amazon S3 버킷이에요. Solr는 버킷을 생성하지 않으므로 버킷이 이미 존재해야 해요. |
s3.region |
버킷의 AWS 리전이에요. |
s3.endpoint |
S3 엔드포인트예요. 프로덕션 Amazon S3에서는 비워 두세요. 커스텀 엔드포인트(예: LocalStack)를 대상으로 할 때만 이 필드를 설정해요. |
3단계: Solr S3 연결 설정
SOLR_OPTS 시스템 프로퍼티를 통해 S3 연결 값을 Solr에 전달해요:
export SOLR_OPTS="-DS3_BUCKET_NAME=my-solr-backups \
-DS3_REGION=us-west-2 \
-DSOLR_SECURITY_MANAGER_ENABLED=false"
{% include copy.html %}
SOLR_SECURITY_MANAGER_ENABLED=false는 Java 보안 관리자가 AWS SDK의 아웃바운드 연결을 차단하는 샌드박스 또는 LocalStack 환경에서만 필요해요. 표준 AWS 배포에서는 필요하지 않아요.
4단계: Solr에 S3 쓰기 권한 부여
Solr 프로세스는 기본 AWS 자격 증명 공급자 체인을 사용해요. 여기에는 환경 변수, Amazon EC2 인스턴스 프로파일, ECS 태스크 역할, ~/.aws/credentials, 또는 공유 프로파일이 포함돼요. 이 자격 증명 소스 중 하나가 백업 버킷으로 범위가 한정된 다음 권한을 가진 IAM 자격 증명으로 확인되도록 하세요:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::my-solr-backups",
"arn:aws:s3:::my-solr-backups/*"
]
}]
}
{% include copy.html %}
Solr는 백업을 증분 방식으로 기록하고, 어떤 Lucene 세그먼트를 다시 업로드할지 판단하려고 이전 백업 메타데이터를 읽어요. 따라서 PutObject, GetObject, ListBucket이 모두 필요해요. DeleteObject는 DELETE_BACKUP 또는 maxNumBackup 정리 기능을 사용할 때만 필요해요.
5단계: solr.xml 게시 및 Solr 재시작
solr.xml을 게시하는 방법은 SolrCloud와 standalone Solr가 달라요. 하지만 2단계의 파일 내용은 두 모드에서 동일해요.
SolrCloud
SolrCloud 모드에서는 solr.xml이 ZooKeeper에 저장돼요. 수정한 파일을 업로드한 다음 새 <backup> 섹션을 로드하도록 각 노드를 재시작해요:
/opt/solr/bin/solr zk cp <path-to-new-solr.xml> zk:/solr.xml -z <ZK_HOST>:2181
/opt/solr/bin/solr restart -force # repeat on every node
{% include copy.html %}
Standalone Solr
수정한 solr.xml을 Solr 홈 디렉터리로 복사하고 Solr를 재시작해요. 기본 Docker 이미지에서 올바른 경로는 /var/solr/data/solr.xml이에요. -Dsolr.solr.home=/var/solr/data로 시작하면 Solr가 이 경로를 무시하기 때문에 /opt/solr/server/solr/solr.xml은 사용하지 마세요. 파일을 복사하고 Solr를 재시작하려면 다음 명령을 실행해요:
cp <path-to-new-solr.xml> /var/solr/data/solr.xml
/opt/solr/bin/solr restart -force
{% include copy.html %}
Migration Assistant 실행 전 리포지토리 검증
Migration Assistant를 실행하기 전에 Solr 클러스터가 S3에 백업을 성공적으로 기록할 수 있는지 확인해요. 테스트 백업이 실패하면 진행하기 전에 Solr 설정에서 문제를 해결하세요.
SolrCloud
SolrCloud의 경우 다음 명령을 실행해요:
# Trigger an async backup of one collection to a throwaway location.
curl "http://<solr-host>:8983/solr/admin/collections?action=BACKUP\
&name=preflight&collection=<SOME_COLLECTION>\
&repository=s3&location=/preflight-check&async=preflight-1&wt=json"
# Poll until state=completed (should take a few seconds on a small collection).
curl "http://<solr-host>:8983/solr/admin/collections?action=REQUESTSTATUS\
&requestid=preflight-1&wt=json"
{% include copy.html %}
REQUESTSTATUS가 state=failed를 반환하면 전체 JSON 응답을 살펴보세요. status.msg 필드에는 "found [preflight-1] in failed tasks" 같은 일반적인 메시지만 들어 있어요. 자세한 오류는 최상위 exception.msg 또는 response.* 필드에 나타나요. 흔한 원인은 다음과 같아요:
- 1단계에서 플러그인 jar를 복사하지 않았어요.
- S3 버킷이 존재하지 않아요.
- 4단계의 IAM 자격 증명이 버킷에 대한 접근 권한이 없어요.
테스트 백업이 성공하면 다음 명령을 실행해서 삭제해요:
curl "http://<solr-host>:8983/solr/admin/collections?action=DELETE_BACKUP&name=preflight&location=/preflight-check&purge=true&repository=s3"
{% include copy.html %}
Standalone Solr
standalone Solr의 경우 다음 명령을 실행해요:
# Trigger a backup of one core.
curl "http://<solr-host>:8983/solr/<CORE_NAME>/replication\
?command=backup&repository=s3&location=/preflight-check&name=preflight&wt=json"
# Poll until status=success (the same endpoint returns the latest backup status).
curl "http://<solr-host>:8983/solr/<CORE_NAME>/replication?command=details&wt=json"
{% include copy.html %}
details.backup.status가 "success"를 반환하는지 확인해요. 값이 "failed" 또는 "exception"이면 details.backup.exception 필드에 오류 세부 정보가 있어요. 근본 원인은 SolrCloud의 경우와 동일해요.
Migration Assistant 사전 요구 사항
다음 Migration Assistant 사전 요구 사항이 충족되는지 확인해요:
- Migration Assistant가 Kubernetes 또는 Amazon EKS에 배포되어 있어야 해요. 자세한 내용은 Kubernetes에 배포 또는 Amazon EKS에 배포를 참고하세요.
- Migration Console 파드와 RFS 워커 파드가 백업 버킷에 대한 읽기 권한(
s3:GetObject및s3:ListBucket)을 가지고 있어야 해요. Solr와 Migration Assistant가 서로 다른 AWS 계정 또는 VPC에서 실행된다면, 진행하기 전에 라우팅(VPC 엔드포인트, 버킷 정책)을 확인해요. - Solr의
solr.xml에 설정된 버킷(s3.bucket.name)과 워크플로 설정에서 참조하는 버킷(s3RepoPathUri)이 동일한 버킷이어야 해요.
워크플로우 구성
Migration Assistant는 설치 시점에 생성된 스키마를 기준으로 워크플로우를 검증해요. 설정을 직접 작성하는 대신 항상 버전에 맞는 샘플(workflow configure sample --load)에서 시작하세요. 스키마 이름과 구조는 릴리스마다 달라져요.
주요 구성 필드
다음 표는 주요 구성 필드를 설명해요.
| 필드 | 설명 |
|---|---|
sourceClusters.<name>.version |
Solr 버전 문자열이에요. SOLR <major>.<minor>.<patch> 형식과 일치해야 해요. 예를 들어 SOLR 6.6.6, SOLR 7.7.3, SOLR 8.11.4, SOLR 9.7.0이 있어요. |
sourceClusters.<name>.snapshotInfo.repos.<repoName>.s3RepoPathUri |
s3://bucket 또는 s3://bucket/subpath 형식의 전체 Amazon S3 URI예요. 버킷은 solr.xml의 s3.bucket.name과 일치해야 해요. 서브패스는 Solr의 BACKUP API에 location 파라미터로 전달돼요. |
sourceClusters.<name>.snapshotInfo.snapshots.<snapshotName>.repoName |
리포지토리 이름이에요. solr.xml의 name 속성과 일치해야 해요. |
targetClusters.<name>.authConfig.sigv4.service |
AWS 서비스 식별자예요. Amazon OpenSearch Service에는 es를, Amazon OpenSearch Serverless NextGen에는 aoss를 사용하세요. |
targetClusters.<name>.authConfig.basic.secretName |
기본 인증 자격 증명을 담고 있는 Kubernetes 시크릿 이름이에요. 자체 관리형 클러스터를 대상으로 할 때는 sigv4 대신 이 필드를 사용하세요. |
perSnapshotConfig.<snapshotName>[].metadataMigrationConfig.skipEvaluateApproval / skipMigrateApproval |
모든 승인을 전역적으로 비활성화하지 않으면서 단계별 승인 게이트를 우회해요. |
perSnapshotConfig.<snapshotName>[].documentBackfillConfig.podReplicas |
RFS 파드 수예요. 각 파드는 서로 다른 샤드를 병렬로 처리해요. |
perSnapshotConfig.<snapshotName>[].documentBackfillConfig.maxShardSizeBytes |
지원되는 최대 샤드 크기예요. 기본값은 80 GiB예요. 이보다 큰 샤드는 백필 전에 줄여야(force-merge 또는 split) 해요. |
S3 리포지토리 경로 URI
CreateSnapshot(쓰기)과 RFS(읽기) 모두 동일한 s3RepoPathUri를 사용하기 때문에 같은 S3 위치를 참조해요. Migration Assistant는 BACKUP을 호출하기 전에 Solr가 기대하는 S3 디렉터리 마커를 <subpath>/와 <subpath>/<snapshotName>/ 양쪽에 자동으로 생성해 주기 때문에 직접 만들 필요가 없어요. 다음 다이어그램을 참고하세요.
s3RepoPathUri: "s3://my-bucket/solr-migration-v3"
│ │
│ └── Subpath — passed as "location" to Solr BACKUP
└── Bucket — must match s3.bucket.name in solr.xml
스냅샷 생성
create snapshot 워크플로우 단계를 실행하면 Migration Assistant가 다음 작업을 수행해요:
- SolrCloud Collections API를 프로빙해서 배포 모드를 감지해요. 프로브가 실패하면 Migration Assistant는 standalone Core Admin API로 폴백해요.
- 백업 단위를 탐색해요 — SolrCloud에서는 컬렉션(
admin/collections?action=LIST사용), standalone에서는 코어(admin/cores?action=STATUS사용)가 대상이에요.solrCollections워크플로우 필드를 지정하면 이를 재정의할 수 있어요. <subpath>/와<subpath>/<snapshotName>/에 Amazon S3 디렉터리 마커를 생성해요(content-type: application/x-directory인 0바이트 객체). Solr의S3BackupRepository는 백업을 수락하기 전에 이 경로들이 존재하는지 확인해요. 이 단계는 SolrCloud에만 적용돼요. Migration Assistant는 standalone 모드에서는 이 마커를 생성하지 않아요. standalone 모드에서specified location실패가 발생하면aws s3api put-object --bucket <bucket> --key <subpath>/ --content-type application/x-directory를 실행해 서브패스를 직접 만든 후 워크플로우를 다시 제출하세요. standalone Solr와 S3 관련 추가 문제는 문제 해결을 참고하세요.- 컬렉션 또는 코어별로 한 번씩 Solr의 백업 API를 호출해요:
- SolrCloud:
admin/collections?action=BACKUP&name=<collection>&location=<subpath>/<snapshotName>&repository=s3&async=...(비동기). - Standalone:
/solr/<core>/replication?command=backup&name=<snapshotName>&location=<subpath>&repository=s3(동기 디스패치, 비동기 실행).
- SolrCloud:
- 모든 단위가
completed,success또는 실패를 보고할 때까지 비동기 ID별로REQUESTSTATUS(SolrCloud)를, 코어별로replication?command=details(standalone)를 사용해 완료 여부를 폴링해요.
3~5단계를 수행하려면 Solr 사전 요구 사항이 충족되어야 해요.
백필 실행
YAML을 워크플로우 세션에 로드한 다음 워크플로우를 제출하세요:
# Option 1: edit interactively (loads sample, opens $EDITOR)
workflow configure sample --load
workflow configure edit
# Option 2: pipe a file in non-interactively
cat solr-backfill.wf.yaml | workflow configure edit --stdin
# Submit and watch
workflow submit
workflow manage # interactive TUI — also shows approval gates
{% include copy.html %}
클러스터에 기존 워크플로우가 있으면 workflow submit이 자동으로 이를 중지하고 교체해요. 다시 제출하지 않고 CRD를 제거하려면 workflow reset(대화형) 또는 workflow reset --all(전체 삭제)을 실행하세요.
문서 수 확인
백필이 완료되면 다음 명령을 실행해 대상의 문서 수를 확인하세요:
console clusters cat-indices --refresh
{% include copy.html %}
문제 해결
다음은 흔히 발생하는 문제와 해결 방법이에요.
스냅샷 생성 실패
다음 표는 흔한 스냅샷 생성 오류와 그 원인, 해결 방법을 정리한 거예요.
| 오류 | 원인 | 해결 방법 |
|---|---|---|
Solr 로그의 ClassNotFoundException: org.apache.solr.s3.S3BackupRepository |
플러그인 jar가 /opt/solr/dist/에서 sharedLib 디렉터리로 복사되지 않았어요. |
모든 노드에서 1단계를 다시 수행하고 Solr를 재시작하세요. |
Repository default-s3 not found |
실행 중인 solr.xml에 <backup> 블록이 없어요(잘못된 파일, 잘못된 마운트 경로, 또는 업로드 후 노드를 재시작하지 않은 경우). |
5단계를 다시 수행하세요. |
specified location s3:///...(슬래시 3개) |
Solr가 HeadObject로 디렉터리 마커를 확인하지 못해요. |
4단계에서 권한을 확인하세요. |
Solr 로그의 S3 AccessDenied |
Solr 노드의 IAM 자격 증명에 버킷 쓰기 권한이 없어요. | 4단계에서 IAM 정책을 수정하고, Solr 노드에서 aws s3 ls를 실행해 접근을 확인하세요. |
(SolrCloud만 해당) status.msg="found [...] in failed tasks" |
비동기 작업이 실패했어요. 상세 오류는 다른 필드에 있어요. | 전체 REQUESTSTATUS JSON 응답을 검토하고 최상위 exception.msg 또는 response.* 필드를 확인하세요. |
(Standalone만 해당) details.backup.status = failed 또는 exception |
코어 수준 백업이 실패했어요. | 상세 오류는 replication?command=details 응답의 details.backup.exception 필드를 확인하세요. |
메타데이터 마이그레이션이 0건을 찾는 경우
메타데이터 마이그레이션 결과가 비어 있는 흔한 원인은 다음과 같아요:
s3RepoPathUri가 잘못됐어요. 버킷은 일치하지만 서브패스가 Solr가 백업을 쓴 위치와 일치하지 않아요.- 스냅샷이 완료되지 않았어요. 모든 컬렉션(SolrCloud)에 대해
REQUESTSTATUS를, 모든 코어(standalone)에 대해replication?command=details를 확인하세요. snapshotMigrationConfigs에서 참조하는 스냅샷 이름이 잘못됐어요.
RFS가 예상보다 적은 문서를 마이그레이션하는 경우
대상의 문서 수가 예상보다 적다면 다음 단계를 수행하세요:
- 다음 명령을 실행해 백업에 모든 샤드가 포함되어 있는지 확인하세요:
aws s3 ls s3://<bucket>/<subpath>/<snapshot>/<collection-or-core>/shard_backup_metadata/ - 각 샤드에
md_shardN_0.json파일이 있는지 확인하세요(연속 백업인 경우md_shardN_<N>.json). Migration Assistant는 가장 큰 N 값을 사용해요. workflow manage에서 작업 항목 상태를 확인하세요.