생에 첫 삼치 낚시
친구가 빠진 자리에 급히 끼어 생애 첫 선상낚시를 하러 새벽 3시 반에 일어나 경주까지 가서 배에 올랐더니 한동안은 나만 조용했지만 이내 쏟아져 나와 결국 친구와 합쳐 대략 34마리의 삼치를 잡았다. 대구 돌아와 황리단길도 잠깐 거닐고 사우나로 몸을 풀고 유튜브 보며 8마리를 손질해 구워 먹으니 담백하게 맛있었고, 새벽 기상은 충분히 값진 경험이었다.
만들고, 고치고, 배우는 것들을 짧은 글로 남길려고 합니다.
22
친구가 빠진 자리에 급히 끼어 생애 첫 선상낚시를 하러 새벽 3시 반에 일어나 경주까지 가서 배에 올랐더니 한동안은 나만 조용했지만 이내 쏟아져 나와 결국 친구와 합쳐 대략 34마리의 삼치를 잡았다. 대구 돌아와 황리단길도 잠깐 거닐고 사우나로 몸을 풀고 유튜브 보며 8마리를 손질해 구워 먹으니 담백하게 맛있었고, 새벽 기상은 충분히 값진 경험이었다.
Redis를 그냥 '빠른 캐시'로 보면 편하지만, Cache Aside·TTL·캐시 만료 동시성, Negative Caching, 메모리 정책, 복구 방식, 복잡해지는 분산 락 등 쓰면서 맞닥뜨리는 여러 문제를 함께 고려해야 하는 것이 핵심 주제입니다. 글은 DB로 해결할 수 있는 부분은 DB에 맡기고, Redis를 도입할 때는 얻는 이득과 새로 생길 비용을 현실적으로 따져야 한다고 조용히 짚어준다.
멀티스레드에서 변수 접근을 다루며 volatile, synchronized, AtomicInteger가 각각 무엇을 보장하고 어떤 한계가 있는지를 짚습니다. volatile은 가시성·순서만, synchronized는 상호 배제로 복합 연산을 보호하고, AtomicInteger는 CAS로 원자적 증감만 제공하니 문제의 성격(가시성인지 원자성인지)을 먼저 가려야 합니다.
서비스는 처음엔 한 대의 서버와 DB로 시작하지만, 트래픽과 요구가 커지며 세션 공유, 캐시 일관성, 읽기/쓰기 분산, 트랜잭션 일관성, 서비스 간 결합도 같은 현실적 문제를 해결하려다 보니 Redis, Replica, Sharding, Kafka 같은 구성으로 자연스럽게 복잡해진다. 이런 변화들은 기술 이름을 외우기보다 "무슨 문제가 생겼고 그걸 왜 이렇게 풀었나"를 이해하는 게 핵심이라는, 약간 골치 아프지만 당연한 결론으로 이어진다.
주문을 DB에 저장한 뒤 곧바로 Kafka에 이벤트를 발행할 때 서버가 죽으면 DB에는 남고 Kafka에는 전달되지 않는 문제가 생기는데, 이는 DB와 Kafka가 같은 트랜잭션으로 묶일 수 없기 때문입니다. Outbox 패턴은 같은 DB 트랜잭션 안에 이벤트를 기록해 별도 Publisher가 나중에 Kafka로 발행하게 함으로써 이벤트 유실을 줄이되, 중복 처리(멱등성)는 여전히 고려해야 한다는 현실적인 해결책을 제시합니다.