중화사전망 - 중국어 사전 - 분산 검색 엔진 유연한 검색의 아키텍처 원리

분산 검색 엔진 유연한 검색의 아키텍처 원리

분산 검색 엔진: 대량의 인덱스 데이터를 여러 블록으로 나누고 각 시스템의 일부를 배치한 다음 여러 시스템을 사용하여 분산된 데이터를 검색합니다. 모든 작업이 여러 시스템에 분산되어 완전한 분산 아키텍처를 형성합니다.

거의 실시간, 두 가지 의미 가 있습니다:

클러스터에는 여러 노드가 포함되어 있으며, 각 노드가 속한 클러스터는 구성에 따라 결정됩니다.

노드는 클러스터의 노드이며 노드에도 이름이 있으며 기본적으로 무작위로 할당됩니다. 기본 노드가 elasticsearch 라는 클러스터에 조인됩니다. 노드 더미를 직접 시작하면 자동으로 elasticsearch 클러스터를 형성합니다. 물론 하나의 노드도 elasticsearch 클러스터를 구성할 수 있습니다.

문서는 전문가 시스템에서 가장 작은 데이터 단위입니다. 문서는 1 고객 데이터, 1 상품 분류 데이터, 1 주문 데이터, 일반적으로 JSON 데이터 구조로 표현될 수 있습니다. 색인 아래의 각 유형에는 여러 문서를 저장할 수 있습니다.

1 문서에 여러 필드가 있으며 각 필드는 1 데이터 필드입니다.

Es 클러스터에 여러 노드가 있을 경우 1 개 노드가 자동으로 마스터 노드로 선택됩니다. 이 마스터 노드는 실제로 인덱스 메타데이터 유지 관리, 마스터 조각 및 복제본 조각의 id 전환 등의 관리 작업을 수행합니다. 마스터 노드가 종료되면 1 개 노드가 마스터 노드로 다시 선택됩니다. 마스터가 아닌 노드에 장애가 발생하면 마스터는 장애가 발생한 노드의 마스터 조각 id 를 다른 시스템의 복제본 조각으로 전송합니다. 그런 다음 다운타임 시스템을 복구하고 재부팅하면 마스터 노드는 누락된 복제본 조각의 할당을 제어하고 이후에 수정된 데이터를 동기화하는 등 클러스터를 정상으로 되돌립니다. 더 간단한 것은 1 입니다. 즉, 마스터가 아닌 노드가 다운되면 해당 노드의 마스터 슬라이스가 없어진다는 뜻입니다. 네, 마스터는 마스터 조각에 해당하는 복사본 조각 (다른 시스템에서) 을 마스터 조각으로 전환합니다. 충돌 복구가 발생하면 복구된 노드는 더 이상 마스터 슬라이스가 아니라 복제본 슬라이스입니다.

색인은 여러 조각으로 나눌 수 있으며 각 슬라이스는 데이터의 일부를 저장합니다. 여러 조각을 분할하는 것이 유익하다. 첫째, 수평 확장을 지원합니다. 예를 들어, 데이터의 양은 3T 이고, 세 개의 조각이 있으며, 각 조각마다 1T 의 데이터가 있습니다. 만약 지금 데이터의 양이 4T 로 증가한다면, 어떻게 확장하느냐는 매우 간단하다. 4 개의 조각으로 1 인덱스를 재구축하고 데이터를 가져옵니다. 두 번째는 성능을 높이는 것이다. 데이터가 여러 shard 에 분산되어 있습니다. 즉, 여러 서버에 분산되어 모든 작업이 병렬로 실행되어 여러 시스템에 분산되므로 처리량과 성능이 향상됩니다. 그런 다음이 조각의 데이터에는 실제로 여러 개의 백업이 있습니다. 즉, 각 슬라이스에는 데이터 쓰기를 담당하는 1 개의 마스터 슬라이스가 있지만 여러 개의 복제본 슬라이스도 있습니다. 마스터 조각이 데이터에 기록되면 데이터는 다른 여러 복제본 조각에 동기화됩니다.

이 복제 시나리오를 통해 조각당 여러 개의 데이터가 백업됩니다. 만약 기계 한 대가 고장났다면 상관없다. 다른 시스템에는 다른 데이터 복제본이 있으므로 가용성이 높습니다.

요약: 분포는 두 점, 1 입니다. 슬라이스 슬라이스를 통한 수평 확장; 고가용성은 복제 메커니즘을 통해 이루어집니다.

기본 개념

데이터 쓰기 프로세스: 클라이언트는 hash 를 통해 조정 노드라고 하는 노드를 선택하여 요청을 보냅니다. 노드 라우팅 docmount 를 조정하고 요청을 해당 마스터 조각에 전달하고, 마스터 조각화는 요청을 처리하고, 데이터를 모든 복제본 조각에 동기화합니다. 이 시점에서 조정 노드는 기본 슬라이스와 모든 복제본 슬라이스가 처리된 것을 발견한 후 클라이언트에 피드백을 제공합니다.

클라이언트가 임의의 노드에 get 요청을 보내면 이 노드를 조정 노드라고 합니다. 노드 라우팅 문서를 조정하고 요청을 해당 노드에 전달합니다. 이때 랜덤 폴링 알고리즘을 사용하여 마스터 조각과 복제본 조각 중 하나를 무작위로 선택하여 읽기 요청의 로드 밸런싱을 수행하고, 요청을 받는 노드는 문서를 조정 노드로 반환하고, 조정 노드는 문서를 클라이언트로 반환합니다.

Es 의 가장 강력한 것은 전체 텍스트 검색을 하는 것입니다. 즉, 예를 들어 세 개의 데이터가 있습니다.

1.자바 정말 재미있어요.

2. 자바는 배우기가 어렵습니다.

3.j2ee 는 아주 좋아요

Java 키워드를 기준으로 검색하면 Java 가 포함된 문서를 검색할 수 있습니다.

데이터 업데이트/삭제 프로세스는 쓰기 및 병합 작업, 새로 고침 프로세스 순으로 진행됩니다.

1, 쓰기 프로세스는 위와 일치합니다.

2. 새로 고침 프로세스가 약간 다릅니다.

역방향 색인이란 먼저 데이터 내용을 단어로 나누고, 각 문장을 하나씩 키워드로 나누고, 각 키워드가 나타나는 id 태그 데이터를 기록하는 것입니다.

그런 다음이 id 를 기반으로 다른 곳에서 해당 데이터를 찾을 수 있습니다. 역방향 인덱스의 데이터 형식 및 조회 방법입니다. 역방향 인덱스를 통해 데이터를 찾는 이러한 방법을 전체 텍스트 검색이라고도 합니다.

역방향 인덱스는 우리의 일반적인 역방향 인덱스이며, 주로 두 부분으로 구성됩니다.

순서가 지정된 데이터 사전 (단어 $ Term 및 해당 발생 빈도 포함).

단어 $ Term (이 단어가 있는 파일) 에 해당하는 레코드

검색 시 먼저 검색 내용을 분해한 다음 사전에서 해당 $ Term 을 찾아 검색과 관련된 파일 내용을 찾습니다.

기본적으로 저장 필드는 간단한 키 값 쌍입니다. 기본적으로 Stored Fields 는 false 이며 ElasticSearch 는 전체 파일의 JSON 소스 코드를 저장합니다.

어떤 경우에 store 속성을 명시적으로 지정해야 합니까? 대부분의 경우 필요하지 않습니다. _source 에서 값을 가져오면 빠르고 효율적입니다. 문서가 길고 _source 를 저장하거나 _source 에서 필드를 가져오는 데 많은 비용이 드는 경우 일부 필드의 store 속성을 yes 로 명시적으로 설정할 수 있습니다. 단점은 위에서 설명한 바와 같습니다. 10 필드를 저장하고 이 10 필드의 값을 얻으려면 여러 io 가 필요합니다. 저장된 필드에서 가져옵니다. 하나만 있으면 되고 _source 는 압축됩니다.

이때 일부 필드인 store 를 true 로 지정할 수 있습니다. 즉, 이 필드의 데이터는 별도로 저장됩니다 (실제로 두 개의 복제본이 있고 소스 필드와 스토리지 필드 모두에 복제본이 있음). 이 시점에서 요청이 field 1 (store: Yes) 를 반환하면 es 는 field 1 이 저장되었음을 인식하므로 _source 에서 로드되지 않고 field 에서 로드됩니다

Doc_values 는 기본적으로 필드 합산, 정렬 및 스크립트 액세스 등의 작업에 적합한 직렬화된 열 저장소입니다. 또한 이 저장 방식은 압축, 특히 숫자 유형에 매우 편리합니다. 이렇게 하면 디스크 공간이 줄어들고 액세스 속도가 향상됩니다. ElasticSearch 는 인덱스의 모든 문서 값을 메모리로 읽어 조작할 수 있습니다.

Doc_values 가 디스크에 존재합니다.

Es 에서 텍스트 유형 필드는 기본적으로 역방향 인덱스만 설정하고, 다른 몇 가지 유형은 역방향 인덱스를 만들 때 정방향 인덱스를 만듭니다. 물론 es 는 사용자 정의를 지원합니다. 여기서 이 직교 색인은 실제로 Doc 값입니다.

위의 동적 지수입니다.

Es 에 기록된 데이터는 실제로 디스크 파일에 기록됩니다. 쿼리 시 운영 체제는 디스크 파일의 데이터를 파일 시스템 캐시로 자동 캐시합니다.

Es 의 검색 엔진은 기본 파일 시스템 캐시에 매우 의존합니다. 파일 시스템에 더 많은 메모리를 캐시하고 모든 idx 세그먼트 파일 인덱스 데이터 파일을 메모리에 넣으려고 하면 검색 시 기본적으로 메모리를 사용하며 성능이 향상됩니다. 성능 격차는 얼마나 될까요? 우리의 이전의 많은 테스트와 스트레스 테스트에서, 만약 접시를 잡는다면, 분명히 초일 것이다. 검색 성능은 절대적으로 초, 1 초, 5 초, 10 초이다. 그러나 파일 시스템 캐시와 순수 메모리의 경우 성능은 일반적으로 디스크보다 한 단계 높은 수준이며, 기본적으로 밀리초부터 수백 밀리초까지 다양합니다.

그렇다면 어떻게 파일 시스템 캐시 공간을 절약할 수 있을까요?

ES 에 데이터를 쓸 때는 데이터 최소화를 고려해야 합니다. 한 행에 30 개 이상의 필드가 있는 경우 모든 데이터를 ES 에 쓸 필요가 없습니다. 필요한 키 열만 검색하면 됩니다. 캐시할 수 있는 데이터가 많을수록. 따라서 각 시스템에서 쓴 데이터를 파일 시스템 캐시 공간보다 작거나 같거나 약간 크게 제어하는 것이 좋습니다. 대량의 데이터를 검색하려면 ES+H 베이스 스키마를 사용해 보십시오. Hbase 를 사용하여 대량의 데이터를 저장하고 ES 가 문서 id 를 검색한 후 문서 id 를 기준으로 Hbase 에 가서 지정된 행 데이터를 질의합니다.

각 시스템이 캐시 OS 보다 너무 큰 데이터를 쓰기 때문에 캐시에 너무 많은 데이터를 넣을 수 없는 경우 일부 핫 데이터를 캐시에 플러시할 수 있습니다.

비교적 덥다고 생각되고 자주 액세스되는 데이터의 경우 전용 캐시 예열 시스템을 만드는 것이 좋습니다. 즉, 일정한 간격으로 열 데이터에 미리 액세스하여 파일 시스템 캐시에 데이터를 넣는 것이 좋습니다. 그래서 다음번에 누군가가 방문하면 표현이 훨씬 좋아질 것이다.

핫 데이터와 콜드 데이터를 분리하여 다른 인덱스에 쓴 다음 핫 인덱스 데이터를 캐시에 플러시해야 합니다.

ES 에서는 복잡한 관계형 테이블 작업을 사용하지 않는 것이 좋습니다. 이러한 장면이 필요한 경우 색인을 만들 때 데이터를 연결할 수 있습니다. 예를 들어 MySQL 에서는 관련 ID 를 기준으로 두 테이블의 관련 데이터를 쿼리해야 합니다. 즉, join b 에서 a.name, b.age 중 a.id = b.id 를 선택하고 es 를 쓸 때 관련 데이터를 한 문서에 직접 넣으면 됩니다.

Es 의 페이지 비교 구덩이입니다. 왜요 예를 들어, 페이지당 10 개의 데이터가 있는 경우 100 페이지를 조회하려고 하면 실제로 각 슬라이스에 저장된 처음 1000 개의 데이터를/Kloc-0 으로 찾을 수 있습니다 5 개의 조각이 있으면 5,000 개의 데이터가 있고, 조정 노드는 5,000 개의 데이터에 대해 몇 가지 작업을 합니다.

분산, 100 페이지에서 10 개의 데이터를 확인해야 합니다. 5 개의 슬라이스부터 각 슬라이스가 2 개의 데이터를 검사하고 마지막으로 조정 노드에서 10 개의 데이터로 병합한다고 말할 수는 없겠죠? 각 조각에서 1000 개의 데이터를 찾고, 필요에 따라 정렬, 필터링 등을 하고, 마지막으로 다시 한 번 100 페이지의 데이터를 얻어내야 한다. 페이지를 넘길수록 각 슬라이스에서 반환되는 데이터가 많을수록 노드 처리 시간이 길어질수록 사기성이 높아집니다. 그래서 es 로 페이지를 만들 때 뒤로 갈수록 느려지는 것을 발견할 수 있다.

우리는 이전에 이 문제에 부딪친 적이 있다. Es 페이지를 사용할 경우 처음 몇 페이지는 수십 밀리초가 걸리며 10 또는 수십 페이지로 이동할 때 기본적으로 5~ 10 초가 필요합니다.

하나의 해결책?

1) 깊이 페이지 없음: 제품 관리자에게 시스템이 페이지를 넘기는 것을 허용하지 않는다고 알려 주십시오. 기본 심도가 높을수록 성능이 떨어집니다.

2) APP 또는 위챗 공식 계정에서 드롭다운 구현 페이지, 즉 드롭다운으로 최신 페이지를 얻을 수 있으며 scroll API 를 통해 수행할 수 있습니다.

Scroll 은 1 에 1 에 모든 데이터의 스냅샷을 생성합니다. 그런 다음 한 페이지로 다시 미끄러질 때마다 커서 scroll_id 를 통해 다음 페이지로 이동합니다. 성능은 위에서 언급한 페이징 성능보다 훨씬 높을 것입니다. 기본적으로 밀리초 단위입니다. 그러나 1 의 단점은 웨이보 드롭 다운 페이지와 같은 장면에 적용되며 어떤 페이지로도 자유롭게 이동할 수 없다는 것입니다. 즉, 10 페이지, 120 페이지, 다시 58 페이지로 이동할 수 없습니다. 마음대로 페이지 위에서 뛰어다닐 수 없다. 그래서 현재 많은 앱 제품들은 페이지를 마음대로 넘기는 것을 허용하지 않으며, 한 페이지만 한 페이지씩 뒤적거릴 수 있는 사이트도 있습니다.

초기화 시 scroll 매개변수를 지정하여 검색을 저장할 컨텍스트의 기간을 es 에 알려야 합니다. 사용자가 몇 시간 동안 계속 페이지를 넘기지 않도록 해야 합니다. 그렇지 않으면 시간 초과로 인해 실패할 수 있습니다.

Scroll API 사용 외에 search_after 도 사용할 수 있습니다. Search_after 의 아이디어는 이전 페이지의 결과를 사용하여 다음 페이지의 데이터를 검색하는 것입니다. 분명히, 이 방법은 네가 마음대로 페이지를 넘기는 것을 허락하지 않는다. 한 번에 한 페이지만 뒤로 뒤집을 수 있다. 초기화 시 1 값만 있는 필드를 정렬 필드로 사용해야 합니다.