docker exec -i my-redis redis-cli -x FUNCTION LOAD REPLACE < coupon_logic.lua 위의 기존 코드를 실행시키면 NOAUTH Authentication required 라는 오류가 발생합니다. 이 경우에는 docker exec -i my-redis redis-cli -a <비밀번호> -x FUNCTION LOAD REPLACE < coupon_logic.lua 와 같은 형식으로 입력하시면 정상 등록됩니다. 경고가 뜨긴 하는데 커맨드라인에 비밀번호를 직접 입력하지 말라고 하는거네요.
안녕하세요. 좋은 강의 감사합니다! docker container로 redis 실습 중 모든 키가 제거되고 backup1,backup2 와 같은 키가 남아있는 현상을 확인했는데 서칭 결과 크롤링 봇에 의한 해킹이라고 진단했습니다. 해킹 원인은 public ip를 사용하는 pc에서 포트를 ip 제한 없이 열어서 그런 것으로 추측했습니다. 그래서 기존 컨테이너 생성 코드 container run --name my-redis -p 6379:6379 redis 에서 docker run -d \ --name my-secure-redis \ -p 127.0.0.1:6379:6379 \ --restart always \ redis:latest \ redis-server --requirepass "비밀번호" --appendonly yes 로 변경하여 local ip 지정 뿐만 아니라 권한 설정, 데이터 백업 등이 설정 된 새로운 컨테이너를 생성했습니다. 수정 후 지금까지는 키가 삭제 현상이 다시 나타나지 않았는데 혹시 잘못된 부분이 있으면 지적 부탁 드립니다. 감사합니다!
강의 내용을 듣고 생각했을때 , 대부분의 경우 Redis String 보다 Redis Hash 사용하는게 대부분 이득일것 같다 생각이 들던데... 어떻게 사용하고 계시나요 ?? 사실 저는 Redis String 으로 Json 으로 많이 사용했었습니다. 그리고 큰 장애를 경험하지 못했는데요 아무래도 트래픽에 대한 차이인것 같네요
최근에 Redis 의 개발사가 라이선스 정책을 변경하면서, 더 이상 완전한 무료 오픈소스로 부르기 애매해지는 사건이 있었습니다. 이에 반발한 AWS, 구글 등 빅테크 기업들이 모인 Linux Foundation 에서 기존 Redis 코드를 그대로 복사해서(포크해서) 만든 진짜 100% 무료 오픈소스가 바로 Valkey 입니다. 라고 제미나이가 그러던데... 요즘은 Valkey를 선택하는 게 대세인가요?
수업 예시에서는 외부 api가 실패할 경우 스케쥴러를 활용해서 후보정 로직을 통하여 결과적 일관성을 맞추고 있습니다. 만약에 자리를 지정하는 콘서트를 위와 같이 처리할 경우 (예약은 성공, 외부 api는 실패), 후보정 로직이 동작하기 전 다른 예약 시스템에서 해당 자리를 예약한 경우 더욱 큰 문제가 발생할 수 있을 것으로 보입니다. 이러한 경우 (좌석처럼 한정된 자원을 예약하는 경우), 외부 API 실패 시 후보정 로직을 통한 비동기 처리 대신 동기적으로 처리하는 것이 올바른 방식인 것 같은데, 강사님은 어떻게 생각하시는지 궁금합니다!
m=32MB짜리 10개와 m=512MB짜리 1개의 경우를 비교해주셨습니다. 그런데 이는 샤딩을 통해서 메모리 효율적으로 됐다기 보다는 메모리 총량이 512MB->320MB로 감소했기 때문에 오차율이 조금 증가하는 대신 메모리를 덜 쓸 수 있는 것 아닌가요? 예를 들어 320MB 짜리 1개인 경우와 32MB짜리 10개인 경우의 오차율이 똑같지 않나 하는 생각이 들어서 질문드립니다!
@Slf4j @SpringBootTest class SplitBloomFilterRedisHandlerTest extends RedisTestContainerSupport { @Autowired SplitBloomFilterRedisHandler splitBloomFilterRedisHandler; @Test void mightContain() { SplitBloomFilter splitBloomFilter = SplitBloomFilter.create("testId", 1000, 0.01); List<String> values = IntStream.range(0, 1000).mapToObj(idx -> "value" + idx).toList(); for (String value : values) { splitBloomFilterRedisHandler.add(splitBloomFilter, value); } for (String value : values) { boolean result = splitBloomFilterRedisHandler.mightContain(splitBloomFilter, value); assertThat(result).isTrue(); } for (int i = 0; i < 1000; i++) { String value = "notAddedValue" + i; boolean result = splitBloomFilterRedisHandler.mightContain(splitBloomFilter, value); if (result) { log.info("value={}", value); } } } } 위 코드는 SplitBloomFilterRedisHandlerTest 인데요. 강의 중 코드입니다 1000 크기에 0.01 오차율의 Bloom Filter 를 만들고 1000개의 데이터를 넣고 False Positive 까지 검증해보는 코드인데요. 질문입니다 Split 전략을 배우기 전에 순수한 Bloom Filter 구현 강의에서도 위와 동일한 테스트 코드가 있는데요 이 때, 순수한 Bloom Filter 의 한계로써 생성한 Bloom Filter 크기를 초과하여 데이터를 넣으면 비트 1이 많아져 오차율이 증가하고 그로 인해 False Positive 데이터가 많이 조회되는 현상을 살펴보거든요. 그리고 그 해결책으로 처음부터 큰 Bloom Filter 를 만드는 것 이외에 Split / Sharding / Sub Filter 전략이라고 말씀하시는데요 근데 위 Split 전략의 테스트 코드에서 BloomFilter 크기는 1000으로 만들고 데이터를 훨씬 초과하여 2000개 만들어 넣어보면 순수한 Bloom Filter 때처럼 False Positive 데이터가 많이 조회됩니다. 저는 PC 가 느려서 False Positive 를 1000번으로 조회하였고 오차율 (0.01) 에 의하면 약 10개의 False Positive 가 나와야 하는데 데이터 1000개를 저장했을 때는 오차율에 맞게 8개로 떨어지는데 데이터 2000개를 저장했을 때는 오차율을 훨씬 넘어갑니다 제가 코드를 잘못 따라 친건지.. Split 도 원래 그런건지.. 제 질문 의미가 전달될지는 모르겠지만.. 명확하게 개념 정리가 되지 않아 질문드립니다
안녕하세요. 게시판 관련 강의를 듣는 도중 궁금한 점이 있어 질문을 남깁니다. 강의에서는 Snowflake 기반 단순 정렬을 기준으로 커버링 인덱스를 설명해주셨는데요, 실무에서는 여러 정렬 조건과 필터, 검색 조건이 함께 붙는 경우가 많습니다. ✅ 이런 복합적인 조회 패턴에서도 커버링 인덱스를 중심으로 설계하는 것이 적절한지, 아니면 다른 전략을 어떻게 사용해야 하는지 궁금합니다.(설명이 길어질 경우 간단한 힌트라도 부탁드립니다.) 💥 걱정하는 부분 정렬되는 컬럼 전부에 대해 인덱스를 걸면 더 문제가 발생할 것 같아요. 검색 %검색어% 의 경우에는 결국엔 full_scan 이어서 성능 최적화가 불가능하다.
강의를 보다가 궁금한 부분들이 생겨 질문드립니다!! 1. RateLimit Boundary Burst 관련 RateLimit을 설명해주시는 부분을 보면서 한 가지 의문이 들었습니다. 예를 들어 1초에 100개로 제한을 두었을 때, 0.9초 시점에 100개 요청이 들어오고 1초가 되자마자 다시 100개가 들어온다면 실제로는 매우 짧은 시간 안에 200개의 요청이 처리될 수 있지 않을까 하는 생각이 들었습니다. 찾아보니 이러한 문제를 Boundary Burst 라고 부른다는 것을 알게 되었습니다. 이를 해결하기 위해: Sliding Window Sliding Window Counter Token Bucket Leaky Bucket 등의 방식이 있다는 것을 확인했습니다. 실무 관점에서는 이런 경계 구간 Burst 문제를 어떤 방식으로 해결하는지 궁금합니다. 2. Request Collapsing 관련 Request Collapsing을 설명해주신 부분을 보면서, 여러 요청을 하나로 모아서 처리하는 방식으로 Golang의 SingleFlight 패턴을 응용하는 방법도 가능하지 않을까 생각해보았습니다. 이와 관련해서 아래와 같은 예제 코드도 작성해 보았습니다. private final StringRedisTemplate redisTemplate; private final Map<String, CompletableFuture<?>> singleFlightMap = new ConcurrentHashMap<>(); @Override public <T> T fetch(String key, Duration ttl, Supplier<T> supplier, Class<T> clazz) { String cached = redisTemplate.opsForValue().get(key); if (cached != null) { return DataSerializer.deserializeOrNull(cached, clazz); } CompletableFuture<T> newFuture = new CompletableFuture<>(); CompletableFuture<T> existing = (CompletableFuture<T>) singleFlightMap.putIfAbsent(key, newFuture); if (existing != null) { // 다른 스레드가 실행 중 → 기다림 return existing.join(); } // 내가 실행자 (락 없이 실행) try { T result = refresh(key, ttl, supplier); newFuture.complete(result); return result; } catch (Throwable t) { newFuture.completeExceptionally(t); throw t; } finally { singleFlightMap.remove(key, newFuture); } } private <T> T refresh(String key, Duration ttl, Supplier<T> dataSourceSupplier) { T result = dataSourceSupplier.get(); put(key, ttl, result); return result; } 이 방식은 분산 락이나 폴링 방식 없이도 동일 인스턴스 내 요청을 모을 수 있다는 장점이 있다고 생각했습니다.물론 이 방법은 모든 분산 서버 간 요청을 하나로 모으는 것은 아니기 때문에 , 서버 인스턴스 수만큼은 요청이 발생할 수 있다는 한계가 있다고 생각합니다. 하지만 인스턴스 수가 많지 않다면, 분산 락으로 인한 오버헤드나 복잡성을 줄이면서도 어느 정도 트래픽을 제어할 수 있는 현실적인 선택지가 될 수 있지 않을까 하는 생각이 들었습니다. 실무 관점에서는 이런 방식에 대해 어떻게 평가하시는지 궁금합니다. 3. Write Through 방식에서의 장애 처리 Write Through 방식에서는 일반적으로: DB에 먼저 저장 동일 데이터를 Redis에도 저장 하는 구조로 이해하고 있습니다. 그런데 만약: DB에는 쓰기 성공 Redis에는 쓰기 실패 하는 상황이 발생한다면, 이 경우를 트랜잭션 실패로 간주해야 하는지 궁금합니다. Redis 장애로 인해 캐시 반영이 실패했을 때, 핵심 트랜잭션(DB 쓰기)까지 롤백해야 하는지 아니면 캐시는 보조 저장소로 보고 DB 성공을 기준으로 처리해야 하는지 두 저장소 간 원자성을 반드시 보장해야 하는 설계인지 실무에서는 어떤 기준으로 판단하는지 궁금합니다.
안녕하세요! AI로 개발하는 대략적인 방법에 대해서 알 수 있어서 재밌게 잘 듣고 있습니다!! 다만, 프론트에서 React 훅을 만드는 작업(API 작업)을 다루는 부분이 많이 스킵되어 이 부분을 어떻게 처리해야 할 지 고민이 됩니다. 이전에 AI로 프로젝트를 진행할 때에도, 이미 만들어진 UI/UX에 API 추가하는 것이 항상 어려움이 있었던 작업이라.. 혹시, API를 연결할 때 조금 더 수월하게 할 수 있는 팁 같은 것이 있을까요? 감사합니다!
안녕하세요! 해당 강의를 통해 redis pipeline과 lua script 활용 법을 눈으로 보고 배울 수 있어서 재밌게 수강하고 있습니다. AsyncPERStrategy() 메서드를 통해 랜덤한 확률로 레디스의 캐시 데이터를 업데이트 하는 것으로 이해하였습니다. 캐시 데이터를 업데이트를 비동기적으로 처리를 위해 프록시 기반 AOP로 동작하는 @Async 어노테이션을 활용하셨는데, 해당 메서드를 내부호출 함으로써 비동기 처리가 안되는 것으로 예상됩니다! 혹시 제가 잘못 알고있을 수도 있으니 확인 부탁드립니다!
1. 현재 학습 진도 몇 챕터/몇 강을 수강 중이신가요? 여기까지 이해하신 내용은 무엇인가요? 2. 어려움을 겪는 부분 어느 부분에서 막히셨나요? 코드의 어떤 로직이 이해가 안 되시나요? 어떤 개념이 헷갈리시나요? 3. 시도해보신 내용 문제 해결을 위해 어떤 시도를 해보셨나요? 에러가 발생했다면 어떤 에러인가요? 현재 작성하신 코드를 공유해주세요 이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다! 안녕하세요. 아직 수강전인데 수강을 해야만 백엔드 기술면접 실전문제집을 받을 수 있는건가요? (혹시 아직 여분이 있는걸까요?!)
1. 현재 학습 진도 몇 챕터/몇 강을 수강 중이신가요? 여기까지 이해하신 내용은 무엇인가요? 2. 어려움을 겪는 부분 어느 부분에서 막히셨나요? 코드의 어떤 로직이 이해가 안 되시나요? 어떤 개념이 헷갈리시나요? 3. 시도해보신 내용 문제 해결을 위해 어떤 시도를 해보셨나요? 에러가 발생했다면 어떤 에러인가요? 현재 작성하신 코드를 공유해주세요 안녕하세요 항상 강의 잘 보고 있습니다 ! 딩코딩코님 혹시, 로컬에서 테스트 한 결과를 이력서에 써도 괜찮을까요? 서비스를 배포를 할 생각이긴한데, 똑같은 환경을 2개 만들어서 배포를 하고 테스트를 하려니 비용이 많이 나올 것 같아서 어떻게 해야될지 고민하고 있습니다 ㅜㅜ 이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다!
코드리뷰 실습 부분에서 아래 두가지와 관련된 질문 들이 있습니다! agents commands 질문 두 가지는 실제로 클로드 코드에서 제공해주는 각각 다른 기능인건가요? 아니면 똑같은 기능이지만 추상적인 의미만 부여한 건가요? agents.md 파일 코드리뷰에이전트 이외에도 테스트코드작성전용에이전트, 쿼리작성에이전트와 같이 하나의 페르소나를 부여한 별도로 하나의 기능을 가진 객체로 생각해도 될까요? commands 기능은 꼭 agents 파일을 바인딩 할 때만 사용하는 기능인가요? 위 기능의 차이점이 단순히 agents.md를 실행하려면 자연어로 명령하고 commands기능은 /xx로 명령하는 차이만 있는건가요?
학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 좋아요에 대한 정합성을 (article_id, user_id) 유니크 인덱스로 보장하는 것은 DB의 역할이라고 생각합니다. 그렇다면, 다수의 동시 요청이나 사용자의 반복 클릭(예: 좋아요 버튼을 연속으로 누르는 경우) 상황에서 불필요한 DB 부하와 예외 발생을 줄이기 위해 애플리케이션 단에서는 어떤 방식으로 이를 보완하고 처리하는 것이 적절한가요? 좋아요에 대한 정합성을 (article_id, user_id) 유니크 인덱스로 보장하는 것은 DB의 역할이라고 생각합니다. 다만, 다수의 동시 요청이나 사용자의 반복 클릭(예: 좋아요 버튼을 연속으로 누르는 경우) 상황에서는 애플리케이션 단의 단순한 선행 검증만으로는 이를 제어하기 어렵다고 느꼈습니다. 예를 들어, 아래와 같은 코드에서는 다음과 같은 경쟁 상태(race condition)가 발생할 수 있습니다. T1: exists → false T2: exists → false T1: insert T2: insert ❌ (유니크 제약 위반) if (!likeRepository.exists(postId, userId)) { likeRepository.save(...); } 이처럼 애플리케이션 레벨의 exists → insert 패턴이 동시성 문제를 해결하지 못하는 상황에서 DB 예외에만 의존하지 않고 불필요한 중복 요청과 예외 발생을 줄이기 위해 애플리케이션 단에서는 어떤 방식으로 이를 보완하는 것이 바람직하다고 보시는지 궁금합니다.