[상단] 높은 동시 서버 설계 - 메모리 풀 설계

4530 단어 서버
서로 다른 업무, 디자인도 모두 같지 않지만, 적어도 모두 공통된 추구, 예를 들어 성능 등이다.
서버 개발을 한 지 여러 해가 되었는데, 때때로 서버 성능이 무엇입니까?각종 서버 간의 조합은 무엇입니까?
간단한 대답은 QPS, 병렬 숫자지만, 때로는 생각해도 틀릴 수도 있다.
QPS와 병렬 수는 같은 업무에 대한 것이기 때문에 업무에 따라 같은 서버가 감당할 수 있는 압력도 다르다.
성능은 다음과 같은 일반적인 예를 들 수 있습니다.
서버는 한 척의 배이고, 성능은 배의 용량이며, 운전하는 속도는 안정적으로 진행되는가이다.
쓸 것은 쓰고, 절약할 것은 절약하다.메모리를 사용할 수 있다면 IO를 사용하지 마라. CPU는 적게 사용할 수 있으면 적게 사용한다. 같은 QPS는 CPU와 메모리를 적게 사용하는 성능이 많이 사용하는 것보다 낫다. 마찬가지로 QPS를 많이 달리는 것은
CPU와 메모리를 조금 더 써도 작은 속도로 달리는 성능이 좋다.
무엇이 성능의 보장입니까?
효율적인 이벤트 모델, 간단명료한 업무 구조, 통일되고 안정적인 자원 관리, 그리고 숙련된 인원.
자원부터 얘기하자.
자원의 대부분은 IO와 관련이 있습니다. 만약에 제 앞의 글을 보셨다면 연결 탱크에 낯설지 않을 것입니다. 그렇습니다. 연결은 시스템의 IO 자원입니다. 다음은 또 다른 IO 자원: 메모리를 보십시오.
만약apache,nginx 같은 서버의 코드를 보거나 착수하고 싶다면 대부분 메모리 관리부터 시작해야 한다.
서버의 성능과 밀접한 관계가 있고 메모리 탱크의 디자인도 신속함과 안정을 추구한다. 생명주기는 일반적으로 다음과 같은 세 가지가 있다.
글로벌: 전체 프로세스의 전역 정보를 저장하는 전역 메모리입니다.
conn: 모든 연결의 정보, 연결에서 닫기까지.
busi: 업무 관련 정보는 모든 업무의 발생과 함께 끝날 때까지
다음은 간단한 메모리 풀을 정의합니다.
typedef struct yumei_mem_buf_s yumei_mem_buf_t;

typedef struct yumei_mem_pool_s yumei_mem_pool_t;



struct yumei_mem_buf_s

{

	int                          size;

	char                        *pos;

	char                        *start;

	yumei_mem_pool_t            *pool;

};



struct yumei_mem_pool_s

{

	int                          size;

	char                        *data;

	char                        *last;

	yumei_mem_pool_t            *next;

	yumei_mem_pool_t            *current;

};



yumei_mem_pool_t* yumei_mem_pool_create( int block_size, int block_num );

int yumei_mem_pool_free( yumei_mem_pool_t  *pool );

yumei_mem_buf_t* yumei_mem_malloc( yumei_mem_pool_t   *pool, int size );

int yumei_mem_buf_free( yumei_mem_buf_t *buf );


모든 연결이 시작될 때 연결이 유일한 메모리 탱크를 만들고 IO 데이터를 저장하며 새로운 업무를 만들 때 업무 메모리 탱크를 만들고 업무 처리가 끝날 때 메모리 탱크를 방출합니다.
typedef struct yumei_busi_s yumei_busi_t;



struct yumei_busi_s

{

	yumei_mem_pool_t      *pool;

	...

	...



}



#define yumei_BUSI_MEM_BLOCL_SIZE 512

#define yumei_BUSI_MEM_BLOCK_NUM  32



yumei_busi_t* yumei_busi_create()

{

	yumei_busi_t* busi;

	yumei_pool_t* pool;

	yumei_mem_buf_t* buf;

	int size;



	pool = yumei_mem_pool_create( yumei_BUSI_MEM_BLOCL_SIZE, yumei_BUSI_MEM_BLOCK_NUM );

	if( !pool ){

		return 0;

	}



	size = sizeof( yumei_busi_t );

	buf = yumei_mem_buf_malloc( pool, size );



	if( !buf ){

		yumei_mem_pool_free( pool );

		return 0;

	}



	busi = buf->data;



	return busi;



}



#define YUMEI_BUSI_ERROR -1

#define YUMEI_BUSI_OK     0



int yumei_busi_free( yumei_busi_t* busi )

{

	if( !busi ){

		return YUMEI_BUSI_ERROR;

	}



	yumei_mem_pool_free( busi->pool );



	return YUMEI_BUSI_OK;

}

어떤 때는 업무가 비교적 간단하다. 하나의 연결이 하나의 업무나 여러 업무에 대응하는 것은 병행 집행이 아니다. 이런 상황에서 업무 메모리 탱크가 필요하지 않고 직접 메모리 탱크를 연결할 수 있다.
yumei_busi_t* yumei_busi_create( yumei_conn_t* conn )

{

	yumei_busi_t* busi;

	yumei_pool_t* pool;

	yumei_mem_buf_t* buf;

	int size;



	pool = conn->pool;

	if( !pool ){

		retur 0;

	}



	size = sizeof( yumei_busi_t );

	buf = yumei_mem_buf_malloc( pool, size );



	if( !buf ){

		yumei_mem_pool_free( pool );

		return 0;

	}



	busi = buf->data;



	return busi;



}



#define YUMEI_CONN_ERROR -1

#define YUMEI_CONN_OK     0



int yumei_conn_close( yumei_conn_t* conn )

{

	if( !conn ){

		return YUMEI_CONN_ERROR;

	}



	yumei_mem_pool_free( conn->pool );



	return YUMEI_CONN_OK;

}


메모리 탱크가 어떻게 사용되는지 알고 내부 디자인을 다시 봅시다.pool의 네 가지 요소에서size대응block_크기, 데이터와last는 각각 블록의 시작 주소와 분배 가능한 주소,next와current는 각각 다음 블록 메모리 탱크와 현재 사용 가능한 메모리 탱크에 대응합니다.
일부 통용되는 서버에서는 또 다른 요소인 large를 볼 수 있다.이것은 일부 큰 메모리에 대한 분배를 다투는 것이다. 업무가 도대체 얼마나 큰 메모리를 필요로 하는지 알 수 없을 때 large는 왕왕 필수적이다. 이렇게 하면 메모리 탱크 구조가 이렇게 된다.
typedef struct yumei_mem_large_s yumei_mem_large_t;



struct yumei_mem_large_s

{

	char                      *data;

	int                        size;

	yumei_mem_large_t         *next;

}



struct yumei_mem_pool_s

{

	int                          size;

	char                        *data;

	char                        *last;

	yumei_mem_pool_t            *next;

	yumei_mem_pool_t            *current;

	yumei_mem_large_t           *large;

};

일부 특수한 업무, 예를 들어 업무에서 사용하는 메모리 크기가 모두 고정되고 비슷할 때 메모리 탱크는 고정 크기의 메모리 관리로 축소된다. 사실은 매우 간단하다. 이런 메모리 탱크는 연결에 연결할 수 있고 다 사용하면 방출하지 않고 다음 연결을 남겨 두고 다시 사용하면 비용을 더욱 절약할 수 있다.

좋은 웹페이지 즐겨찾기