>  기사  >  위챗 애플릿  >  libco가 엄청난 양의 데이터 정보를 지원하는 방법을 가르쳐주세요.

libco가 엄청난 양의 데이터 정보를 지원하는 방법을 가르쳐주세요.

Y2J
Y2J원래의
2017-05-11 11:53:362021검색

Ibco는 WeChat 백엔드에서 대규모로 사용되는 c/C++ 코루틴 라이브러리로, 2013년부터 WeChat 백엔드의 수만 대의 시스템에서 안정적으로 실행되고 있습니다. Libco는 Tencent의 6대 오픈 소스 프로젝트 중 하나로 2013년에 처음으로 오픈 소스화되었습니다. 최근 대규모 업데이트가 github.com/tencent/libco에 동기화되었습니다. libco는 백엔드 민첩한 동기화 스타일 프로그래밍 모델을 지원하는 동시에 시스템의 높은 동시성 기능을 제공합니다.

libco가 지원하는 기능

비즈니스 로직을 침범할 필요가 없으며 다중 프로세스 및 다중 스레드 서비스를 코루틴 서비스로 변환할 필요가 없으며 동시성 기능이 100배 향상됩니다.

CGI 프레임워크 지원, 웹 서비스 구축 용이(신규)

gethostbyname, mysqlclient, ssl과 같이 일반적으로 사용되는 세 번째 라이브러리 지원(신규)

선택 사항 공유 스택 모드, 독립형으로 쉽게 액세스 가능(신규)

완벽하고 간결한 코루틴 프로그래밍 인터페이스

- pthread와 유사한 인터페이스 디자인, co_create 및 co_resume과 같은 간단하고 명확한 인터페이스를 통해 코루틴 생성 및 복원 완료 – 스레드와 유사한 코루틴 전용 변수 , 코루틴 간 통신을 위한 코루틴 세마포 co_signal(신규) – 비언어 수준 람다 내부 코루틴과 결합된 구현(신규) – 시간 룰렛 타이머 기반의 고성능 타이머인 epoll/kqueue 기반의 작고 가벼운 네트워크 프레임워크; >
생성자: libco 배경

WeChat 백엔드 초기에는 복잡하고 변화하는 비즈니스 요구와 빠른 제품 반복으로 인해 대부분의 모듈이 반동기식 및 반비동기식
모델을 채택했습니다. . 액세스 계층은 비동기식 모델이고 비즈니스 논리 계층은 동기식 다중 프로세스 또는 다중 스레드 모델입니다. 비즈니스 논리의 동시성 기능은 수십에서 수백 개에 불과합니다. WeChat의 비즈니스가 성장함에 따라 시스템 규모는 점점 커지고 각 모듈은 백엔드 서비스/네트워크 지터의 영향을 받기 쉽습니다.
비동기 변환의 선택

WeChat 백엔드의 동시성 기능을 향상시키기 위한 일반적인 접근 방식은 기존 네트워크의 모든 서비스를 비동기 모델로 변경하는 것입니다. 이 접근 방식에는 프레임워크부터 비즈니스 로직 코드까지 엄청난 양의 작업이 필요하며, 이를 위해서는 시간이 많이 걸리고 노동 집약적이며 위험할 수 있는 완전한 변환이 필요합니다. 그래서 우리는 코루틴 사용에 대해 생각하기 시작했습니다.

그러나 코루틴을 사용하면 다음과 같은 문제에 직면하게 됩니다.

업계에서는 c/C++ 환경에서 코루틴을 대규모로 적용한 경험이 없습니다.

코루틴을 제어하는 ​​방법; 스케줄링;

 소켓, mysqlclient 등과 같은 동기화된 스타일
API 호출 처리 방법;
 기존 전역 변수 및 스레드 전용 변수 사용 처리 방법 ;

결국 우리는 libco를 통해 위의 모든 문제를 해결하고 비즈니스 로직의 비침해적 비동기 변환을 달성했습니다. 우리는 libco를 사용하여 수백 개의 WeChat 백엔드 모듈을 코루틴 및 비동기 변환으로 변환했습니다. 변환 프로세스 중에 비즈니스 로직 코드는 기본적으로 변경되지 않았습니다. 지금까지 WeChat 백엔드의 대부분의 서비스는 다중 프로세스 또는 다중 스레드 코루틴 모델입니다. 동시성 기능은 이전에 비해 질적으로 향상되었으며 libco는 WeChat 백엔드 프레임워크의 초석이 되었습니다.

 libco 프레임워크

Libco는 프레임워크에서 인터페이스 계층, 시스템
기능Hook 계층 및 이벤트드라이버의 세 가지 계층으로 나뉩니다. 레이어.

libco가 엄청난 양의 데이터 정보를 지원하는 방법을 가르쳐주세요.


동기식 API 처리

주로 동기식 네트워크 호출인 동기식 API의 경우 libco의 주요 작업은 이러한 대기로 인한 리소스 점유를 제거하고 시스템의 동시성 성능을 향상시키는 것입니다. 일반적인 네트워크 백그라운드 서비스의 경우 연결, 쓰기, 읽기 등의 단계를 거쳐 완전한 네트워크 상호 작용을 완료할 수 있습니다. 이러한 API를 동기식으로 호출하면 전체 스레드가 네트워크 상호 작용을 기다리면서 중단됩니다.

동기식 프로그래밍 스타일의 동시성 성능은 좋지 않지만 명확한 코드 논리, 쉬운 작성, 빠른 비즈니스 반복 및 민첩한 개발을 지원할 수 있다는 장점이 있습니다. 온라인에서 기존 비즈니스 로직 코드를 수정하지 않고 동기 프로그래밍의 장점을 계속 유지하기 위해 libco는 혁신적으로 네트워크 호출 인터페이스(Hook)를 인수하고 콜백을 통해 비동기 네트워크 IO에 코루틴 항복 및 복구를 이벤트로 등록했습니다. . 비즈니스 처리 중에 동기 네트워크 요청이 발생하면 libco 계층은 네트워크 요청을 비동기 이벤트로 등록합니다. 이 코루틴은 CPU 점유를 포기하고 CPU는 실행을 위해 다른 코루틴으로 넘겨집니다. Libco는 네트워크 이벤트가 발생하거나 시간 초과되면 자동으로 코루틴 실행을 재개합니다.

우리는 Hook 메서드를 통해 대부분의 동기화 스타일 API를 인계받았으며 libco는 적절한 시간에 실행을 재개하도록 코루틴을 예약합니다.

수천만 개의 코루틴 지원
기본적으로 libco는 각 코루틴이 자체 실행 스택을 갖도록 허용합니다. 코루틴이 생성되면 고정 크기 메모리가 실행 스택으로 힙 메모리에서 할당됩니다. 코루틴을 위해. 프런트 엔드에서 액세스 연결을 처리하기 위해 코루틴을 사용한다면 대규모 액세스 서비스의 경우 서비스의 동시성 제한은 메모리에 의해 쉽게 제한됩니다. 이를 위해 libco는 스택 없는 코루틴 공유 스택 모드도 제공합니다. 이를 통해 동일한 실행 스택을 공유하도록 여러 코루틴을 설정할 수 있습니다. 동일한 공유 스택 아래의 코루틴 간에 전환할 때 현재 실행 중인 스택 콘텐츠를 코루틴의 개인 메모리에 복사해야 합니다. 이러한 메모리 복사본 수를 줄이기 위해 공유 스택의 메모리 복사본은 서로 다른 코루틴 간에 전환할 때만 발생합니다. 공유 스택의 점유자가 변경되지 않은 경우 실행 중인 스택을 복사할 필요가 없습니다.

libco 코루틴의 공유 코루틴 스택 모드를 사용하면 충분한 코루틴을 생성하기만 하면 단일 시스템에서 수천만 개의 연결에 쉽게 액세스할 수 있습니다. libco 공유 스택 모드를 통해 1,000만 개의 코루틴(E5-2670 v3 @ 2.30GHz * 2, 128G 메모리)을 생성합니다. 각 100,000개의 코루틴은 128k 메모리를 사용하며 전체 echo 서비스는 안정적입니다. 약 66G입니다.
코루틴 프라이빗 변수
멀티 프로세스 프로그램을 멀티 스레드 프로그램으로 변환할 때 스레드를 사용하여 전역 변수를 빠르게 수정할 수 있습니다. 코루틴 환경에서는 코루틴 변수 ROUTINE_VAR을 생성하여 Reduce를 크게 단순화했습니다. 코루틴 변환의 작업량.
코루틴은 본질적으로 스레드 내에서 직렬로 실행되므로 스레드 전용 변수를 정의할 때 재진입 문제가 발생할 수 있습니다. 예를 들어, 스레드의 스레드 전용 변수를 정의하는 경우 원래는 각 실행 로직이 이 변수에 독점적으로 액세스할 수 있기를 원했습니다. 하지만 우리의 실행 환경을 코루틴으로 마이그레이션하면 동일한 스레드 전용 변수가 여러 코루틴에서 작동될 수 있어 변수 침입 문제가 발생할 수 있습니다. 이러한 이유로 우리는 libco의 비동기 변환을 수행할 때 대부분의 스레드 전용 변수를 코루틴 수준의 전용 변수로 변경했습니다. 코루틴 전용 변수에는 다음과 같은 특징이 있습니다. 코드가 다중 스레드 비코루틴 환경에서 실행되는 경우 변수는 스레드 전용입니다. 코드가 코루틴 환경에서 실행되는 경우 이 변수는 코루틴 전용입니다. 기본 코루틴 개인 변수는 실행 환경의 판단을 자동으로 완료하고 필요한 값을 올바르게 반환합니다.
코루틴 프라이빗 변수는 기존 환경을 동기화에서 비동기화로 전환하는 데 결정적인 역할을 합니다. 동시에 한 줄의 선언만큼 간단한 코루틴 프라이빗 변수를 정의하는 매우 간단하고 편리한 방법을 정의했습니다. 암호.
 gethostbyname의 후크 방법
기존 네트워크 서비스의 경우 시스템의 gethostbyname API 인터페이스를 통해 실제 주소를 얻으려면 DNS를 쿼리해야 할 수도 있습니다. 코루틴 변환 중에 우리 후크의 소켓 패밀리 기능이 gethostbyname에 적용되지 않는다는 것을 발견했습니다. 코루틴이 gethostbyname을 호출하면 결과를 동기적으로 기다리므로 동일한 스레드의 다른 코루틴이 실행이 지연됩니다. 우리는 glibc의 gethostbyname 소스 코드를 연구한 결과 주로 glibc가 일반 폴링 방법 대신 이벤트를 기다리는 폴링 방법을 정의하고 동시에 전환할 스레드 전용 변수를 정의하기 때문에 후크가 적용되지 않는다는 것을 발견했습니다. 다른 코루틴을 사용하면 데이터가 부정확해질 수 있습니다. 마지막으로, gethostbyname 코루틴의 비동기화는 Hook 폴링 방법과 코루틴 개인 변수 정의를 통해 해결됩니다.
Gethostbyname은 glibc에서 제공하는 동기식 쿼리 DNS 인터페이스입니다. 업계에는 gethostbyname에 대한 뛰어난 비동기 솔루션이 많이 있지만 이러한 구현에는 타사 라이브러리의 도입이 필요하며 기본 레이어에서 비동기 콜백 알림 메커니즘을 제공해야 합니다. . 후크 방법을 통해 libco는 glibc 소스 코드를 수정하지 않고 gethostbyname의 비동기화를 실현합니다.
코루틴 세마포
멀티 스레드 환경에서는 스레드 간 동기화가 필요합니다. 예를 들어 한 스레드의 실행은 다른 스레드의 신호를 기다려야 합니다. pthread_signal을 사용하여 해결하세요. libco에서는 코루틴 간의 동시성 요구 사항을 처리하기 위해 코루틴 세마포 co_signal을 정의합니다. 코루틴은 co_cond_signal 및 co_cond_broadcast를 통해 대기 중인 코루틴에 알리거나 대기 중인 모든 코루틴을 깨울지 결정할 수 있습니다.
요약
Libco는 완전한 코루틴 프로그래밍 인터페이스, 일반적으로 사용되는 소켓 계열 함수 Hook 등을 제공하는 효율적인 c/C++ 코루틴 라이브러리로, 기업이 신속한 반복 개발을 위해 동기식 프로그래밍 모델을 사용할 수 있도록 해줍니다. 지난 몇 년간 안정적인 운영을 통해 libco는 WeChat 백엔드 프레임워크의 초석으로서 중추적인 역할을 해왔습니다.

[관련 추천]

1. 위챗 공개 계정 플랫폼 소스코드 다운로드

알리지 주문 시스템 소스코드 무료 다운로드

위 내용은 libco가 엄청난 양의 데이터 정보를 지원하는 방법을 가르쳐주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.