5장. 안정 해시 설계 수평적 규모 확장성을 달성하기 위해서 요청 / 데이터를 서버에 균등하게 분포하는 것은 중요한 일이다. 이 작업은 '안정 해시'로 구현될 수 있다. 해시 키 재배치(Rehash) 문제 N개의 캐시 서버가 있을 때, 서버들에 균등히 부하를 나누는 보편적인 방법은 아래의 해시 함수를 사용하는 것이다. serverIndex = hash(key) % N (N은 서버의 개수) 이 방법으로 해시키를 분배할 경우 초기에는 균등히 분배되지만, 서버가 추가/삭제 되었을 때 많은 해시 키가 재배치 된다. 4대의 서버가 3대의 서버로 줄었을 때를 가정하면 아래 결과를 볼 수 있다. 키 해시 해시 % 4 해시 % 3 key0 18358617 1 0 key1 26143584 0 0 key2 18131146..
Effective Java : 아이템 73. 추상화 수준에 맞는 예외를 던져라. 저수준 예외는 고수준 예외로 변경(예외번역)해서 상위 계층으로 던져야 함. 현재 계층의 저수준 예외가 상위 계층으로 던져지면, 현재 계층의 내부 구현이 상위 계층을 오염시킴. 예외 번역 시, 저수준 예외가 디버깅에 도움이 된다면 예외 연쇄를 사용. 저수준 예외는 고수준 예외로 변경 저수준 예외를 고수준으로 추상화해서 상위 계층으로 던져야 한다. 그렇지 않으면 하위 계층의 내부 구현을 상위 계층이 알게 된다. 이 말은 상위 계층이 하위 계층의 내부 구현을 알고 적절히 대응해야 하는 것을 의미한다. 클래스 간의 의존성이 높아지는 방향이기 때문에 지양해야 한다. 일반적으로 예외 번역은 이런 식으로 사용할 수 있다. // 하위 계층..
Effective Java : 아이템 49. 매개변수가 유효한지 검사하라. 메서드가 시작할 때 매개변수 유효성 검사를 해라. 만약 여기서 오류를 잡지 못하면, 메서드 내에서 알 수 없는 에러가 발생하거나 이상한 객체가 만들어져 다른 메서드에 예외를 발생시킬 수 있다. 공개 API는 매개변수 유효성 검사에 실패했을 때 발생할 수 있는 에러와 조건을 문서화 해야함. (@throws 태그) private API에는 반드시 유효한 값만 전달되도록 개발자가 직접 작성해야 함. 이것을 전제로 assert 문으로 처리할 수 있음. assert 문은 일반적으로는 런타임에서 무시됨. (성능 영향 없음) 필요한 경우 java -ea로 활성화 할 수 있음. 나중에 사용할 값을 매개변수로 받는 경우, 매개변수 유효성 검사를 ..
들어가기 전 조회수는 별거 아닌 기능인 것처럼 생각되지만, 이번에 구현해보려고 할 때 정말 어려운 작업이라는 것을 느꼈다. 특히 다음 관점에서 어렵다. 아래에서는 여러 버전을 구현하고 테스트 하면서 결론을 하나씩 정리해보고자 한다. 동시성 문제 실시간 반영성 문제 정확성 문제 요구 사항 가능한 실시간으로 업데이트 되어야 함. 한 명이 하나의 가게를 하루에 여러 번 조회해도 가게의 조회수는 단 한 번만 증가해야 함. 조회수 기능이 동작하지 않더라도 어플리케이션은 동작해야 함. 내가 구현한 조회수 기능의 요구 사항은 다음과 같다. 결과 검증 코드 많은 요청이 동시에 들어왔을 때 발생할 수 있는 동시성 문제 / 성능 문제를 확인하기 위해 아래 파이썬 코드를 이용했다. aiohttp와 asyncio를 이용해 비..
Effective Java : 아이템 45. 스트림은 주의해서 사용하라. 스트림과 For문을 적절히 사용하는 것이 베스트 케이스다. 극단적으로 스트림만 쓰거나, For문만 쓰는 경우는 지양하자. 스트림은 지연 평가됨. 스트림 최초 원소와 최종 연산에 참여하는 원소는 다를 수 있음. 스트림 내에서는 함수 객체(람다, 메서드 참조)를 주로 사용한다. 함수 객체는 타입이 주로 생략되므로 가독성을 위해 매개변수 이름을 잘 지어야 함. 도우미 메서드를 적절히 활용하는 것은 함수 객체(스트림쪽)에서 도움됨. 너무 어려운 코드라면 하나의 도우미 함수로 빼서 가독성을 올릴 수 있음. char 타입을 처리할 때는 Stream을 사용하지 말자. 스트림에서 처음에 사용된 원소였으나 최종 연산에서 사용할 수 없게 된 경우, ..