저자 소개
간단히 말하면 Ctrip 백엔드 개발 관리자로서 기술 아키텍처, 성능 최적화, 운송 계획 및 기타 분야에 중점을 두고 있습니다.
교통 계획 및 교통 자원의 한계로 인해 사용자가 문의한 두 장소 간 직행 운송이 불가능하거나, 주요 공휴일에는 직행 운송이 매진되었습니다. 그러나 사용자는 여전히 기차, 비행기, 자동차, 선박 등 양방향 또는 다방향 환승을 통해 목적지에 도달할 수 있습니다. 또한 가격이나 시간 소모 측면에서 환승 운송이 더 유리한 경우도 있습니다. 예를 들어, 상하이에서 윈청까지 기차로 연결하는 것이 직행 열차보다 빠르고 저렴할 수 있습니다.
그림 1 씨트립 열차 환승 운송 목록
환승 운송 솔루션을 제공할 때 매우 중요한 링크는 기차, 비행기, 자동차, 선박 등 두 개 이상의 여행을 가능한 환승으로 결합하는 것입니다. 계획. 대중교통을 접속할 때 첫 번째 어려움은 접속 공간이 크다는 것입니다. 상하이만 대중교통 도시로 간주하면 거의 1억 개의 조합이 생성될 수 있다는 것입니다. 또 다른 어려움은 생산 라인 데이터 때문에 실시간 성능이 필요하다는 것입니다. 기차, 비행기, 자동차, 선박에 대한 데이터는 언제든지 변경되고 지속적으로 업데이트되어야 합니다. 전송 트래픽 접합에는 많은 컴퓨팅 리소스와 IO 오버헤드가 필요하므로 성능을 최적화하는 것이 특히 중요합니다.
이 기사에서는 전송 트래픽 접합 성능을 최적화하는 과정에서 따르는 원리, 분석 및 최적화 방법을 예제를 사용하여 소개하고 독자에게 귀중한 참고 자료와 영감을 제공할 것입니다.
2. 최적화 원칙성능 최적화에는 비즈니스 요구 사항 충족을 전제로 다양한 리소스와 제약 조건 간의 균형을 맞추고 절충이 필요합니다. 이를 따르면 불확실성을 제거하고 문제에 접근할 수 있습니다. 특히, 전송 트래픽 스플라이싱 최적화 프로세스에서는 다음 세 가지 원칙을 주로 따릅니다.
2.1 성능 최적화는 목적이 아닌 수단입니다.이 문서는 성능 최적화에 관한 것이지만 여전히 처음에 강조할 필요가 있습니다. : 최적화를 위해 하지 말고 최적화하세요. 비즈니스 요구 사항을 충족하는 방법에는 여러 가지가 있으며 성능 최적화는 그 중 하나일 뿐입니다. 문제가 매우 복잡하고 제한 사항이 많은 경우도 있습니다. 사용자 경험에 크게 영향을 주지 않으면서 제한 사항을 완화하거나 다른 프로세스를 채택하여 사용자에게 미치는 영향을 줄이는 것도 성능 문제를 해결하는 좋은 방법입니다. 소프트웨어 개발에는 약간의 성능을 희생하여 상당한 비용 절감을 달성한 사례가 많이 있습니다. 예를 들어 Redis에서 카디널리티 통계(중복 제거)에 사용되는 HyperLogLog 알고리즘은 표준 오류 0.81%로 단 12K 공간에서 264개의 데이터를 계산할 수 있습니다.
문제 자체로 돌아가서, 생산 라인 데이터를 자주 쿼리하고 대규모 접합 작업을 수행해야 하기 때문에 각 사용자가 쿼리할 때 가장 최근의 전송 계획을 즉시 반환해야 한다면 비용이 매우 높을 것입니다. 비용을 줄이려면 응답 시간과 데이터 최신성 사이의 균형을 맞춰야 합니다. 신중하게 고려한 후 분 단위의 데이터 불일치를 허용하기로 결정했습니다. 일부 인기 없는 경로 및 날짜의 경우 처음 쿼리할 때 적절한 환승 계획이 없을 수 있습니다. 이 경우 사용자에게 페이지를 새로 고치도록 안내합니다.
2.2 잘못된 최적화는 모든 악의 근원입니다Donald Knuth는 "Go To 문을 사용한 구조적 프로그래밍"에서 언급했습니다. "프로그래머는 중요하지 않은 경로의 성능에 대해 생각하고 걱정하는 데 많은 시간을 낭비합니다. 성능의 이 부분을 최적화하면 전체 코드의 디버깅 및 유지 관리에 매우 심각한 부정적인 영향을 미치므로 97%의 경우 작은 최적화 사항을 잊어버려야 합니다." 즉, 실제 성능 문제가 발견되기 전에 코드 수준에서 과도하고 허식적인 최적화를 수행하면 성능이 향상될 뿐만 아니라 더 많은 오류가 발생할 수 있습니다. 하지만 저자는 “나머지 핵심 3%에 대해서는 최적화의 기회를 놓치지 말아야 한다”고 강조했다. 따라서 항상 성능 문제에 주의를 기울여야 하며 성능에 영향을 미치는 결정을 내리지 말고 필요할 경우 올바른 최적화를 수행해야 합니다.
이전 섹션에서 언급했듯이 최적화하기 전에 먼저 성능을 정량화하고 병목 현상을 식별해야 최적화가 더욱 목표화될 수 있습니다. 성능의 정량적 분석에는 시간이 많이 걸리는 모니터링, 프로파일러 성능 분석 도구, 벤치마크 벤치마크 테스트 도구 등을 사용할 수 있으며 특히 시간이 오래 걸리거나 실행 빈도가 특히 높은 영역에 중점을 둡니다. Amdahl의 법칙에 따르면 "시스템의 특정 구성 요소에 대해 더 빠른 실행 방법을 사용하여 얻을 수 있는 시스템 성능 향상 정도는 이 실행 방법이 사용되는 빈도 또는 전체 실행 시간의 비율에 따라 달라집니다. "
또한 성능 최적화는 장기간의 싸움이라는 점에 유의하는 것도 중요합니다. 비즈니스가 계속 발전함에 따라 아키텍처와 코드도 끊임없이 변화하고 있기 때문에 지속적으로 성능을 정량화하고 병목 현상을 지속적으로 분석하며 최적화 효과를 평가하는 것이 더욱 필요합니다.
성과 분석에 앞서 먼저 비즈니스 프로세스를 정리해야 합니다. 환승 운송 계획의 연결에는 주로 다음 4단계가 포함됩니다.
a 난징 환승을 통해 베이징에서 상하이까지의 경로 지도를 로드하며 경로 자체의 정보만 고려되며 경로와는 아무런 관련이 없습니다. 특정 열차
b 출발 시간, 도착 시간, 출발 역, 도착 역, 가격 및 잔여 티켓 정보 등을 포함한 항공기, 자동차 및 선박의 생산 라인 데이터를 확인하세요. c. 환승을 주로 고려하여 가능한 모든 환승 운송 솔루션을 연결합니다. 환승을 완료할 수 없도록 탑승 시간이 너무 짧아서는 안 되며, 너무 오래 기다리지 않도록 너무 길어서는 안 됩니다. 실행 가능한 솔루션을 결합한 후에도 총 가격, 총 시간 소비, 전송 정보 등과 같은 비즈니스 분야를 개선해야 합니다.
d 특정 규칙에 따라 모든 실행 가능한 전송 솔루션에서 일부 사용자를 선택합니다. 관심을 가질만한 프로그램을 분리했습니다.
3.2 정량분석 성능
시간이 많이 걸리는 모니터링은 각 단계의 시간이 많이 걸리는 상황을 거시적 관점에서 관찰하는 가장 직관적인 방법입니다. 비즈니스 프로세스의 각 단계에서 시간이 소요되는 가치와 시간이 소요되는 비율을 볼 수 있을 뿐만 아니라 장기간에 걸쳐 시간이 소요되는 변화 추세를 관찰할 수도 있습니다.
시간이 많이 걸리는 모니터링은 회사의 내부 지표 모니터링 및 경보 시스템을 사용하여 운송 솔루션을 연결하는 주요 프로세스에 시간이 많이 걸리는 관리를 추가할 수 있습니다. 이러한 프로세스에는 경로 지도 로드, 교대 데이터 쿼리 및 접합, 접합 계획 필터링 및 저장 등이 포함됩니다. 각 단계의 시간이 소요되는 상황은 그림 2에 나와 있습니다. 스플라이싱(생산 라인 데이터 포함)이 시간 소모의 가장 높은 비율을 차지하는 것을 볼 수 있으므로 향후 핵심 최적화 대상이 되었습니다.
그림 2 시간이 많이 걸리는 전송 트래픽 스플라이싱 모니터링
(2) 프로파일러 성능 분석
시간이 많이 걸리는 관리는 비즈니스 코드를 침해하고 성능에 영향을 미칠 수 있습니다. 따라서 이를 초과해서는 안 되며, 주요 프로세스를 모니터링하는 데 더 적합합니다. 해당 프로파일러 성능 분석 도구(예: Async-profiler)는 보다 구체적인 호출 트리와 각 기능의 CPU 사용량 비율을 생성하여 중요한 경로와 성능 병목 현상을 분석하고 찾는 데 도움을 줍니다.
그림 3 스플라이싱 호출 트리 및 CPU 비율
그림 3에서 볼 수 있듯이 스플라이싱 솔루션(combineTransferLines)이 53.80%를 차지하고 쿼리 생성 라인 데이터(querySegmentCacheable, 캐시 사용)가 21.45%. 스플라이싱 기법에서는 스킴 점수 계산(computeTripScore, 48.22% 차지), 스킴 엔터티 생성(buildTripBO, 4.61% 차지), 스플라이싱 타당성 확인(checkCombineMatchCondition, 0.91% 차지)이 가장 큰 3대 링크이다.
그림 4 솔루션 점수 호출 트리 및 CPU 비율
계산 계획 점수(computeTripScore)를 가장 높은 비율로 분석한 결과 직접 호출(계획 점수 세부 정보를 표시하는 데 사용)을 포함하여 주로 사용자 지정 문자열 서식 지정 기능(StringUtils.format)과 관련이 있다는 사실을 발견했으며, getTripId 호출(구성표를 생성하는 데 사용되는 ID)을 통한 간접 호출. 사용자 정의된 StringUtils.format의 가장 높은 비율은 java/lang/String.replace입니다. Java 8의 기본 문자열 대체는 정규 표현식을 통해 구현되는데, 이는 상대적으로 비효율적입니다(이 문제는 Java 9 이후에 개선되었습니다).
// 计算方案评分(computeTripScore) 中调用的StringUtils.format代码示例 StringUtils.format("AAAA-{0},BBBB-{1},CCCC-{2},DDDD-{3},EEEE-{4},FFFF-{5},GGGG-{6},HHHH-{7},IIII-{8},JJJJ-{9}", aaaa, bbbb, cccc, dddd, eeee, ffff, gggg, hhhh, iiii, jjjj) // getTripId 中调用StringUtils.format代码示例 StringUtils.format("{0}_{1}_{2}_{3}_{4}_{5}_{6}", aaaa, bbbb, cccc, dddd, eeee, ffff) // 通过Java replace实现的自定义format函数 public static String format(String template, Object... parameters) { for (int i = 0; i < parameters.length; i++) { template = template.replace("{" + i + "}", parameters[i] + ""); } return template; }
(3) 벤치마크 벤치마크 테스트
벤치마크 벤치마크 도구의 도움으로 코드의 실행 시간을 보다 정확하게 측정할 수 있습니다. 표 1에서는 JMH(Java Microbenchmark Harness)를 사용하여 세 가지 문자열 형식 지정 방법과 한 가지 문자열 접합 방법에 대해 시간이 많이 걸리는 테스트를 수행합니다. 테스트 결과, Java8의 교체 메소드를 사용한 문자열 포맷팅이 가장 나쁜 성능을 보였으며, Apache의 문자열 스플라이싱 기능을 사용한 것이 가장 좋은 성능을 보였습니다.
표 1 문자열 서식 지정 및 접합 성능 비교
implementation |
평균 시간(us) 소모 1000회 실행 |
StringUtils .format은 Java8의 교체 |
1988.982 |
StringUtils.format이 Apache 교체 |
656을 사용하여 구현되었습니다. |
Java8에는 문자열이 함께 제공됩니다. 형식 |
1417.474 |
Apache의 StringUtils.join |
116.812 |
위 내용은 Ctrip 환승 운송 계획의 접합 성능 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!