동시성 처리하기 2

JaeGu Jeong·2024년 2월 29일
0

동시성 처리하기

목록 보기
2/2

https://velog.io/@jay13jeong/동시성-처리하기

코드 최적화 하기

기존 코드는 synchronized 사용하면서 스레드마다 병목이 생겨서 유저가 많아질 수록 응답시간이 매우 낮아 졌습니다.

ConcurrentHashMap는 Lock Striping이라는 분할 잠금방식을 채택하고 있습니다. 공유자원을 완전히 잠그지 않고 병렬로 일부만 잠가서 성능을 높인 자료구조입니다.

이번엔 synchronized블록을 제거하고 ConcurrentHashMap의 add가 성공하면 true 실패하면 false를 반환하는 특징을 사용하여 최적화를 해보겠습니다.

private final Database db;
private final static Set<Long> depositingUsers = ConcurrentHashMap.newKeySet();

public Mileage postMileage(Long id, Long mileage) {
    Mileage result;
    if (!depositingUsers.add(id)){
        return null;
    }
    result = db.postMileage(id, mileage);
    try {
        Thread.sleep(10000L);
    } catch (Exception e){
        //err logger
        return null;
    } finally {
        depositingUsers.remove(id);
    }
    return result;
}

동시성 테스트 기록

테스트 방식은 이전과 동일합니다.
이번에도 ExecutorService와 CountDownLatch를 사용하여 테스트 하였습니다.
측정 시간은 스레드를 모두 생성 후 Latch를 풀기 직전부터 스레드가 모두 종료 순간까지 입니다.
오차범위는 500ms입니다.
기대값은 각 유저당 요청 1개 성공과 나머지 실패입니다.

요청 10000개씩 2명 테스트 성공 / 10초

요청 1000개씩 20명 테스트 성공 / 15초

요청 100개씩 200명 테스트 성공 / 15초

요청 5개씩 4000명 테스트 성공 / 19초

요청 3개씩 8000명 테스트 성공 / 26초

요청 2개씩 15000명 테스트 성공 / 47초

최적화 성공

Deduplication을 확실하게 하기위해서 스레드 대기시간을 10000ms까지 늘렸습니다.
작은 테스트에서는 시간이 조금 늘어 났지만 큰 규모에서 보았을 때 확실히 성과가 나타났습니다.
Lock Striping기능을 적극 활용하면서 성능이 기존에 비해 2배이상 최적화 되었습니다.
테스트 유저수가 많아질수록 체감이 더 커집니다.

profile
BackEnd Developer

0개의 댓글