December 14, 2023
1. Redis 소개 # Redis instance # 여러 client가 하나의 redis 서버로 요청 전달 단일 redis 서버에 문제가 발생하면 장애 -> 모든 client에서 접속 불가 Redis replication # master와 replica로 구성 master에 데이터가 업데이트 -> replica 동기화 replica : 읽기만 가능 replica에 문제 발생 -> 여러 node에 data가 복제되었기 때문에 복구 가능 master에 문제 발생 -> 개발자가 직접 replica 중 하나를 master로 변경 Redis sentinel # master에 문제 발생 -> replica들이 master를 선출 이전 master가 복구 된 경우, replica로 전환되어 새로운 master를 바라보게된다.
...
December 14, 2023
2. Lettuce # 구조 # Reactor 기반으로 Reactive API 지원 Reactive streams API 지원 동기 API, 비동기 API 모두 지원 Netty 기반으로 높은 성능과 확장성 제공 일반 TCP 통신 뿐만 아니라 epoll, kqueue 기반의 multiplexing I/O 지원 주요 컴포넌트 # RedisClient : Redis의 연결 정보를 포함하는 객체 Netty의 Channel, EventLoopGroup 등을 포함하기 때문에 가능한한 재사용 RedisConnecction 생성 StatefulRedisConnection : Redis 서버 Connection 여러 쓰레드가 동시에 접근해도 안전 동기, 비동기, Reactive command를 제공 RedisReactiveCommand : Redis API와 관련된 reactive command 제공 RedisReactiveCommand 획득 # RedisClient.
...
December 14, 2023
3. ReactiveRedisTemplate # ReactiveRedisTemplate # ReactiveRedisTemplate은 Spring data redis reactive의 추상화 클래스 ReactiveRedisConnectionFactory를 통해서 RedisConnection을 주입 ReactiveRedisConnectionFactory # ReactiveRedisConnectionFactory는 RedisConnection을 제공 LettuceConnectionFactory와 JedisConnectionFactory 구현체 RedisTemplate bean # RedisReactiveAutoConfiguration를 통해서 자동으로 ReactiveRedisTemplate bean 생성 JdkSerializationRedisSerializer는 ObjectOutputStream을 이용하여 key와 value로 주어지는 object를 binary로 변환 key, value에 대해서 String만 지원하는 ReactiveStringRedisTemplate bean도 등록 ReactiveRedisOperations # ReactiveRedisConnection에 직접 접근할 수 있는 execute, executeInSession 메소드 pub/sub 메소드 key와 관련된 메소드 스크립트 메소드 operations 접근 메소드 pub/sub # convertAndSend: destination 채널로 message를 전달하고 메시지를 받은 클라이언트의 숫자를 반환 listenToChannel: channels에 주어진 채널들을 listen하고 메시지를 Flux 형태로 전달 key 관련 # hasKey: EXISTS.
...
December 14, 2023
4. ReactiveOperations # ReactiveValueOperations 실행 # set으로 특정 key에 value를 추가 setIfAbsent로 key에 값이 없을때만 설정 get으로 key의 value를 조회 multiGet으로 여러 key에 접근 increment로 특정 key의 value를 증가 ReactiveListOperations # size: LLEN. list의 크기를 반환 leftPush: LPUSH. list의 head에 값을 추가 rightPush: RPUSH. list의 tail에 값을 추가 set: LSET. 특정한 index에 값을 설정 remove: LREM. list에서 value를 count 숫자만큼 제거 leftPop: LPOP. list의 head에서 값을 제거하고 반환 rightPop: RPOP.
...
December 11, 2023
Spring data mongodb reactive # Entity # 데이터베이스에서 하나의 Document와 매칭되는 클래스 ReactiveMongoEntityTemplate, ReactiveMongoRepository 등은 데이터베이스에 요청을 보내고 그 결과를 Entity 형태로 반환한다. Collection, Document에 필요한 데이터베이스 metadata를 어노테이션 등으로 제공 ReactiveMongoTemplate # ReactiveMongoTemplate은 Spring data mongodb reactive의 추상화 클래스 Mongo 쿼리들을 Bson 형태로 넘기거나 PojoCodec, Custom codec 등을 등록하지 않아도, 메소드 체이닝을 통해서 쿼리를 수행하고 결과를 entity 객체로 받을 수 있다 ReactiveMongoOperations를 구현 MongoTemplate 생성 # MongoClient와 databaseName을 전달하여 생성 가능 spring에서는 ReactiveMongoDatabaseFactory와 MongoConverter을 주입받아 생성 ReactiveMongoOperations # ReactiveMongoTemplate의 operations를 담당하는 interface ReactiveFluentMongoOperations를 상속하고 MongoConverter 제공 MongoConverter: 주어진 Document를 Entity로 만드는 converter ReactiveMongoDatabaseFactory # getMongoDatabase: MongoDatabase를 반환 getCodecRegistry: bson의 CodecRegistry를 반환 ReactiveMongoTemplate은 ReactiveMongoDatabaseFactory의 MongoDatabase를 통해서 MongoCollection에 접근 ReactiveMongoTemplate 구현 # ReactiveMongoTemplate은 createMono 혹은 createFlux를 이용하여 MongoCollection을 획득 ReactiveMongoTemplate 구현 # createFlux를 이용하여 collectionName과 callback을 전달 callback에서 Publisher를 반환 이런 방식으로 여러 operations를 구현 MongoConverter # MongoWriter(EntityWriter를 상속), EntityReader를 구현
...
December 11, 2023
Object mapping # Spring data의 object mapping # 만약 지원하는 converter가 없다면 MappingMongoConverter는 다음 과정을 거쳐서 Document를 entity로 변환 Object creation constructor, factory method 등을 이용해서 Document의 field들로 Object 생성 Property population setter, with.. 메소드 등을 이용해서 Document의 field를 Object에 주입 Object creation # 다음 순서로 체크하여 해당하는 알고리즘으로 Document를 Object로 변환 @PersistenceCreator 어노테이션을 갖는 constructor가 있다면 해당 constructor 사용 인자가 없는 constructor가 있다면 해당 constructor 사용 constructor가 정확히 하나 있다면 해당 constructor 사용 id mapping # mongodb에서 모든 document는 _id를 필요 MappingMongoConverter는 다음의 방법으로 _id를 감지 @Id가 붙어있는 필드 필드명이 id이고 @Field를 통해서 별도의 이름이 부여되지 않은 경우 id 필드가 제공되지 않는 경우, 자동으로 추가 Property population # r2dbc에서는 property가 mutable할때만 property population 적용이 가능했지만, mongodb에서는 with 메소드 지원 No-args constructor를 호출하여 텅 빈 객체를 만들고, gender를 제외한 나머지 필드는 reflection으로 진행 gender는 withGender 메소드 호출 Metadata Mapping # Entity 클래스에 annotation을 추가하여 데이터베이스와 관련된 설정들을 주입 @Id: _id에 해당하는 필드에 적용 @Document: entity class에 적용.
...
December 11, 2023
ReactiveMongoOperations # ReactiveMongoOperations # ReactiveFluentMongoOperations를 상속 ReactiveFluentMongoOperations는 여러 Operations를 상속 ReactiveFindOperation: find query와 관련된 메서드 제공 ReactiveInsertOperation: insert query와 관련된 메서드 제공 ReactiveUpdateOperation: update query와 관련된 메서드 제공 ReactiveRemoveOperation: delete query와 관련된 메서드 제공 ReactiveAggregationOperation: aggregation query와 관련된 메서드 제공 ReactiveChangeStreamOperation: watch query와 관련된 메서드 제공 ReactiveFindOperation # ReactiveFindOperation의 query 부터 시작 TerminatingFind의 count, exists, first, one, all, tail 등으로 종료 query -> inCollection -> as -> matching -> 최종 query -> inCollection -> matching -> 최종 query -> as -> matching -> 최종 query -> matching -> 최종 query -> 최종 ReactiveFindOperation # inCollection query를 실행할 collection 이름을 전달 제공되지 않을 경우 domain Type의 class 이름 통해 collection 이름 획득 @Document 어노테이션 통해 collection 이름 획득 as Entity를 전부 mapping하지 않고 특정 필드만 mapping 하고 싶은 경우 Entity의 일부 property만 담고 있는 subclass 또는 interface를 넘겨서 projection projection이 제공되지 않는다면 Entity에 모든 필드를 mapping matching query의 filter에 해당 Query를 전달하여 filter에 들어갈 내용을 설정 matching을 생략하면 collection 전체에 대한 요청을 보내는 것과 동일 최종 마지막으로 count, exists, first, one, all, tail 등의 연산을 선택 count: 조건에 맞는 document의 개수 반환 exists: 조건에 맞는 document 존재 여부 반환 first: 조건에 맞는 첫 번째 document 반환 one: 조건에 맞는 하나의 document 반환.
...
December 11, 2023
ReactiveMongoRepository # ReactiveMongoRepository # ReactiveSortingRepository, ReactiveQueryByExampleExecutor를 상속한 interface SimpleReactiveMongoRepository에서 구현 ReactiveMongoRepository 등록 # MongoReactiveRepositoriesAutoConfiguration가 활성화되어 있다면 SpringBootApplication 기준으로 자동으로 scan 혹은 EnableReactiveMongoRepositories를 통해서 repository scan SimpleReactiveMongoRepository # ReactiveMongoRepository를 구현 ReactiveMongoOperations를 기반으로 Mongo 쿼리를 실행하고 결과를 Entity로 mapping save # save mongoOperations의 insert 혹은 update를 이용 새로운 entity라면 insert, 아니라면 update, Id 필드가 null이라면 new saveAll concatMap을 이용하여 save를 순차적으로 실행 전부 new entity라면 bulkInsert, 아니라면 각각을 save @Transactional이 없는 점 find # findById, existsById, count 모두 ReactiveMongoOperations에서 제공하는 단축 메소드 (findById, exists, count) 사용 delete # ReactiveMongoOperations에서 제공하는 단축 메소드 (remove) 사용 References 강의 : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지_
December 11, 2023
Query method # 쿼리 메소드 (Query method) # ReactiveMongoRepository를 상속한 repository interface에 메소드를 추가 메소드의 이름을 기반으로 Query 생성 조회, 삭제 지원 @Query, @Update, @Aggregation 어노테이션을 사용해서 복잡한 쿼리 실행 가능 쿼리 메소드 - find # id 뿐만 아니라 다른 필드를 이용해서 조회 가능 first 등의 키워드를 사용해서 query에 limit 제공 가능 기존의 Entity 뿐만 아니라 Projection을 사용하여 일부 필드만 조회 가능 사용예제
findFirstByNameOrderByAgeDesc name이 “taewoo”인 row들을 찾고 age 내림차순으로 sort 하여 limit을 1로 모든 field를 조회하여 PersonDocument class로 mapping 쿼리 메소드 - delete # 다른 필드를 이용해서 삭제 가능 여러 반환 타입 지원 Long: 영향을 받은 row 수 반환 Flux: 삭제된 document 반환 사용예제
...
December 10, 2023
Reactive MongoDB driver # MongoDB driver # MongoDB사에서 공식적인 2가지 java driver를 제공 Sync Driver Reactive Streams Driver Sync driver # 동기적으로 동작 클라이언트 요청을 보내면 응답이 돌아오기 전까지 쓰레드가 blocking 메서드가 응답 객체를 바로 반환 -> 직관적 쓰레드 동시성 문제 발생 가능성 Reactive Streams driver # 비동기적으로 동작 클라이언트가 요청을 보내면 쓰레드는 non-blocking 모든 응답이 publisher를 이용해서 전달되기 때문에 처리하기 어렵다. Spring reactive stack과 함께 사용되어 높은 성능, 안정성 제공 Spring Data MongoDB Reactive, REactive Streams MongoDB Driver # Mongo Reactive streams driver # MongoCollection 획득 # MongoDB의 MongoClient, MongoDatabase, MongoCollection MongoClient MongoDB 클러스터를 가리키는 객체 (MongoDatabase factory 역할) MongoDatabase Mongo의 Database를 가리킨다.
...