Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

.NET 8 웹 API의 기본 데이터 저장소인 Redis

소개

이 글에서는 Redis에 대해 논의하고 이를 기본 데이터베이스로 사용하여 데이터를 저장하는 사용 사례에 대해 설명하겠습니다.

  • Redis 소개
  • Redis 데이터 유형
  • Redis를 DB로 사용할 때의 장점과 단점
  • 컨테이너에 Redis 설정
  • Redis를 .NET 8 Web API와 함께 기본 데이터베이스로 사용

기본 요건

  • 비주얼 코드
  • .NET 8 SDK
  • Redis 데스크톱 관리자. URL(https://redis.io/resources/tools/)에서 다운로드하실 수 있습니다.
  • 도커 데스크톱
  • 패키지
    • Microsoft.Extensions.Caching.stackExchangeRedis
    • StackExchange.Redis

Redis 소개

Redis는 인메모리 데이터 저장소이자 키-값 데이터 저장소이며 주로 캐싱 계층에 사용됩니다. Redis는 데이터를 메모리에 저장하므로 지연 시간이 짧은 데이터 액세스에 적합한 매우 빠른 읽기 및 쓰기 작업이 가능합니다. Redis가 데이터를 메모리에 저장하지만 시스템을 재부팅하면 데이터가 손실되는 것과 같은 질문이 있을 것입니다.

데이터 지속성 문제를 해결하기 위해 Redis는 스냅샷과 같은 다양한 메커니즘을 제공합니다. 추가 전용 파일(AOF) 이러한 메커니즘을 사용하면 데이터를 디스크에 지속적으로 저장할 수 있으므로 시스템 재부팅 후에도 데이터를 복구할 수 있습니다. URL에서 Redis Persistence에 대해 자세히 알아볼 수 있습니다

대부분 Redis는 캐시 계층으로 사용되지만 복잡한 데이터베이스 시스템에 대한 다른 호출을 줄이기 위해 데이터베이스로 사용할 수도 있습니다. Redis는 주로 JSON 형식으로 문서에 데이터를 저장하는 문서 데이터베이스 모델을 사용합니다. URL을 통해 자세한 내용을 확인할 수도 있습니다

Redis 데이터 유형

Redis는 캐싱, 대기열, 이벤트 처리 관련 문제를 해결할 수 있는 몇 가지 데이터 유형을 제공합니다.

  • 문자열: 일련의 바이트를 나타냄
  • 목록 - 문자열 목록
  • 세트 - 고유 문자열의 순서가 지정되지 않은 컬렉션
  • 해시 - 필드-값 쌍의 컬렉션으로 모델링된 레코드 유형

URL에서 데이터 유형에 대해 자세히 알아보세요

Redis를 DB로 활용하는 프로

  • 고성능
  • 다양한 데이터 구조
  • 낮은 지연 시간
  • 확장성

Redis를 DB로 사용하는 단점

  • 데이터 내구성
  • 제한된 쿼리 기능
  • 메모리 제약

컨테이너에 Redis 설정

Docker Desktop이 실행 중인지 확인하고 Visual Studio 2022를 엽니다.

"새 프로젝트 만들기"를 선택하세요 --> "ASP.NET Core Web API"를 클릭하고 "다음"을 클릭하세요.

구성 페이지에서 프로젝트 이름을 입력하고 "다음"을 누르세요.

.NET 8 웹 API의 기본 데이터 저장소인 Redis

추가 정보 페이지에서 스크린샷에 따라 정보를 선택하고 "만들기"를 선택하세요.

.NET 8 웹 API의 기본 데이터 저장소인 Redis

이제 Redis 구성을 저장할 "docker-compose.yaml" 파일을 생성하고 아래 코드를 붙여넣으세요.

version: '3.8'
services:
 redis:
 image: redis:alpine
 container_name: redisStudentAPI
 ports:
 - 6379:6379

그런 다음 도구 -> 명령줄 -> 개발자 Powershell에서 개발자 Powershell 프롬프트를 엽니다.

그런 다음 프로젝트 폴더 내부를 탐색하고 명령을 입력하여 YAML 파일 "docker compose up -d"를 실행합니다.

Docker 데스크탑을 열고 컨테이너로 이동하면 YAML 파일에서 생성된 컨테이너를 볼 수 있습니다. 또한 'docker ps'를 실행하여 실행 중인 컨테이너를 확인할 수도 있습니다.

.NET 8 웹 API의 기본 데이터 저장소인 Redis

Redis 서버와 상호 작용하려면 컨테이너 ID로 아래 명령을 실행해야 합니다.

docker exec -it <container_id> /bin/sh

Docker의 기본 설정이 완료되었으며 명령줄을 통해 Redis와 상호 작용할 수 있습니다.

이제 키와 값 쌍을 문자열로 저장하므로 문자열 데이터 유형에 대해 더 자세히 살펴보겠습니다.

문자열

키와 연결되는 가장 간단한 값 유형이며 키와 값 사이의 일대일 매핑입니다.

Set 를 사용하여 값을 설정할 수 있고 GET

를 사용하여 가져올 수도 있습니다.

Del

를 사용하여 키를 삭제할 수도 있습니다.

이제 NuGet 패키지 관리자에서 필요한 패키지를 설치해야 합니다.

.NET 8 웹 API의 기본 데이터 저장소인 Redis

Program.cs 파일에 구성 추가

Programs.cs

builder.Services.AddSingleton<IConnectionMultiplexer>(options =>
 ConnectionMultiplexer.Connect(("127.0.0.1:6379")));
builder.Services.AddScoped<IStudentRepository, StudentRepository>();

Models 폴더를 만들고 Model Student.cs에 대한 파일을 만든 다음 코드를 붙여넣으세요.

학생.cs

namespace StudentAPIWithRedisDB.Models
{
 public class Student
 {
 public string Id { get; set; } = $"student:{Guid.NewGuid().ToString()}";
 public required string StudentName { get; set; } = string.Empty;
 }
}

그런 다음 Respection 파일에 아래 코드를 복사하여 붙여넣으세요.

StudentRepository.cs

using StudentAPIWithRedisDB.Models;
namespace StudentAPIWithRedisDB.Data
{
 public interface IStudentRepository
 {
 IEnumerable<Student> GetAllStudents();
 Student? GetStudentById(string id);
 void AddStudent(Student student);
 Student? UpdateStudent(Student student);
 Student? DeleteStudent(string id);
 }
}

StudentRepository.cs는 IStudentRespository.cs 인터페이스와 해당 메서드의 구현입니다.

using StackExchange.Redis;
using StudentAPIWithRedisDB.Models;
using System.Text.Json;
namespace StudentAPIWithRedisDB.Data
{
 public class StudentRepository : IStudentRepository
 {
 private readonly IConnectionMultiplexer _redis;
 public StudentRepository(IConnectionMultiplexer redis) 
 {
 _redis = redis;
 }
 public void AddStudent(Student student)
 {
 if(student == null)
 {
 throw new ArgumentOutOfRangeException(nameof(student));
 }
 var db = _redis.GetDatabase();
 var serializedStudent = JsonSerializer.Serialize(student);
 db.StringSet(student.Id, serializedStudent);
 }
 public Student? DeleteStudent(string id)
 {
 var db = _redis.GetDatabase();
 var student = db.StringGet(id);
 if (student.IsNullOrEmpty)
 {
 return null;
 }
 db.KeyDelete(id);
 return JsonSerializer.Deserialize<Student>(student);
 }
 public IEnumerable<Student> GetAllStudents()
 {
 var db = _redis.GetDatabase();
 var studentKeys = db.Multiplexer.GetServer(_redis.GetEndPoints().First()).Keys(pattern: "student:*");
 var students = new List<Student>();
 foreach (var key in studentKeys)
 {
 var studentJson = db.StringGet(key);
 if (!studentJson.IsNullOrEmpty)
 {
 var student = JsonSerializer.Deserialize<Student>(studentJson);
 students.Add(student);
 }
 }
 return students;
 }
 public Student? GetStudentById(string id)
 {
 var db = _redis.GetDatabase();
 var student = db.StringGet(id);
 if(student.IsNullOrEmpty)
 {
 return null;
 }
 return JsonSerializer.Deserialize<Student>(student);
 }
 public Student UpdateStudent(Student student)
 {
 var db = _redis.GetDatabase();
 
 var id = student.Id;
 if (db.KeyExists(id))
 {
 var updatedStudentJson = JsonSerializer.Serialize(student);
 db.StringSet(id, updatedStudentJson);
 return student;
 }
 else
 {
 return null;
 }
 }
 }
}

StudentsController.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using StudentAPIWithRedisDB.Data;
using StudentAPIWithRedisDB.Models;
namespace StudentAPIWithRedisDB.Controllers
{
 [Route("api/[controller]")]
 [ApiController]
 public class StudentsController : ControllerBase
 {
 private readonly IStudentRepository _studentRepository;
 public StudentsController(IStudentRepository studentRepository)
 {
 _studentRepository = studentRepository;
 }
 [HttpGet("{Id}", Name = "GetStudentById")]
 public ActionResult<Student> GetStudentById(string Id)
 {
 var student = _studentRepository.GetStudentById(Id);
 if(student == null)
 {
 return NotFound();
 } 
 return Ok(student);
 }
 [HttpPost]
 public ActionResult<Student> AddStudent(Student student)
 {
 _studentRepository.AddStudent(student);
 return CreatedAtRoute(nameof(GetStudentById), new { Id = student.Id }, student);
 }
 [HttpGet(Name = "GetAllStudents")]
 public ActionResult<Student> GetAllStudents()
 {
 var students = _studentRepository.GetAllStudents();
 return Ok(students);
 }
 [HttpDelete("{id}")]
 public ActionResult<Student> DeleteStudent(string id)
 {
 var student = _studentRepository.DeleteStudent(id);
 if(student == null)
 {
 return NotFound();
 }
 return Ok(student);
 }
 [HttpPatch]
 public ActionResult<Student> UpdateStudent(Student student)
 {
 var studentToUpdate = _studentRepository.GetStudentById(student.Id);
 if(studentToUpdate == null)
 {
 return NotFound();
 }
 _studentRepository.UpdateStudent(student);
 return NoContent();
 }
 }
}

이제 애플리케이션을 실행하면 Swagger를 사용하여 브라우저에 표시되는 엔드포인트를 볼 수 있습니다.

.NET 8 웹 API의 기본 데이터 저장소인 Redis

또한 Redis Desktop Manager를 열어 데이터를 확인하면 도움이 될 것입니다. 처음에는 데이터가 없는 16개의 데이터베이스가 있습니다.

엔드포인트 생성을 누르면 자동으로 DB0에 레코드가 생성됩니다.

만들기

간편한 테스트를 위해 Postman을 사용하여 엔드포인트를 테스트했습니다.

이름만 전달하면 학생 이름과 새 Guid 접미사가 포함된 ID가 자동으로 생성됩니다.

그리고 DB0에 문서가 생성됩니다.

GetStudentById

이를 위해서는 문서에서 ID를 복사해야 합니다. 그런 다음 요청 URL에 전달하세요.

ID를 기준으로 값을 반환합니다.

GetAllStudents

데이터베이스에서 사용 가능한 모든 문서를 반환합니다.

업데이트

ID와 업데이트된 값을 전달해야 합니다. 그러면 ID를 기준으로 업데이트됩니다.

관리자를 새로 고치면 업데이트된 값이 표시됩니다.

삭제

사용자를 삭제하려면 해당 ID를 입력해 주시면 학생DB에서 해당 문서가 삭제됩니다.

그리고 해당 문서는 파일에서 삭제됩니다.

이전에는 학생 테이블에 두 개의 문서가 있었지만 지금은 첫 번째 문서가 삭제되었습니다.

이것은 우리 애플리케이션에서 Redis를 데이터베이스로 사용하는 방법을 보여주는 간단한 방법입니다. 여기서는 캐시를 줄이고 데이터를 Redis에 직접 저장했으며, 이를 검색하고 변경했습니다. 마찬가지로 지원서에도 동일하게 적용할 수 있습니다.