웹 API에 대한 네트워크 호출에서 여러 데이터베이스 호출이 실제로 중요합니까?


16

고용주 중 한 곳에서 REST (SOAP에도 적용됨) API 작업을했습니다. 응용 프로그램 UI 인 클라이언트는 웹 (일반 프로덕션 배포의 LAN)을 통해 API를 호출합니다. API는 데이터베이스를 호출합니다.

토론에서 되풀이되는 한 가지 주제는 성능입니다. 팀의 일부 사람들은 성능 때문에 단일 API 호출에서 여러 데이터베이스 호출 (보통 읽기)이 없어야한다고 생각합니다. 각 API 호출에 하나의 데이터베이스 호출 만 포함되도록 최적화해야합니다.

그러나 이것이 정말로 중요합니까? UI가 API를 네트워크 호출해야한다고 생각하십시오. 꽤 큽니다 (밀리 초 단위). 데이터베이스는 메모리에 내용을 보관하고 매우 빠르게 읽기를 실행하도록 최적화되어 있습니다 (예 : SQL Server는 모든 것을 RAM에로드 및 보관하고 가능한 경우 거의 모든 여유 RAM을 소비 함).

TLDR : LAN을 통해 이미 네트워크 호출을 할 때 여러 데이터베이스 호출에 대해 걱정하는 것이 정말로 중요합니까? 그렇다면 왜 그렇습니까?

분명히하기 위해, 나는 규모의 순서에 대해 이야기하고 있습니다-나는 그것이 특정 (기계 하드웨어, API 및 DB 선택 등)에 달려 있다는 것을 알고 있습니다 .O (밀리 초)가 걸리는 호출이 있으면 DB를 최적화합니다. 10 배 적은 통화가 실제로 중요합니까? 아니면 이것보다 문제가 더 있습니까?

편집 : 후손을 위해, 특히 프로파일 링이 부족한 상황에서 데이터베이스 호출을 결합하여 성능을 개선해야한다고 주장하는 것은 우스운 일이라고 생각합니다. 그러나 우리가 이것을하는지 아닌지는 나의 결정이 아니다. 이것이 웹 API 호출을 최적화하는 올바른 방법이라고 생각하는 이유가 무엇인지 알고 싶습니다.


API 계층과 데이터베이스 사이에 다른 네트워크 호출이 없습니까?
Sign

4
타이밍 테스트는 무엇을 보여 주었습니까?
Dan Pichelman

@Sign API와 DB간에 네트워크 호출이 없습니다. 그들은 내가 이해 한 것과 같은 기계에 있다고 보장합니다.
ashes999

@ DanPichelman 그게 내가 요구하는 것입니다. 아무도 성능을 발휘하지 않는 것 같습니다. "모든 DB 호출을 단일 호출로 결합하여 X의 성능을 수정해야한다는 요구 사항을 얻었습니다."
ashes999

답변:


25

그러나 이것이 정말로 중요합니까? UI가 API를 네트워크 호출해야한다고 생각하십시오. 꽤 큽니다 (밀리 초 단위). 데이터베이스는 메모리에 내용을 보관하고 매우 빠르게 읽기를 실행하도록 최적화되어 있습니다 (예 : SQL Server는 모든 것을 RAM에로드 및 보관하고 가능한 경우 거의 모든 여유 RAM을 소비 함).

논리

이론적으로는 맞습니다. 그러나이 근거에는 몇 가지 결함이 있습니다.

  1. 당신이 언급 한 바에 따르면 실제로 앱을 테스트 / 프로파일 링했는지 확실하지 않습니다. 즉, 앱에서 API 로의 네트워크 전송이 가장 느린 구성 요소 라는 것을 실제로 알고 있습니까? 그것이 직관적이기 때문에, 그것을 추측하기가 쉽습니다. 그러나 성능을 논의 할 때 절대 가정해서는 안됩니다. 저는 고용주로서 성과 책임자입니다. 내가 처음 가입했을 때 사람들은 병목 현상이 무엇인지에 대한 직감을 바탕으로 CDN, 복제 등에 대해 계속 이야기했습니다. 우리의 가장 큰 성능 문제는 데이터베이스 쿼리의 성능 저하였습니다.

  2. 데이터베이스가 데이터를 검색하는 데 능숙하기 때문에 데이터베이스가 반드시 최고 성능으로 실행 중이고 최적으로 사용 중이며 개선하기 위해 수행 할 수있는 작업이 없다고합니다. 즉, 데이터베이스는 빠르도록 설계되었으므로 걱정할 필요가 없습니다. 또 다른 위험한 사고 방식. 그것은 자동차가 빠르게 움직인다는 의미이므로 오일을 바꿀 필요가 없습니다.

  3. 이 사고 방식은 한 번에 단일 프로세스를 가정하거나 동시성을 사용하지 않는 다른 방식을 가정합니다. 한 요청이 다른 요청의 성능에 영향을 줄 수 없다고 가정합니다. 디스크 I / O, 네트워크 대역폭, 연결 풀, 메모리, CPU주기 등과 같은 리소스는 공유됩니다. 따라서 한 데이터베이스 호출의 공유 리소스 사용을 줄이면 다른 요청이 느려지는 것을 방지 할 수 있습니다. 내가 현재 고용주에 처음 합류했을 때 경영진은 3 초 데이터베이스 쿼리 튜닝이 시간 낭비라고 믿었습니다. 3 초가 너무 적어서 왜 시간이 낭비됩니까? CDN이나 압축 또는 다른 방법으로 더 나아지지 않습니까? 그러나 인덱스를 추가하여 1 초 안에 3 초 쿼리를 실행할 수 있다면, 즉 블로킹 2/3, 스레드 점유에 소요되는 시간 2/3, 더 중요한 것은 디스크에서 읽는 데이터가 적습니다.

이론

소프트웨어 성능이 단순히 속도에 관한 것이라는 일반적인 개념이 있습니다 .

순전히 속도의 관점에서, 당신이 맞습니다. 시스템은 가장 느린 구성 요소만큼 빠릅니다. 코드를 프로파일 링하고 인터넷이 가장 느린 구성 요소라는 것을 알게되면 다른 모든 것이 가장 느린 부분은 아닙니다.

그러나 위의 내용을 감안할 때 리소스 경합, 인덱싱 부족, 잘못 작성된 코드 등이 성능에 놀라운 차이를 만드는 방법을 알 수 있기를 바랍니다.

가정

마지막 한가지. 데이터베이스 호출은 앱에서 API 로의 네트워크 호출에 비해 저렴해야한다고 언급했습니다. 그러나 앱과 API 서버가 동일한 LAN에 있다고 언급했습니다. 따라서 둘 다 네트워크 호출과 비슷하지 않습니까? 다시 말해, API 전송이 모두 사용 가능한 대역폭이 같을 때 데이터베이스 전송보다 수십 배 느리다고 가정하는 이유는 무엇입니까? 물론 프로토콜과 데이터 구조는 다르지만 그 정도는 다르다고 가정합니다.

어두워지는 곳

이 전체 질문은 "복수"대 "단일"데이터베이스 호출에 관한 것입니다. 그러나 얼마나 많은지 불분명합니다. 위에서 말한 것 때문에 일반적으로 경험에 따라 데이터베이스 호출을 적게하는 것이 좋습니다. 그러나 그것은 단지 경험의 법칙 일뿐입니다.

이유는 다음과 같습니다.

  1. 데이터베이스는 데이터를 잘 읽습니다. 그들은 스토리지 엔진입니다. 그러나 비즈니스 로직은 애플리케이션에 있습니다. 모든 API 호출로 인해 정확히 하나의 데이터베이스 호출이 발생한다는 규칙을 작성하면 비즈니스 논리가 데이터베이스에서 종료 될 수 있습니다. 어쩌면 괜찮습니다. 많은 시스템이 그렇게합니다. 그러나 일부는 그렇지 않습니다. 유연성에 관한 것입니다.
  2. 때때로 좋은 디커플링을 달성하기 위해 2 개의 데이터베이스 호출을 분리하려고합니다. 예를 들어, 모든 HTTP 요청은 일반 보안 필터를 통해 라우팅되며,이 보안 필터는 DB에서 사용자에게 올바른 액세스 권한이 있는지 확인합니다. 그렇다면 해당 URL에 적절한 기능을 계속 수행하십시오. 이 기능은 데이터베이스와 상호 작용할 수 있습니다.
  3. 루프에서 데이터베이스 호출 이것이 내가 몇 개인 지 물었던 이유입니다. 위의 예에서는 2 개의 데이터베이스 호출이 있습니다. 2는 괜찮습니다. 3 괜찮을 수도 있습니다. N은 좋지 않습니다. 루프에서 데이터베이스를 호출하는 경우 이제 성능이 선형이되었으므로 루프의 입력에있는 시간이 오래 걸릴 것입니다. 따라서 API 네트워크 시간이 가장 느리다는 말은 데이터베이스를 10,000 번 호출하는 아직 발견되지 않은 루프로 인해 오랜 시간이 걸리는 트래픽의 1 %와 같은 예외를 완전히 간과하는 것입니다.
  4. 때로는 복잡한 계산과 같이 앱이 더 나은 것들이 있습니다. 데이터베이스에서 일부 데이터를 읽고 계산을 수행 한 다음 결과를 기반으로 매개 변수를 두 번째 데이터베이스 호출에 전달해야합니다 (일부 결과 작성 가능). 데이터베이스를 한 번만 호출하기 위해 저장 프로 시저와 같은 단일 호출로 이들을 결합하는 경우 앱 서버가 더 나은 데이터베이스를 사용해야합니다.
  5. 로드 밸런싱 : 하나의 데이터베이스 (아마도)와 여러로드 밸런싱 된 응용 프로그램 서버가 있습니다. 따라서 앱이 수행하는 작업이 많고 데이터베이스가 적을수록 데이터베이스를 설정하는 것보다 일반적으로 앱 서버를 추가하는 것이 더 쉽기 때문에 확장하기가 더 쉽습니다. 이전 글 머리 기호를 기준으로 SQL 쿼리를 실행 한 다음 여러 서버에 분산 된 응용 프로그램에서 모든 계산을 수행 한 다음 완료되면 결과를 기록하는 것이 좋습니다. 전체 트랜잭션 시간이 동일하더라도 처리량이 향상 될 수 있습니다.

TL; DR

TLDR : LAN을 통해 이미 네트워크 호출을 할 때 여러 데이터베이스 호출에 대해 걱정하는 것이 정말로 중요합니까? 그렇다면 왜 그렇습니까?

예, 그러나 어느 정도까지만 가능합니다. 가능할 때 데이터베이스 호출 수를 최소화하려고하지만 서로 결합하기 위해 서로 관련이없는 호출을 결합하지 마십시오. 또한 모든 비용으로 루프에서 데이터베이스를 호출하지 마십시오.


3

팀이 이유를 밝히기 전에 최적화하는 것처럼 들립니다. 이러한 요청을 실행하는 시간을 측정 했습니까? 웹 서버로의 왕복은 웹 서버에서 데이터베이스로의 연결 시간보다 대기 시간이 훨씬 길기 때문에이 패러다임을 강요하면 최종 사용자의 성능이 저하 될 수 있습니다. 또한 대부분의 웹 브라우저는 단일 웹 서버에 2 개의 동시 연결 만 수행하므로 복잡한 페이지의 경우 병목 현상이 발생할 수 있습니다.

백업 할 데이터가 없으면 최적화 결정을 내릴 수 없습니다. 그것을 측정하고 응용 프로그램에 가장 적합한 것을 알아냅니다.


1
이것은 우리의 나쁜 성능 관행에 대한 좋은 의견이지만, 이미 네트워크 호출이있을 때 DB 호출이 걱정할만한 것인지에 대한 내 질문에는 대답하지 않습니다.
ashes999

1
일반적으로 여러 데이터베이스 호출을 수행하면 문제가되지 않습니다. 이것은 주로 연결 풀링과 DB와 웹 서버 간의 짧은 대기 시간 때문입니다. 다른 db 호출을 여러 번 수행하면 성능에 부정적인 영향을 미치는 지점이 있지만 어려운 것은 아닙니다. 환경과 응용 프로그램에 따라 다릅니다. 측정 만하면 원하는 답을 얻을 수 있습니다.
brianfeucht

나는 순서에 대해 이야기하고 있기 때문에 (필수적으로) 세부 사항에 의존해서는 안됩니다.
ashes999

대략적인 추측 (측정해야 함) : 웹 서버에서 DB에 연결하는 데 걸리는 평균 시간 : 2ms 클라이언트에서 웹 서버에 연결하는 데 걸리는 평균 시간 : 20ms 그래서 내가 임의로 뽑아 낸 숫자가 정확하다고 가정하면 10을 할 수 있습니다 하나의 웹 서비스 호출을 수행하는 데 걸리는 시간에 데이터베이스 호출. 데이터베이스 쿼리에 동일한 시간이 걸린다고 가정합니다. 그 수치는 환경에 크게 의존합니다. 웹 서비스 호출을하는 클라이언트가 로컬 인 경우 몇 배 정도 줄어 듭니다.
brianfeucht

2

우리는 당신에게 말할 수 없습니다.

우리는 당신의 쿼리처럼 보이지 않습니다. 우리는 그들이 완료하는 데 걸리는 시간을 모른다. API 서버에 대한 각 요청에 얼마나 많은 오버 헤드가 포함되어 있는지 알 수 없습니다. 고객이 지리적으로 어떻게 분산되어 있는지 모릅니다. 기타.

최적화필요한 시나리오 이고 통화를 분할 또는 참여할지 여부를 결정할 있는 시나리오 인 경우 두 가지 방법으로 벤치마킹해야합니다 . 최적화 할 대상 결정 (UI 대기 시간, 서버 CPU로드, 경합, 등)을 선택하고 최적화 목표를 더 잘 달성하는 것을 선택하십시오.


그 외에, 단 하나 내가 상대 확실하게 추가 할 수있는 일이있다 :

단일 요청 내에서 응답을 빌드하기 위해 수행해야하는 모든 쿼리를 수행해야합니다.

다시 말해, 모든 N 개의 쿼리가 수행 될 때까지 응답을 생성 할 수없는 경우 일반적으로 쿼리를 분리하는 것은 의미가 없습니다. 각 쿼리 후 중간 또는 완료 여부에 관계없이 의미있는 결과를 생성 할 수있는 경우 벤치마킹을 시작하십시오.


1

두 가지 생각 :

먼저 API를 사용하는 소비자에게 작업을 수행하기 위해 한 번의 호출을하고 있습니다. 서버가 요청을 채우기 위해 전화를받은 후 발생하는 일은 그렇게 엄격해서는 안됩니다. 소비자가 한 번의 호출에서 데이터를 가져 와서 리턴하기 위해 10 개의 하위 작업 항목이 필요한 경우 이는 허용 가능해야합니다.

둘째 : 문제의 프로세스에 실제 데이터베이스 성능 문제가 있습니까? 필자의 경험에 따르면 데이터베이스 요청의 모든 측면을 단일 호출에 자주 넣으려고하면 단순히 데이터를 3-4 개 호출하는 것보다 덜 효율적으로 호출 할 수 있습니다. 최신 데이터베이스는 캐싱 ​​및 실행 계획에서 매우 효율적입니다. 너무 많은 일을하려고 할 때 커서가있는 프로 시저 (데이터가 한 번에 설정되지 않고 한 행씩 수행되기 때문에 성능이 매우 나빠짐)와 코드가 깨진 경우보다 계획이 덜 효율적인 결과를 보게됩니다. 몇 가지 작은 쉬운 단계로 전화.

간단한 코드 구성에서 각 API 호출은 단일 저장 프로 시저 (또는 db 함수)를 호출해야하며 요청을 작성해야합니다. 절차에 여러 단계가있을 수 있습니다.


아무도하지 않는 것 같은 성능 측정에 대해 동의합니다. 이것이 더 빠르다는 증거는 없지만 계속 올라옵니다. 1000 DB와 같은 호출이있을 때 성능이 문제로 나타납니다 SELECT.
ashes999

@ ashes999는 db 호출 수를 빠르게 볼 수 있지만 호출 수가 아닌 인덱싱 전략 등에서 더 많이 발견됩니다. 모두가 지적했듯이 성능 데이터를 살펴보십시오.
Richard

리차드, 나는 동의한다. 그리고 나는 그것을 실제로 알고있다. 제 질문은 네트워크 호출이 관련 될 때 다양한 사람들이 계속해서 "다중 DB 호출이 느리다"는 점을 제기하는 이유입니다. 나는 그것이 어떻게 중요한지 알지 못한다.
ashes999

@ ashes999 죄송합니다. 네트워크 호출에 대해 좀 더 자세히 설명해야 할 것입니다. 분명해 보이므로 귀하의 질문에 조금 더 있음을 느낍니다. 질문에 뭔가 빠진 것 같습니다. 항상 약간의 네트워크 대기 시간이 발생하며 각 통화는 각 통화마다 "x"시간 (단순)으로 증가 할 가능성이 있습니다. 액면가에 대한 설명은 true이며 여러 네트워크 호출은 db에 대한 하나의 네트워크 호출보다 느립니다. 그래서 저장 프로 시저에 한 번의 호출을 제안하여 다중 네트워크 호출없이 db를 여러 번 호출 할 수 있습니다.
Richard

1

데이터베이스가 REST 서비스와 다른 서버에있는 경우 각 데이터베이스 호출로 인해 네트워크 왕복이 발생하여 성능 크게 저하 될 수 있습니다 .

한 번 웹 서비스 호출이 약 500 개의 데이터베이스 쿼리로 변환되는 것을 관찰했습니다. 이것은 웹 서비스와 데이터베이스가 같은 컴퓨터에있을 때 거의 문제가되지 않았지만 서로 다른 상태에서 6-7 초의 응답 시간으로 바뀌 었습니다. 기계.

분명히, 데이터베이스로의 500 왕복은 매우 극단적입니다. 성능 요구 사항이 무엇인지 확실하지 않지만 대체로 REST 호출 당 약 10 개의 데이터베이스 쿼리에 머무르면 성능이 크게 저하되지 않아야합니다.


1

매우 까다로운 몇 가지 응용 프로그램이 있습니다. 모든 데이터베이스 호출이 있습니다. 단일. 작은. 의회. 참조 데이터를 반복해서 제공하는 것은 시스템에서 작업 부하의 주요 부분입니다. 실제 디스크 IO가 없더라도 작업자 스레드 예약, 잠금 획득 및 삭제, 캐시 검사 계획 등이 추가됩니다. 트랜잭션은 여러 DB 호출에서 잠금을 유지해야하기 때문에 처리량이 더 많으므로 처리량이 훨씬 적습니다. 이 팀은 이제 이로 인해 매우 고가의 DB 서버를 새로 구매해야합니다.

따라서 시스템의 현재 구성에서 대부분의 경과 시간이 REST API 호출을 사용하더라도 DB 레벨의 성능을 무시하면 미래의 문제점이 저장됩니다.


0

제시된 최적화 경로는 단순히 사물을 보는 잘못된 방법입니다.

API 호출은 원자 적이어야합니다. 즉, 원하는 작업을 수행하기 위해 1 개의 웹 API 호출을 수행 할 수 있어야합니다. 그것이 데이터를 가져 오는지, 레코드를 업데이트하는지 또는 무엇이든. 조치를 유발하기 위해 호출을 두 번 이상 가져서는 안됩니다. 그리고 여러 통화에서 거래를 활용하려는 시도는 전염병처럼 피해야합니다.

때로는 단일 조치가 다소 복잡합니다. 예를 들어 여러 소스에서 결합 된 데이터 페치 : 다시 한 번 호출해야합니다. 전체가 작동하거나 전체가 실패합니다.

이제 단일 API 호출로 하나의 DB 쿼리 만 실행해야한다는 것은 약간 모 론적입니다. 당신이 지적했듯이, 네트워크를 통해 전화를 마샬링하는 데 드는 오버 헤드는 종종 전체 시간면에서 훨씬 더 비쌉니다.

내가 할 수 다소 그들의 문을 이해하는 하나의 쿼리가 실행 빨리 여러 가지 이상의 수; 그러나 이것은 전체 DB 및 네트워크로드를 무시하므로 잘못된 인상을줍니다. DB에서 데이터를 가져 오는 다양한 방법을 프로파일 링해야만 문제가 실제로 무엇인지 파악할 수 있습니다. 나는 모든 사람들이 적절한 인덱스가 배치 될 때까지 특정 쿼리가 예상보다 100 배 더 자주 실행되었다는 이야기를 가지고 있다고 확신합니다 ...

궁극적으로 당신은 단지 대화만으로 그들을 설득 할 수 없을 것입니다. 두 가지 접근 방식에 대한 테스트 사례를 설정하고 프로파일 링하십시오. 필요한 데이터, 생성 된 네트워크 트래픽 양, 데이터베이스 호출 수 및 타이밍 등을 확보하는 데 총 시간을주의하십시오. 전체 시스템을 살펴 보는 전체적인 접근 방식을 취하십시오. 까마귀를 먹거나 황금의 길을 보여줄 데이터.

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