어떤 조건에서 (있는 경우) 두 서버를 쿼리하고 가장 빠른 응답 만 소비하는 것이 좋습니까?


12

왜 누군가가 javascript 's를 사용하는 지에 대해 SO 에 대한 삭제 된 커뮤니티 질문이 무엇인지 물었고 높은 응답 Promise.race사용자가 다음과 같이 말했습니다.

일부 값을 계산하는 두 개의 서비스가있는 경우 서비스를 병렬로 쿼리하고 하나를 쿼리하고 실패를 기다린 다음 두 번째를 쿼리하지 않고 먼저 반환되는 값을 사용할 수 있습니다.

중복 성과이 유스 케이스에 대해 봤지만 아무것도 찾을 수 없었으며 POV에서 응답을 사용하지 않을 경우 서버 / 서비스에 워크로드를 추가하는 것은 결코 좋은 생각이 아닙니다.


장난감 예 : 항상 quicksort를 사용하는 대신 데이터를 복사하여 quicksort, mergesort 및 heapsort 등으로 보냅니다. 병리 적 사례인지 확인하기 위해 입력을 검사 할 필요가 없습니다. 에 대한 모든 사람들의, 때문에 그것의 pathalogical 경우되지 않습니다 모든 그들 중
Caleth

Dean and Barroso 논문 The Tail at Scale 은 이러한 접근 방식의 "헤지 드 요청"에 대한 변형을 요구합니다. 또한 오류율 및 대기 시간의 롱테일 변동성을 제어하기위한 몇 가지 관련 접근 방식의 장단점에 대해서도 설명합니다.
Daniel Pryden

두 번째 "서버 요청"은 가짜 일 수 있습니다. 5 초 동안 원하는 다음 자리 표시 자 응답을 반환 할 수 있습니다. 실제 요청에 대한 시간 초과가 발생합니다.
user253751

Lyft를 주문한 다음 Uber를 주문하십시오. 먼저 오는 것을 가져 가라.
user2023861 2016 년

이 비유에서 @ user2023861은 한 운전자가 무의식적으로 귀하의 위치를 ​​향해 운전하는 동안 다른 요청을 대신했을 수 있습니다
Adelin

답변:


11

나는 이것이 경제적 인 문제라고 주장한다. 그러나 이는 엔지니어가 할 수있는 판단 요청입니다. 따라서 대답하고 있습니다.

답변을 네 부분으로 나눕니다.

  • 위기 관리
  • 전략
  • 소송 비용
  • 직관

위기 관리

따라서 때때로 클라이언트가 서버로부터 응답을 얻지 못하는 경우가 있습니다. 나는 이것이 프로그래밍상의 오류 때문이 아니라고 가정 할 것입니다 (그렇지 않으면 해결책은 해결하는 것이므로 그렇게하십시오). 대신, 그것은 당신이 통제 할 수없는 우연한 상황 때문이어야합니다 ...

그러나 당신의 지식을 넘어선 것은 아닙니다. 당신은 알아야합니다 :

  • 얼마나 자주 발생합니까?
  • 어떤 영향이 있습니까?

예를 들어, 실패 및 재시도 시간의 약 2 % 만 발생하면이를 해결할 가치가 없습니다. 시간의 약 80 %가 발생하면 ...

클라이언트는 얼마나 많은 시간을 기다려야합니까? 그리고 어떻게 비용으로 해석 할 수 있습니까? 정규 애플리케이션에서 약간의 지연이있을 수 있습니다. 아마 큰 문제는 아닙니다. 중요하고 실시간 응용 프로그램 또는 온라인 비디오 게임을 사용하는 경우 사용자가 멀어지고 더 많거나 더 나은 서버에 투자하는 것이 좋습니다. 그렇지 않으면 "로드 중"또는 "서버 대기 중"메시지를 넣을 수 있습니다. 지연이 실제로 크지 않는 한 (수십 초 정도), 일반 응용 프로그램에 비해 너무 클 수 있습니다.


전략

위에서 말했듯이이 문제를 해결하는 방법은 여러 가지가 있습니다. try-fail-retry 루프 구현이 이미 있다고 가정합니다. 그럼 보자 ...

  • 로딩 메시지를 넣습니다. 저렴하고 사용자 유지에 도움이됩니다.
  • 병렬로 쿼리하십시오. 더 빠를 수 있지만 여전히 실패 할 수 있습니다. 중복 서버가 필요하며 (비용이 많이들 수 있음) 서버 시간과 네트워크 트래픽이 낭비됩니다.
  • 더 빠른 서버를 구축하고 거기서부터 사용하기 위해 병렬로 쿼리하십시오. 더 빠를 수 있지만 여전히 실패 할 수 있습니다. 중복 서버가 필요하며 (비용이 많이들 수 있음) 서버 시간과 네트워크 트래픽을 많이 낭비하지 않습니다.

자, 이것들은 여전히 ​​실패 할 수 있습니다. 서버에 대한 쿼리가 80 %의 실패 가능성을 가정하면 두 서버에 대한 병렬 쿼리는 64 %의 실패 가능성을 갖습니다. 따라서 다시 시도해야 할 수도 있습니다.

더 빠른 서버를 선택하고 계속 사용한다는 이점은 네트워크 문제로 인해 더 빠른 서버도 실패 할 가능성이 적다는 것입니다.

요청이 실패한 이유를 알 수 있다면 그렇게하십시오. 장애를 예방할 수 없더라도 상황을보다 잘 관리하는 데 도움이됩니다. 예를 들어 서버 쪽에서 더 빠른 전송 속도가 필요합니까?

좀 더:

  • 전 세계에 여러 서버를 배포하고 지리적 위치별로 서버를 선택하십시오.
  • 서버 측에서로드 밸런싱을 수행하십시오 (전용 시스템은 모든 요청을 가져 와서 서버에 요청, 병렬 처리 또는 더 나은 균형 전략을 가질 수 있음).

그리고 누가이 중 하나만해야한다고 말했습니까? 로딩 메시지를 넣고, wrold에 분산되어있는 여러 서버를 쿼리하여 더 빠르게 선택하고 루프를 다시 시도 할 때만 사용하고, 각 서버는로드 밸런싱 기능이있는 머신 클러스터가되도록 할 수 있습니다 . 왜 안돼? 글쎄요, 비용은 ...


소송 비용

네 가지 비용이 있습니다.

  • 개발 비용 (보통 매우 저렴)
  • 배포 비용 (일반적으로 높음)
  • 비용 런타임 (응용 프로그램 유형 및 비즈니스 모델에 따라 다름)
  • 실패 비용 (아마도 낮지 만 반드시 필요한 것은 아님)

균형을 잡아야합니다.

예를 들어 만족스러운 사용자 당 약 1 달러의 수익이 있다고 가정 해 보겠습니다. 하루에 3000 명의 사용자가 있습니다. 요청이 약 50 % 실패합니다. 그리고 요청의 실패시 사용자의 2 %가 비용을 지불하지 않고 떠납니다. 이는 하루에 30 달러 (3000 * 50 % * 2 %)를 잃고 있음을 의미합니다. 이제 새로운 기능을 개발하는 데 100 달러의 비용이 소요되고 서버를 배포하면 800 달러의 비용이 발생하고 런타임 비용을 무시한다고 말하면 ((100 + 800) / 30에 대한 투자 수익을 얻게됩니다 ) 30 일. 이제 예산을 확인하고 결정할 수 있습니다.

현실을 대표하는 이러한 가치를 고려하지 말고 나는 수학의 편의를 위해 그것들을 선택했습니다.

부록 :

  • 나는 또한 세부 사항을 무시하고 있음을 기억하십시오. 예를 들어, 배포 비용은 적지 만 CPU 시간을 지불하고 있으므로 고려해야합니다.
  • 중복 요청에서 데이터 패키지를 낭비하지 않으면 일부 클라이언트가 감사 할 수 있습니다.
  • 제품을 개선하면 자연스럽게 광고하는 데 도움이 될 수 있습니다.
  • 기회 비용을 잊지 마십시오. 다른 것을 개발해야합니까?

문제는 밸런싱 비용 측면에서 문제를 고려할 경우 고려한 전략에 대한 비용을 추정하고이 분석을 사용하여 결정할 수 있다는 것입니다.


직관

경험으로 육성하는 경우 직감. 매번 이런 종류의 분석을 제안하지는 않습니다. 어떤 사람들은 그렇게합니다. 나는 당신이 이것에 대해 약간의 이해를 가지고 그것에 대한 직감을 개발하도록 제안하고 있습니다.

또한 공학에서 실제 과학에서 얻는 지식을 제외하고는 실습에서 배우고 작동하는 것과 작동하지 않는 것에 대한 지침을 작성합니다. 그러므로 종종 예술의 상태가 무엇인지 보는 것이 현명한 일입니다. 때때로, 당신은 때때로 당신의 영역 밖에서 볼 필요가 있습니다.

이 경우 온라인 비디오 게임을 볼 것입니다. 로드 화면이 있고 여러 서버가 있으며 대기 시간에 따라 서버를 선택하며 사용자가 서버를 전환 할 수도 있습니다. 우리는 그것이 작동한다는 것을 알고 있습니다.

모든 요청에서 네트워크 트래픽과 서버 시간을 낭비하는 대신 중복 서버를 사용하더라도 오류가 발생할 수 있다는 점에 유의하십시오.


2
나는 그것을 말할 필요는 없다고 생각하지만 이것은 훌륭한 대답입니다. 당신은하지
아 델린

9

클라이언트 시간이 서버 시간보다 더 가치있는 경우 이는 허용됩니다.

클라이언트가 빠르고 정확해야합니다. 여러 서버 쿼리를 정당화 할 수 있습니다. 유효한 답변을 받으면 요청을 취소하는 것이 좋습니다.

물론 서버의 소유자 / 관리자에게 문의하는 것이 좋습니다.


요청을 취소 해야하는 이유는 무엇 입니까? 확실히 주관적입니다.
JᴀʏMᴇᴇ

@ JᴀʏMᴇᴇ, 그것은 편집증에 빌드됩니다. 나는 한 번 대기열을 지우지 않은 시스템으로 작업했으며 대기열이 가득 찼을 때 충돌했습니다 (예 : 전문 소프트웨어였습니다).
Toon Krijthe

4

이 기술은 대기 시간을 줄일 수 있습니다. 서버 응답 시간은 결정적이지 않습니다. 규모에 따라 응답 시간이 좋지 않은 서버가 하나 이상있을 수 있습니다. 따라서 해당 서버를 사용하는 것은 응답 시간이 좋지 않습니다. 여러 서버에 제출하면 성능이 떨어지는 서버와 통신 할 위험이 줄어 듭니다.

비용에는 추가 네트워크 트래픽, 낭비되는 서버 처리 및 응용 프로그램 복잡성이 포함됩니다 (라이브러리에 숨겨 질 수 있음). 미사용 요청을 취소하거나 두 번째 요청을 보내기 전에 잠시 기다리면 이러한 비용을 줄일 수 있습니다.

여기 하나의 종이있고 또 다른 종이가 있습니다. 나는 그들의 구현도 구글 논문을 읽는 것을 기억한다.


2

나는 대부분 다른 답변에 동의하지만 실제로는 매우 드 물어야한다고 생각합니다. 나는 당신이 사용할 때에 대해 훨씬 더 일반적이고 합리적인 예를 공유하고 싶었습니다 Promise.race(). 몇 주 전에 (파이썬과 동등한) 사용했습니다.

긴 작업 목록이 있는데, 그 중 일부는 병렬로 실행할 수 있고 일부는 다른 것보다 먼저 실행되어야한다고 가정 해보십시오. 종속성없이 모든 작업을 시작한 다음로 목록을 기다립니다 Promise.race(). 첫 번째 작업이 완료 되 자마자 첫 번째 작업에 종속 된 작업을 시작 Promise.race()하고 원래 목록의 완료되지 않은 작업과 결합 된 새 목록에서 다시 시작할 수 있습니다 . 모든 작업이 완료 될 때까지 계속 반복하십시오.

참고 Javascript의 API는이를 위해 이상적으로 설계된 것은 아닙니다. 그것은 작동하는 최소한의 최소한이며, 약간의 접착제 코드를 추가해야합니다. 그러나 필자의 요점은 같은 기능 race()은 중복성을 위해 거의 사용되지 않는다는 것입니다. 모든 약속의 결과를 실제로 원할 때 주로 사용되지만 후속 조치를 취하기 전에 모든 약속이 완료되기를 기다리지 않습니다.


문제는 적어도 Javascript의 Promise.race를 사용하여 race 메소드를 실행할 때마다 실제로 작업을 시작한다는 것입니다. 완료되지 않은 작업이 아니라 이전에 실행 된 내용에 관계없이 새로운 작업 집합이됩니다 (작업 수준에서 해당 로직을 구현하지 않는 한). 원래 목록은 그렇지 않으면 잊혀지고 첫 번째 작업의 반환 값만 남아 있습니다
Adelin

1
Javascript의 약속 new Promise은 호출 될 때 간절히 시작 되고 Promise.race()호출 될 때 다시 시작되지 않습니다 . 일부 약속 구현은 게으르지 만 열망이 훨씬 일반적입니다. 콘솔에 로그인하는 콘솔에서 약속을 작성하여 테스트 할 수 있습니다. 당신은 즉시 로그를 볼 수 있습니다. 그런 다음 그 약속을에 전달하십시오 Promise.race(). 다시 기록하지 않는 것을 볼 수 있습니다.
Karl Bielefeldt

아 맞다. 그러나 promise.race와 함께 첫 번째 약속을 제외한 나머지 약속의 반환 값은 afaik입니다.
Adelin

그렇기 때문에 API가 이상적으로 설계되지 않았다고 말했습니다. 원래 작업 세트를 변수 어딘가에 저장해야합니다.
Karl Bielefeldt

1

기술적 고려 사항 외에도 실제 비즈니스 모델의 일부인 경우이 방법을 사용할 수 있습니다.

이 방법의 변형은 광고의 실시간 입찰 에서 비교적 일반적입니다 . 이 모델에서 게시자 (광고 공간 공급자)는 광고주 (광고 공급자)에게 특정 사용자 의 노출 에 입찰하도록 요청 합니다. 그래서 모든 같은 인상을 위해, 당신은 각 광고주를 조회 할이 (대안 자신의 서버에서 엔드 포인트로 실행 광고주가 제공하는 스크립트 나) 각 광고주가 제공하는 엔드 포인트 인상의 세부 쿼리를 전송, 가입, 경주 이러한 모든 요청은 최대 시간 초과 (예 : 100ms) 한 다음 다른 입찰을 무시하고 가장 높은 입찰가를 취합니다.

고객의 대기 시간을 줄이는 데 도움이되는 특정 변형은 게시자가 입찰가에 대한 최소 목표 값을 허용하도록하여 해당 값을 초과하는 첫 번째 광고주 입찰이 즉시 수락되도록하는 것입니다 (또는 입찰가를 초과하지 않는 경우). 값, 최대 값이 사용됩니다). 따라서이 변형에서 첫 번째 도착 쿼리는 우수하거나 더 나은 경우에도 이기고 다른 쿼리는 버릴 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.