Search 엔진
Search 엔진 (Search Engines)
Backstage에서 지원하는 검색 엔진들을 설명하는 문서예요.
출처: 문서
본문
Backstage는 기본적으로 3가지 검색 엔진을 지원해요. 인메모리 엔진인 Lunr, Postgres, 그리고 Elasticsearch/OpenSearch예요.
Lunr
Lunr 검색 엔진은 스캐폴딩된 앱에 추가 변경을 하지 않았다면 Backstage 인스턴스에서 기본으로 활성화돼요.
Lunr는 Search 백엔드 플러그인에 내장되어 있으므로 다음과 같이 추가할 수 있어요.
Backstage 루트 디렉터리에서
yarn --cwd packages/backend add @backstage/plugin-search-backend
그런 다음 다음 줄을 추가해요.
packages/backend/src/index.ts
const backend = createBackend();// Other plugins...backend.add(import('@backstage/plugin-search-backend'));backend.start();
:::note Lunr는 로컬에서 Backstage의 다른 부분을 개발할 때 zero-config 검색 엔진으로 적합하지만, 프로덕션에서 Backstage를 실행할 때는 사용이 강하게 권장되지 않아요. Backstage를 배포할 때는 다른 검색 엔진 중 하나를 사용하세요. :::
Postgres
Postgres 기반 검색 엔진은 Postgres가 Backstage의 데이터베이스 엔진으로 구성되어 있기만 하면 돼요. 따라서 Elasticsearch 같은 또 다른 외부 서비스를 유지 관리하고 싶지 않은 설정을 대상으로 해요. 이 검색은 괜찮은 결과를 제공하고 수만 개의 인덱싱된 문서로도 잘 동작해요. Postgres에 대한 연결은 다른 플러그인도 사용하는 데이터베이스 관리자(database manager)를 통해 수립돼요.
중요: 검색 플러그인은 Postgres 12 이상이 필요해요!
먼저 플러그인을 추가해야 해요.
Backstage 루트 디렉터리에서
yarn --cwd packages/backend add @backstage/plugin-search-backend-module-pg
그런 다음 다음 줄을 추가해요.
packages/backend/src/index.ts
const backend = createBackend();// Other plugins...// search pluginbackend.add(import('@backstage/plugin-search-backend'));backend.add(import('@backstage/plugin-search-backend-module-pg'));backend.start();
선택적 구성 (Optional Configuration)
다음은 Postgres를 검색 백엔드로 사용할 때 적용할 수 있는 선택적 구성의 예시예요. 현재는 주로 하이라이트 기능을 위한 것이에요.
search: pg: highlightOptions: useHighlight: true # Used to enable to disable the highlight feature. The default value is true maxWord: 35 # Used to set the longest headlines to output. The default value is 35. minWord: 15 # Used to set the shortest headlines to output. The default value is 15. shortWord: 3 # Words of this length or less will be dropped at the start and end of a headline, unless they are query terms. The default value of three (3) eliminates common English articles. highlightAll: false # If true the whole document will be used as the headline, ignoring the preceding three parameters. The default is false. maxFragments: 0 # Maximum number of text fragments to display. The default value of zero selects a non-fragment-based headline generation method. A value greater than zero selects fragment-based headline generation (see the linked documentation above for more details). fragmentDelimiter: ' ... ' # Delimiter string used to concatenate fragments. Defaults to " ... ".
참고: 하이라이트 검색어 기능은 ts_headline을 사용하는데, 이는 성능에 영향을 줄 수 있는 것으로 알려져 있어요. 문제가 있을 때 이 최소 구성만으로 비활성화할 수 있어요.
search: pg: highlightOptions: useHighlight: false
Postgres의 '결과 하이라이트(Highlighting Results)' 문서에 더 자세한 내용이 있어요.
Elasticsearch와 OpenSearch
Backstage는 Elasticsearch 및 OpenSearch 검색 엔진 연결, 인덱싱, 쿼리를 기본 지원해요. 사용 가능한 구성 옵션으로 AWS나 Elastic.co 호스팅 솔루션, 또는 사용자 지정 셀프 호스팅 솔루션을 이용할 수 있어요.
지원 버전
| Search Engine | Supported Versions | |
|---|---|---|
| Elasticsearch | >= 8.19 | |
| OpenSearch | 1.x, 2.x |
:::note Elasticsearch 7.x는 더 이상 지원되지 않아요. 마이그레이션 방법은 v1.55.0 릴리스 노트를 참고하세요. :::
설정 (Setup)
위의 Postgres와 비슷하게 Elasticsearch를 설정할 수 있어요.
먼저 플러그인을 추가해야 해요.
Backstage 루트 디렉터리에서
yarn --cwd packages/backend add @backstage/plugin-search-backend-module-elasticsearch
그런 다음 다음 줄을 추가해요.
packages/backend/src/index.ts
const backend = createBackend();// Other plugins...// search pluginbackend.add(import('@backstage/plugin-search-backend'));backend.add(import('@backstage/plugin-search-backend-module-elasticsearch'));backend.start();
Elasticsearch는 인스턴스에서 사용할 준비가 되기 전에 추가 구성이 필요해요. 구성 옵션은 구성 스키마 정의 파일에 문서화되어 있어요.
aws 또는 opensearch provider가 구성되면 Elasticsearch 클라이언트 대신 OpenSearch 클라이언트가 사용돼요.
구성 예시
AWS
AWS 호스팅 Elasticsearch를 사용하면 필요한 유일한 구성 옵션은 Elasticsearch 서비스의 URL이에요. 이 구현은 AWS access key id와 secret access key에 대한 환경 변수가 기본 AWS 자격 증명 체인에 따라 정의되어 있다고 가정해요.
search: elasticsearch: provider: aws node: https://my-backstage-search-asdfqwerty.eu-west-1.es.amazonaws.com
Elastic.co
Elastic Cloud 호스팅 Elasticsearch는 Cloud ID를 사용해 연결할 호스팅 Elasticsearch 인스턴스를 결정해요. 추가로 Backstage 문서에 정의된 것처럼 사용자 이름과 비밀번호를 직접 제공하거나 환경 변수를 사용해 제공해야 해요.
search: elasticsearch: provider: elastic cloudId: backstage-elastic:asdfqwertyasdfqwertyasdfqwertyasdfqwerty== auth: username: elastic password: changeme
OpenSearch
OpenSearch는 예를 들어 공식 docker 이미지로 셀프 호스팅할 수 있어요. 구성에는 node와 인증만 필요해요.
search: elasticsearch: provider: opensearch node: http://0.0.0.0:9200 auth: username: opensearch password: changeme
기타 (Others)
클러스터가 지원한다면 표준 Elasticsearch 인증 방법과 노출된 URL을 사용해 다른 Elasticsearch 인스턴스에도 연결할 수 있어요. 필요한 구성 옵션은 node의 URL과 인증 정보예요. 인증은 사용자 이름/비밀번호를 제공하거나 API 키로 처리할 수 있어요. API 키를 만드는 방법에 대한 자세한 내용은 Elastic API 키 문서를 참고하세요.
사용자 이름과 비밀번호로
search: elasticsearch: node: http://localhost:9200 auth: username: elastic password: changeme
API 키로
search: elasticsearch: node: http://localhost:9200 auth: apiKey: ***
Elasticsearch 배치 크기
Elasticsearch 엔진의 기본 배치 크기는 1000으로 설정돼 있어요. 더 낮은 사양의 컴퓨팅 리소스(예: AWS 소형 인스턴스)를 사용한다면 제한된 thread_pool 구성 때문에 오류가 발생할 수 있어요. (429 Too Many Requests /_bulk)
이 경우 이런 오류를 방지하려면 리소스를 인덱싱하기 위해 배치 크기를 줄여야 해요. Elasticsearch 구성에 제공된 batchSize 옵션을 사용해 app-config.yaml에서 배치 크기를 쉽게 줄이거나 늘릴 수 있어요.
배치 크기를 100으로 설정
search: elasticsearch: batchSize: 100
대형 ES 인스턴스를 사용한다면 배치 크기를 늘릴 수도 있어요.
Elasticsearch 배치 키 필드
기본적으로 Elasticsearch 인덱서로 대량(bulk) 업로드할 때, batchKeyField가 명시적으로 설정되지 않으면 각 문서에는 자동 생성된 _id가 할당돼요. 이 구성은 선택 사항이며 대부분의 사용자는 사용자 지정할 필요가 없어요. 하지만 사용 사례가 기존 문서에 대한 빈번한 조회나 업데이트를 포함한다면 batchKeyField를 설정하는 것이 유익할 수 있어요. 각 문서에 대한 일관된 식별자를 정의할 수 있게 해주어 업데이트를 간소화하고 중복 항목을 방지하는 데 도움을 줘요. batchKeyField에 제공된 값이 문서 간에 고유하지 않다면 Elasticsearch가 동일한 _id를 가진 기존 문서를 덮어쓴다는 점에 유의하세요.
batchKeyField 사용 (Custom _id)
search: elasticsearch: batchKeyField: document_id
기본 동작 (자동 생성 _id)
search: elasticsearch: # No batchKeyField specified — Elasticsearch will autogenerate _id
Elasticsearch 인덱스 이름 사용자 지정
기본적으로 Elasticsearch 인덱서는 인덱스 이름을 유형(type), 구분자, 그리고 현재 날짜를 접미사로 하여 생성해요. 모든 인덱스에 사용자 지정 접두사를 구성하려면 앱 구성에 다음 섹션을 추가하세요.
기본 인덱스 이름의 예시는 다음과 같아요.
software-catalog-index__20250219
모든 인덱스에 사용자 지정 문자열(예: custom-prefix)을 접두사로 붙이려면 다음 구성을 사용해요.
search: elasticsearch: indexPrefix: custom-prefix-
이 설정을 적용하면 인덱스 이름은 custom-prefix-software-catalog-index__20250219처럼 보여요.
Elasticsearch 쿼리 구성
기본적으로 Elasticsearch 쿼리의 기본 설정이 사용돼요. 쿼리 결과의 퍼지(fuzziness) 정도를 조정해야 한다면 fuzziness와 prefixLength 두 매개변수로 처리할 수 있어요.
fuzziness는 최대 Levenshtein 거리를 정의할 수 있게 해주며, AUTO가 기본값이자 널리 받아들여지는 표준이에요. prefixLength는 쿼리 용어의 시작 부분에서 정확히 일치해야 하는 최소 문자 수를 제어할 수 있게 해줘요. 기본값은 0이에요. 자세한 정보는 여기에서 확인하세요.
search: elasticsearch: queryOptions: fuzziness: AUTO prefixLength: 3;
사용자 지정 인증 확장 지점
자동 회전이 있는 bearer 토큰 같은 동적 인증 메커니즘이 필요한 엔터프라이즈 환경을 위해 Elasticsearch 모듈은 인증 확장 지점(extension point)을 제공해요. 이는 다음과 같은 경우에 유용해요.
-
서비스 인증을 위해 OAuth2/OIDC ID 제공자를 사용하는 경우
-
토큰을 자동으로 새로고침해야 하는 경우(예: 매시간 만료되는 토큰)
-
내부 ID 서비스와 통합하는 경우
-
토큰 기반 인증으로 보호된 Elasticsearch/OpenSearch 클러스터를 실행하는 경우
사용자 지정 인증을 사용하려면 인증 제공자를 제공하는 백엔드 모듈을 만들어요.
packages/backend/src/modules/elasticsearchAuth.ts
import { createBackendModule } from '@backstage/backend-plugin-api';import { elasticsearchAuthExtensionPoint } from '@backstage/plugin-search-backend-module-elasticsearch';export default createBackendModule({ pluginId: 'search', moduleId: 'elasticsearch-custom-auth', register(env) { env.registerInit({ deps: { elasticsearchAuth: elasticsearchAuthExtensionPoint, }, async init({ elasticsearchAuth }) { elasticsearchAuth.setAuthProvider({ async getAuthHeaders() { // Fetch token from your identity service const token = await myTokenService.getToken(); return { Authorization: *** ${token}` }; }, }); }, }); },});
그런 다음 이 모듈을 백엔드에 등록해요.
packages/backend/src/index.ts
const backend = createBackend();// Other plugins...backend.add(import('@backstage/plugin-search-backend'));backend.add(import('@backstage/plugin-search-backend-module-elasticsearch'));backend.add(import('./modules/elasticsearchAuth'));backend.start();
getAuthHeaders 메서드는 각 요청 전에 호출되어 시기적절한(JIT) 토큰 검색과 자동 회전을 가능하게 해요. 인증 제공자가 구성되면 app-config.yaml의 정적 인증보다 우선해요.
:::note
사용자 지정 인증은 elastic, opensearch, 그리고 기본 제공자에서 지원돼요. aws 제공자는 AWS SigV4 요청 서명을 사용하며 사용자 지정 인증 제공자를 지원하지 않아요.
:::