Vinted 검색 확대/축소 5장: 분할

Elasticsearch는 매우 빠르지만 데이터 모델이나 접근 모델을 모릅니다.Elasticsearch는 우리의 디렉터리에 강력한 지원을 제공합니다. 이것은 비밀이 아니지만, 목록과 조회 수량이 끊임없이 증가함에 따라, 우리는 해결해야 할 문제가 많습니다.
2020년 중반, 우리는 러시아워에 실패한 검색 요청의 수가 끊임없이 증가하고 있음을 알아차렸다.Grafana의 노드 내보내기 지표를 보면 아무런 문제가 없습니다. 집단 부하가 상당히 균형이 잡혔지만, 분명히 그렇지 않습니다. 실제 서버에 로그인한 후에야 우리가 실행하는 모든 Elasticsearch 노드에 부하 분포가 고르지 않다는 것을 깨달았습니다.

문서 기록이 있는 최적화 집단과 JVM 설정의 지도 원칙에 따라 우리는 number_of_shards * (number_of_replicas + 1) < #data_nodes의 건의에 따라 조각 크기와 사본 수량을 실험했다.그러나 이것은 우리에게 현저한 개선을 가져오지 않았기 때문에 우리는 다른 전략으로 이 문제를 처리해야 한다.
우리는 특정한 유형의 조회를 위한 단독 인덱스를 만들기 위해 '분리된' 정책을 적용하기로 결정했다.그것들은 서로 다른 집단에 존재하거나, 서로 다른 수량의 조각이나 복사본을 가지거나, 색인 시간 순서를 가지고 있을 수 있다.우리는 우선 모든 /_count 검색을 다른 그룹으로 바꾸었습니다. 이것은 실패 요청의 부분을 크게 줄였습니다.그리고 우리는 우리가 몇 가지 중요한 것을 발견했다는 것을 깨달았다.
Vinted는 다중 언어 검색을 지원하며 각 언어의 색인 정책을 사용합니다.또한 사용자가 텍스트를 검색하지 않고도 필터를 사용하여 디렉토리를 탐색할 수 있습니다.우리는 이러한 검색을 지원하기 위해 버전의 목록 인덱스를 만들었습니다.이렇게 하면, 우리는 모든 목록을 색인에 놓고, 텍스트 필드를 분석하지 않고, 모든 조회를 그것들로 바꿀 수 있다.
놀랍게도 새 지수는 같은 집단에 있지만 집단의 부하를 더욱 고르게 분배하는 데 도움이 된다.추가 디스크 공간과 복잡성 증가는 균형 잡힌 문제다.우리는 데이터의 증가를 더욱 쉽게 제어하고 조회 성능을 향상시키며 리셋 시간을 줄일 수 있는지 날짜에 따라 색인을 구분하기로 결정했다.날짜에 따라 색인을 나누면 조각을 이용해서 기술을 뛰어넘을 수 있습니다.예를 들어 검색 조회가 2주 동안 지속되는 데이터를 가정한다.Elasticsearch는 조각을 건너뛰고, 지난달의 색인 구역만 조회하고, 나머지 구역은 건너뛰는 것으로 최적화할 것입니다.
SMT(Single Message Transformation Transformation Transformation Transformations) 가 포함된 데이터 캡처 기능을 통해 메시지가 Connect를 통과할 때 변환할 수 있음을 이미 알고 계실 것입니다.특히 두 SMT는 흥미롭습니다.
  • Timestamp Router
  • Regex Router
  • 타임 스탬프 라우터는 로깅된 주제 이름과 서식 적용 기능이 있는 타임 스탬프 필드를 사용하여 새 주제 필드를 구성할 수 있습니다.
    Regex Router에서는 레코드의 주제를 구성된 정규 표현식과 대체 문자열로 업데이트할 수 있습니다.
    이 공유기, 우리의 기록, 그리고 묘비 정보를 사용하려면 반드시 고정된 시간 스탬프를 포함해야 한다.그렇지 않으면, 우리는 영원히 일치된 데이터를 Elasticsearch로 촬영할 수 없을 것이다.기본적으로 모든 새 기록은 현재 시간 스탬프를 사용하지만 ruby-kafka allows it to be overwritten 모든 값을 사용합니다.우리는 목록의 생성 시간으로 그것을 덮어쓰는 것이 작용할 것이라고 믿는다.우리도 시도ILMdata streams를 고려해 보았지만 곧 거절했다. 왜냐하면 이 두 가지 기술은 모두 부가 데이터만을 대상으로 하기 때문이다.
    우리는 작은 응용 프로그램을 구축하여 우리의 섭취 파이프를 시뮬레이션했지만 몇 가지 변화가 있었다.
  • 키당
  • 의 고정값으로 덮어쓰기create_time
  • 타임 스탬프 라우터를 사용하여 기록을 매월 한 번의 구역으로 구분
  • {
      "transforms": "TimestampRouter",
      "transforms.TimestampRouter.timestamp.format": "yyyy.MM",
      "transforms.TimestampRouter.topic.format": "${topic}-${timestamp}",
      "transforms.TimestampRouter.type": "org.apache.kafka.connect.transforms.TimestampRouter"
    }
    
    설정 변경은 상당히 간단하지만, 매우 강력하다. 기록된 시간 스탬프를 기록의 주제로 하고, 연도와 월의 접미사를 붙인다.

    좋지만, 우리는 과거의 목록이 많고, 아주 적은 기록을 위해 한 달 동안 저장통을 만드는 것은 매우 비싸다.이 문제를 해결하기 위해서, 우리는 Regex 공유기를 사용하여 2019년 이전의 모든 구역을 하나의 old 구역에 놓았다.그것은 새로운 물건에 손대지 않을 것이다.
    {
      "transforms": "TimestampRouter,MergeOldListings",
      "transforms.TimestampRouter.timestamp.format": "yyyy.MM",
      "transforms.TimestampRouter.topic.format": "${topic}-${timestamp}",
      "transforms.TimestampRouter.type": "org.apache.kafka.connect.transforms.TimestampRouter",
      "transforms.MergeOldListings.regex": "(?-mix:(.+)-((2010|2011|2012|2013|2014|2015|2016|2017|2018).*))",
      "transforms.MergeOldListings.replacement": "$1-old",
      "transforms.MergeOldListings.type": "org.apache.kafka.connect.transforms.RegexRouter"
    }
    


    이 모든 것이 정상적이라는 것을 확인한 후에 우리는 응용 프로그램에서 이 점을 실현했다. 이것은 상당히 간단하다.
  • 우리의 목록을 위한 새로운 테마 만들기(현재의 섭취관에 영향을 주고 싶지 않음)
  • 신구 화제 동시 쓰기
  • 새 테마에 기록을 보낼 때 목록 생성 시간 사용하기
  • 새로운 테마와 루트 정책을 사용하여 섭취 테스트
  • 우리가 섭취 효과가 예상대로 확인되면
  • 새로운 주제로 전환
    처음에 섹션 인덱스로 전환하는 데 성공하지 못했기 때문에, 우리는 그것들을 위해 맞춤형 조회를 하고, 조각의 수량과 복사본의 수량을 조정해야 한다.여러 차례의 실패한 시도를 거쳐 우리는 마침내 매우 효과적인 판본을 하나 얻었다.

    Dell은 P99를 20ms 절감하는 데 성공했을 뿐만 아니라 다음과 같은 놀라운 성과를 거두었습니다.
  • 쿼리 및 요청 캐시 적중률이 90% 이상인 이유는 이전 인덱스 업데이트 빈도가 낮기 때문
  • 여러 색인 간에 부하를 분배하면 전체 집단의 부하가 더욱 고르게 되기 때문에 우리는 더 이상 열 노드가 없다
  • top-k의 최신 항목
  • 을 조회할 때 색인 파편이 더 적습니다
    회상해 보면 이런 이상 행위는 던전 선택 공식에 적응하는 bug에 의한 것일 가능성이 높다.그러나 과거로 돌아가면 우리는 분할치료 전략을 창조적으로 응용함으로써 이 결함을 완화시켰고 이 전략은 지금까지도 우리를 도와주고 있다.

    좋은 웹페이지 즐겨찾기