2012-02-01 3 views
4

해시 역할을하는 원자 배열이있는 프로젝트에서 작업하고 있습니다. 사용자가 서버에 연결할 때마다 특정 값이 해시되고 해당 해시를 배열의 요소를 조회하는 색인으로 사용하고 해당 요소를 반환합니다. "외부 힘"(장기 실행 gen_server에 의해 처리되는)은이 배열을 변경할 수 있으므로 단순히 하드 코드 할 수는 없습니다. 내 문제는이 배열을 "호스팅"하는 방법입니다.배열 : 배열에 분산 작업

나의 첫 번째 구현은 배열 사본을 보관하고 요청한 사람에게 보낸 간단한 gen_server였습니다. 그런 다음 그것을 요구하는 프로세스는 그것을 통과하여 원하는 인덱스를 얻을 수 있습니다. 이 구현에는 사용 된 메모리의 양과 과도한 양이있었습니다.이 동일한 어레이의 사본이 너무 많이 떠 다니는 이유가 여기에 있습니다.

현재 구현에는이 배열의 상태를 처리하는 중앙 gen_server와 실제 요청을 처리하는 하위가 있습니다. 상태가 변경되면 중앙 gen_server가 자식을 업데이트합니다. 프로세스가 해쉬 결과를 찾고자 할 때, 프로세스는 인덱스 번호를 중앙 gen_server로 전송하고, 중앙 gen_server는 그 요청을 자식 중 하나에게 전달합니다. 자식은 "로컬"목록을 탐색하고 결과 아톰을 원래 프로세스로 되돌려 보냅니다.

현재 구현의 문제점은 트래픽이 많을 때 느려지 게된다는 것입니다. 나는 점점 더 많은 아이들을 사용하려고 노력해 왔지만 중앙 gen_server가 병목이라고 확신한다.

아무에게도 내 문제에 대한 더 나은 해결책에 대한 아이디어가 있습니까?

편집 : % s의/배열/목록/g

답변

6

ETS Tables을 사용하는 것이 좋습니다. Array 메서드가 충분히 효율적이지 않다고 생각합니다. ETS Table을 응용 프로그램 백엔드에서 공용으로 생성하면 필요한 모든 프로세스가 항목을 바로 조회 할 수 있습니다. 현재 최신 버전의 erlang에있는 ETS Tables에는 동시 액세스 기능이 있습니다.

%% Lets create a record structure 
%% where by the key will be a value 
%% in the array. 
%% For now, i do not know what to 
%% put in the field: 'other'
-record(element,{key,other}).
create_table(TableName)-> Options = [ named_table,set, public, {keypos,2}, %% coz we are using record NOT tuple {write_concurrency,true} ], case ets:new(TableName,Options) of TableName -> {success,true}; Error -> {error,Error} end.
lookup_by_hash(TableName,HashValue)-> try ets:lookup(TableName,HashValue) of Value -> {value,Value}; catch X:Y -> {error,{X,Y}} end.
이런 종류의 배열을 사용하면 데이터가있는 단일 gen_server에서 발생하는 A Single Point of Failure을 피할 수 있습니다. 이 데이터는 여러 프로세스에서 필요하므로 단일 프로세스에서 보유하지 않아야합니다. 그것은 어디서나 조회가 필요할 때마다 언제든지 접근 할 수있는 테이블입니다.

배열의 값을 element과 같은 형식의 레코드로 변환 한 다음 ETS Tables에 삽입해야합니다. 이 방법의

장점

1. 우리가 ETS 표는 목록 또는 훨씬 낮은 비교 메모리 소비 어레이로서 데이터 구조보다 더 많은 요소를 처리 할 수있는만큼 ETS Tables 2.
가능한 만들 수있다.
3. ETS Tables은 접근 할 수있는 모든 프로세스에서 동시에 액세스 할 수 있으므로 데이터를 처리하기 위해 중앙 프로세스 또는 서버가 필요하지 않습니다.
4.이 데이터를 보유하는 단일 프로세스 또는 gen_server는 해당 데이터가 손상된 경우 전체 메일 함)을 사용할 수 없으므로 배열을 필요로하는 프로세스는이 한 서버가 다시 시작될 때까지 기다려야합니다. 그렇지 않으면 알 수 없습니다.
5. 요청 메시지를 보내어 배열 데이터 액세스하기 동일한 어레이를 필요한 각 프로세스에 복사하는 것은 "얼랭 (Erlangic)"설계가 아닙니다.
6.마지막으로 ETS Tables 소유권을 프로세스간에 전송할 수 있습니다. 소유 프로세스가 중단되면 (gen_servers만이 죽어 가고 있음을 감지 할 수 있음) ETS Table을 다른 프로세스로 이전 할 수 있습니다. 여기에서 확인하십시오 : ETS Give Away

그건 제 생각입니다.

1

다른 모든 값이 도움이,하지만 당신은 (당신의 해시 사업에서 독립) 분산 해시 테이블의 중앙 해시 값을 관리 할 수 ​​있다면 확실하지 않음 ? 그렇게하면 여러 프로세스가 하나의 중앙 프로세스 대신로드 작업을 수행 할 수 있습니다.

내가 읽은 것으로부터 배열은 실제로 배열 일 필요는없는 것 같습니다.