여러 워커가 Redis를 통해 풀을 공유할 때 정렬된 집합은 간단한 정책을 구현할 수 있습니다. 기록된 할당이 가장 적은 적격 프록시를 고르는 것입니다. 프록시 식별자를 멤버로, 할당 횟수를 점수로 저장합니다.

허용된 공개 요청을 처리하는 풀이라면 무료 프록시 목록에서 엔드포인트 후보를 받아 해당 풀의 적격성 규칙으로 평가할 수 있습니다. 적격 멤버는 합의된 시작 횟수로 초기화합니다. 그다음 선택과 증가를 하나의 서버 측 작업으로 만듭니다.

local chosen = redis.call('ZRANGE', KEYS[1], 0, 0)[1]
if not chosen then
    return nil
end

redis.call('ZINCRBY', KEYS[1], 1, chosen)
return chosen

정렬된 집합의 키를 Redis 클라이언트의 EVAL 인터페이스로 스크립트의 유일한 키 인수로 전달합니다. 빈 풀은 null을 반환하므로 애플리케이션은 요청을 보내지 않고 처리해야 합니다.

왜 두 명령을 합치는가

읽기와 증가가 분리되면 두 워커가 어느 쪽도 갱신하기 전에 같은 최솟값을 볼 수 있습니다. Redis는 Lua 스크립트를 원자적으로 실행하므로 다른 워커가 이 스크립트의 읽기와 증가 사이에 선택을 끼워 넣을 수 없습니다. 실행 중에는 다른 Redis 작업을 막으므로 스크립트를 짧게 유지합니다.

ZRANGE는 가장 낮은 점수를 먼저 반환합니다. 같은 점수는 무작위가 아니라 멤버 순서로 해결됩니다. ZINCRBY는 선택된 멤버의 점수를 다음 할당을 위해 하나 올립니다.

점수의 의미를 정의하기

이것은 할당을 세며, 나중에 네트워크 요청이 실패하는 할당도 포함합니다. 지연 시간, 성공한 요청, 진행 중인 작업은 측정하지 않습니다. 유일한 적격 멤버가 반복해서 선택될 수 있으며, 스크립트는 그것을 배타적으로 예약하지 않습니다.

풀의 상태와 정책 규칙으로 적격성을 유지합니다. 멤버를 제거했다가 나중에 복원한다면 과거 횟수를 유지할지 결정합니다. 복원된 프록시를 0에서 시작하면 따라잡는 동안 할당이 그쪽에 몰릴 수 있습니다.

최소 동시성 정책에는 완료와 버려진 작업 처리를 포함한 다른 수명 주기가 필요합니다. 이 누적 카운터를 그 수명 주기로 해석하지 마십시오.

관련 글