들어가며Standalone Redis 하나에 연결할 때는 주로 연결 상태, 명령 대기 시간, 장애 시 처리 방식을 고려한다.Redis Cluster에서는 클라이언트가 어떤 노드에 명령을 보내야 하는지도 알아야 한다. 장애 조치나 슬롯 이동으로 담당 노드가 바뀌면, 오래된 정보를 가진 클라이언트는 이전 노드로 요청을 보낼 수 있다.이 글에서는 Lettuce의 Topology Refresh가 이런 변화에 어떻게 대응하는지 살펴본다. 이어서 연결이 끊겼을 때의 명령 처리 방식과 Timeout 설정도 함께 정리한다.1. Redis Cluster에서 클라이언트가 알아야 하는 정보Redis Cluster의 Key Space는 16,384개의 Hash Slot으로 나뉜다. 각 슬롯은 클러스터의 Primary 노드가 ..
들어가며최근 담당하고 있는 시스템에서 Caffeine을 이용한 로컬 캐시에서 Redis로의 전환 작업을 맡게 되었다.로컬 캐시는 애플리케이션 프로세스 내부의 메모리를 사용하기 때문에 구조가 단순하고 별도의 네트워크 통신도 필요하지 않다. 하지만 서버가 여러 대로 늘어나면 각 서버가 독립적인 캐시를 가지게 된다는 문제가 있다.Server A└── Local Cache └── employee:100 = AServer B└── Local Cache └── employee:100 = B같은 데이터를 캐싱하더라도 특정 서버에서 데이터를 변경하고 캐시를 갱신했을 때 다른 서버의 캐시에는 이전 데이터가 남아 있을 수 있다.이를 해결하기 위해 캐시 저장소를 Redis로 변경하면 여러 서버가 하나의 캐시를 공..
들어가며서비스를 개발하다 보면 위치를 기반으로 데이터를 검색해야 하는 경우가 있다.예를 들어 다음과 같은 기능들이다.현재 위치에서 3km 이내에 있는 음식점 찾기주변에 있는 배달 기사 찾기지도 화면 안에 존재하는 매장 조회특정 지역에서 발생한 주문 수 집계현재 위치와 가장 가까운 주유소 찾기각 데이터가 다음과 같이 위도와 경도를 가지고 있다고 가정해보자.사용자 A : (35.8714, 128.6014)사용자 B : (35.8682, 128.5932)사용자 C : (37.5665, 126.9780)...데이터가 몇 개 없다면 모든 데이터의 좌표를 읽어서 현재 위치와의 거리를 계산해도 큰 문제가 없다.현재 위치 ↓사용자 A와 거리 계산사용자 B와 거리 계산사용자 C와 거리 계산...하지만 위치 데이터가..
문자열 데이터를 다루다 보면 단순한 LIKE만으로는 처리하기 어려운 경우가 있다.예를 들어 다음과 같은 작업이다.문자열이 숫자로만 구성되어 있는지 검사이메일과 비슷한 형식인지 검사문자열에서 숫자만 제거하거나 추출쉼표로 구분된 문자열에서 특정 번째 값 추출특정 패턴이 문자열에 몇 번 등장하는지 계산Oracle에서는 이러한 작업을 위해 REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_COUNT와 같은 정규표현식 함수를 제공한다.1. 정규표현식 기본 패턴정규표현식은 일반 문자와 특별한 의미를 갖는 메타 문자를 조합해 문자열의 패턴을 표현한다.예를 들어 [0-9]+는 숫자가 1개 이상 연속되는 문자열을 의미하고,^[0-9]+$는 문자열 전체가 ..
실행 계획을 보다 보면 SORT AGGREGATE, SORT ORDER BY, SORT GROUP BY, SORT UNIQUE와 같은 Sort 오퍼레이션을 자주 볼 수 있다.모두 이름에 Sort가 들어가지만 역할은 서로 다르다. 어떤 오퍼레이션은 실제 정렬을 수행하고, 어떤 오퍼레이션은 이름과 달리 정렬을 수행하지 않는다.이번 글에서는 각 Sort 오퍼레이션이 언제 발생하는지와 내부 동작을 그림과 함께 정리해보자.1. SORT AGGREGATE전체 로우를 대상으로 하나의 집계 결과를 만들 때 발생한다.이름에 Sort가 포함되어 있지만 실제 정렬은 수행하지 않는다.SELECT SUM(sal), MAX(sal), MIN(sal)FROM emp;동작 흐름EMP │ ▼모든 Row 읽기 │ ..
SQL 튜닝을 하다 보면 IN 조건을 자주 사용한다.WHERE status IN ('PAID', 'READY', 'DONE')겉으로 보면 단순히 여러 값을 비교하는 조건처럼 보인다.하지만 실행계획 관점에서 보면 IN 조건은 생각보다 중요한 차이를 만든다.특히 Oracle에서는 INLIST ITERATOR라는 실행 방식으로 나타날 수 있고, 이 경우 IN 목록의 각 값을 기준으로 인덱스를 반복 탐색한다. 반대로 어떤 경우에는 IN 조건이 인덱스 탐색 범위를 만드는 데 사용되지 않고, 이미 읽은 데이터에 대해 값이 맞는지 확인하는 filter 조건으로 사용되기도 한다.이 글에서는 IN 조건이 인덱스에서 어떻게 동작하는지, 그리고 왜 항상 INLIST ITERATOR가 좋은 것은 아닌지 정리한다. 1. IN..
들어가며서비스를 개발하다 보면 거의 모든 데이터에 ID가 필요하다.예를 들어 다음과 같은 데이터들은 대부분 고유한 식별자를 가진다.회원 ID주문 ID게시글 ID댓글 ID결제 ID단일 서버와 단일 데이터베이스만 사용하는 환경에서는 ID 생성이 비교적 단순하다. 데이터베이스의 AUTO_INCREMENT나 SEQUENCE를 사용하면 된다.User Tableid | name---|------1 | Kim2 | Lee3 | Park하지만 시스템 규모가 커지면 상황이 달라진다.서버가 여러 대로 늘어나고, 데이터베이스가 샤딩되고, 여러 지역의 데이터센터에서 동시에 요청을 처리해야 한다면 단순히 숫자를 1씩 증가시키는 방식만으로는 충분하지 않을 수 있다.Server A ─┐Server B ─┼──> ID 생성Se..
어떤 값이 집합에 "있을 수도 있음 / 없음은 확실함"을 매우 빠르고 메모리 효율적으로 판단하기 위한 확률적 자료 구조이다.1. 목적존재 여부 검사를 빠르게 하기 위함정확성보다 속도와 메모리 효율을 우선대표적인 사용 목적캐시 Penetration 방지존재 가능한 키만 Bloom Filter에 미리 등록요청 키가 Bloom Filter에서 없음이면 Cache / DB 접근 자체를 차단존재하지 않는 ID에 대한 반복 DB 조회 방지 및 봇·악성 트래픽 방어중복 요청 차단이미 처리된 요청 ID를 Bloom Filter에 기록하여 요청이 다시 들어올 경우 "이미 처리됨"으로 간주멱등성 보조 수단 및 결제, 메세지 발송 중복 방지 (정확성이 중요한 경우 단독 사용은 부적합) 크롤러의 URL 중복 방문 방지방문한 ..