Backend/SpringBoot

NoSQL DB 사용

Dean83 2025. 9. 2. 10:03

mysql이나 오라클 같은 전통적인 RDBMS도 사용하지만, NoSQL도 많이 사용하는것 같다. 그 이유를 생각해보면, 

  • RDBMS
    • 테이블을 미리 생성해야 하고, 컬럼들과 타입을 미리 정의해야 한다. 
    • 컬럼 추가 및 변경시 마이그레이션이 필요하다.
    • 서버를 여러대 두는 분산처리가 어렵다. 때문에 DB에 문제가 생기면 장애가 발생하기 쉽다
    • 데이터 정합성 확보에 좋다 (동시성 처리)
    • 금융, 주문, 결제 시스템 등 데이터가 중요한 경우 사용
  • NoSQL
    • 보통 Json 또는 key-value 구조로 되어 있어, 정해진 틀에 맞추지 않고 유연하게 저장이 가능하다.
    • 분산처리에 최적화 되어 있어 클라우드 환경에 최적화 되어 있다. 일부 서버 장에에도 서비스가 가능하다
    • 대용량 데이터, 속도, 확장성, 가용성 위주이다 보니, 일관성이 깨질 수 있다.
    • 캐시, 로그, SNS나 빅데이터에 유리

 

NoSQL 중, 스프링부트에서 주로 사용하는 것은 MongoDB 와 Redis 인듯 하다. 

 

1. MongoDB

  • HDD, SSD 등 디스크에 실제로 저장을 하는 NoSQL DB
  • Json 형태로 데이터 저장
  • Document 단위로 저장
  • 저장되는 데이터의 예시
{
  "user_id": "u12345",
  "name": "홍길동",
  "email": "hong@test.com",
  "posts": [
    {
      "title": "첫 글",
      "content": "MongoDB는 JSON으로 데이터를 저장합니다",
      "created_at": "2025-09-02"
    },
    {
      "title": "두 번째 글",
      "content": "스키마가 자유롭습니다",
      "created_at": "2025-09-02"
    }
  ]
}
  • SpringBoot 에서 사용 예
@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String name;
    private String email;
}

public interface UserRepository extends MongoRepository<User, String> {
    List<User> findByName(String name);
}
  • @Entity 가 아닌 @Document 어노테이션을 사용한다. 
  • 이외 사용법은 JPA를 사용할때와 동일하다
  • 스프링부트 서버 실행전에 미리 실행 해야 한다.
    • brew services start mongodb-community
  • 스프링부트 properties 설정 예
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=testdb
  • 테스트용 MongoDB를 사용할 때에는 별도의 설치 및 실행을 하지 않아도 된다. 
    • gradle 에서, 다음을 추가
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
  • Docker 에서 mongoDB 설치 후 실행
    • 스프링부트도 도커 환경에서 실행될 때가 많으므로, 도커에서 mongodb 이미지를 다운받고 실행하면 편하다.
docker run -d -p 27017:27017 --name mongodb mongo:7
  • -d → 백그라운드 실행
  • -p 27017:27017 → 호스트 27017 포트를 컨테이너 27017 포트와 연결
  • --name mongodb → 컨테이너 이름 지정
  • mongo:7 → MongoDB 공식 이미지, 버전 7
  • Spring Boot에서는 localhost:27017으로 접속 가능.

 

2. Redis

  • 기본적으로 메모리에 올라가는 DB 이다. 따라서 프로그램 종료시 사라진다.
    • 물론 디스크에 저장할 수도 있고, 실행시 저장된 항목을 불러올 수 있다.
  • 메모리에 있어서 속도가 매우 빠르다 
  • DB의 캐시 처리, 세션 저장을 위해 주로 사용된다.
  • key-value 타입으로 저장
  • 저장되는 데이터 예시
// 문자열
SET session:u12345 "active"

// 해시(Hash)
HSET user:u12345 name "홍길동" email "hong@test.com"

// 리스트(List)
LPUSH notifications:u12345 "새 메시지 도착" "댓글이 달렸습니다"

// 집합(Set)
SADD friends:u12345 u67890 u54321
  • 스프링부트 에서 사용 예
@Service
public class CacheService {
    private final StringRedisTemplate redisTemplate;

    public CacheService(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void saveSession(String userId, String value) {
        redisTemplate.opsForValue().set("session:" + userId, value, 10, TimeUnit.MINUTES);
    }

    public String getSession(String userId) {
        return redisTemplate.opsForValue().get("session:" + userId);
    }
}
  • key-value 형식으로 저장되기에 @Entity나 @Document 같은 어노테이션이 필요가 없다. 
  • redisTemplate 는 시스템에서 생성하는 Bean이므로 그냥 주입받아서 쓰면 된다.
  • 스프링부트 시작 전 redis가 실행되어 있어야 한다

그래들 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.fasterxml.jackson.core:jackson-databind'
}

 

Redis 설정 (파일로 저장, 실행시 불러오기)

  • redis.conf 에서 설정 변경
    • 기본 redis 설치 위치에 존재 하거나 (Mac (Homebrew): /usr/local/etc/redis/redis.conf) 따로 저장 가능
    • 터미널에서 redis-server 명령어를 통해 실행.
      • 경로가 별도로 있을경우 : redis-server /경로/redis.conf
# =========================
# RDB Snapshot 설정
# =========================
save 900 1      # 900초 동안 1개 이상 키 변경 시 스냅샷
save 300 10     # 300초 동안 10개 이상 키 변경 시 스냅샷
dir ./data      # RDB/AOF 파일 저장 위치
dbfilename dump.rdb

# =========================
# AOF 설정
# =========================
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
  • 이렇게 설정시 자동으로 데이터를 파일에 저장하고, 실행시 파일에서 데이터를 복원함.
  • 스프링부트 properties 에 Redis 접속 정보 설정 예
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=yourpassword # 필요 시