About Redis.

Written by Paul
AWS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Redis๋ฅผ ๋„์šธ๋•Œ์—๋Š” ๋‘๊ฐ€์ง€ ์ •๋„ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋‹ค.
  • ElastiCache ์‚ฌ์šฉ
  • EC2์— ์ง์ ‘ ์ ์šฉ
์ด๋ฒˆ ๊ธ€์—์„œ๋Š” EC2์— ์ง์ ‘ ์ ์šฉํ•˜๋Š” ๋ฒ•์„ ๋‹ค๋ค„๋ณผ๊นŒ ํ•œ๋‹ค.

Amazon Linux (EC2) ์— redis ์„ค์น˜.

sudo yum update -y ๋กœ ์ผ๋‹จ ์‹œ์Šคํ…œ์„ ์—…๋ฐ์ดํŠธ ํ•ด์ค€๋‹ค.
ย 
# Enable the Extra Packages for Enterprise Linux (EPEL) repository $ sudo amazon-linux-extras install epel -y # Install Remi Repository $ sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm # Enable the Remi Redis Module $ sudo yum --enablerepo=remi install redis -y # Start Redis $ sudo systemctl start redis # Enable Redis to start on boot $ sudo systemctl enable redis # Check Redis status $ sudo systemctl status redis
๋‚˜๋Š” ์œ„์™€๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ yum์„ ์‚ฌ์šฉํ•˜์—ฌ redis๋ฅผ ์„ค์น˜ํ•˜์˜€๋‹ค.
$ redis-server # ํ˜น์€ redis-cli ๋ช…๋ น์–ด๋กœ ๋กœ์ปฌํ˜ธ์ŠคํŠธ์— ์˜ฌ๋ผ์˜จ ๋ ˆ๋””์Šค์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค

์„ค์น˜๋œ redis์— ip bind ํ’€์–ด์ฃผ๊ธฐ.

๊ธฐ๋ณธ์ ์œผ๋กœ redis์˜ ์„ค์ •์€ /etc/redis.conf ํŒŒ์ผ์— ๋“ค์–ด์žˆ๋‹ค. ํ•ด๋‹น ํŒŒ์ผ์„ vim์œผ๋กœ ์—ด๊ฑฐ๋‚˜ nano๋กœ ์—ด์–ด์„œ bind ๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค. ์•„๋งˆ bind 127.0.0.1 ๋กœ ๊ธฐ๋ณธ์„ค์ •์ด ์žกํ˜€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด ์„ค์ •์„ bind 0.0.0.0 ์œผ๋กœ ํ’€์–ด์ฃผ์–ด EC2 ์ธ์Šคํ„ด์Šค ์™ธ๋ถ€์—์„œ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค. (ํ•„์š” ์‹œ)

์„ค์น˜๋œ redis์— ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฑธ๊ธฐ.

๋งŒ์•ฝ ์œ„์™€๊ฐ™์ด bind๋ฅผ ๋ชจ๋“  ip๋กœ๋ถ€ํ„ฐ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ’€์—ˆ๋‹ค๋ฉด, ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋‹ค์‹œ /etc/redis.conf ํŒŒ์ผ๋กœ ์ ‘๊ทผํ•˜์—ฌ, requirepass ๋ผ๋Š” ๋‹จ์–ด๋กœ ๊ฒ€์ƒ‰ํ•œ๋‹ค. ํ•ด๋‹น requirepass ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค.
์œ„ ์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด sudo systemctl restart redis ๋ช…๋ น์–ด๋กœ ๋ ˆ๋””์Šค๋ฅผ ๋‹ค์‹œ ์žฌ ์‹คํ–‰ ํ•˜์—ฌ ์„ค์ •์„ ์ ์šฉํ•œ๋‹ค.

LoadBalancer ํ˜น์€ security ์„ค์ •.

๋งŒ์•ฝ EC2๊ฐ€ LoadBalancer ์— ์—ฎ์—ฌ์žˆ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด 6379 ํฌํŠธ๋ฅผ ์—ด์–ด์ฃผ๋Š” ์„ค์ •์„ ํ•ด์•ผ ํ•œ๋‹ค.

Step 1: Create a Target Group for Redis

  1. Go to the AWS Management Console and navigate to the EC2 Dashboard.
  1. Under Load Balancing, select Target Groups and click Create target group.
  1. Choose target type: Select Instances.
  1. Target group name: Give your target group a name, e.g., redis-target-group.
  1. Protocol: Choose TCP.
  1. Port: Enter 6379.
  1. VPC: Select the VPC where your Redis EC2 instance is running.
  1. Health checks: Set the protocol to TCP (Redis doesnโ€™t have HTTP endpoints, so use TCP for health checks).
  1. Advanced health check settings: Adjust the health check interval, timeout, and thresholds if needed.
  1. Register Targets: Select your Redis EC2 instance and click Add to registered. Then click Create target group.

Step 2: Create a Network Load Balancer (NLB)

  1. In the EC2 Dashboard, navigate to Load Balancers and click Create Load Balancer.
  1. Choose a load balancer type: Select Network Load Balancer.
  1. Name: Give your load balancer a name, e.g., redis-nlb.
  1. Scheme: Choose either Internet-facing (if you need external access) or Internal (for VPC-only access).
  1. IP address type: Choose IPv4.
  1. Listeners:
      • By default, a listener on TCP port 80 will be created; change this to TCP and 6379 for Redis.
  1. Availability Zones: Select the VPC and the subnets where your Redis instance is running. If you have multiple availability zones, select the corresponding subnets.
  1. Click Next.

Step 3: Configure the Load Balancer with the Target Group

  1. Select Target Group: In the Target Group section, choose Select a target group and select the Redis target group you created earlier.
  1. Click Create Load Balancer.

Step 4: Modify Security Groups

To allow traffic through the load balancer and to your Redis instance, ensure that both the load balancer and the Redis instance have the correct security group rules.
  1. Load Balancer Security Group: The NLB itself doesn't need a security group since it operates at the network layer, but you still need to ensure your Redis instance allows inbound traffic from the load balancer.
      • In your Redis EC2 instanceโ€™s security group, add an inbound rule to allow TCP traffic on port 6379 from the load balancerโ€™s IP range.
      • Set the Source to Custom and specify the security group or IP range.
  1. Redis Instance Security Group: Allow inbound traffic on port 6379.
      • Type: Custom TCP Rule
      • Protocol: TCP
      • Port Range: 6379
      • Source: Choose the security group associated with your load balancer, or set it to 0.0.0.0/0 for public access (this is not recommended for security reasons).
ย 
๊ฐ„๋‹จํ•˜๊ฒŒ EC2์˜ security ์„ค์ •๋งŒ ๋˜์–ด์žˆ๋‹ค๋ฉด, 6379 ํฌํŠธ์˜ ์•„์ดํ”ผ๋ฅผ 0.0.0.0 ์œผ๋กœ ํ’€์–ด์ฃผ๋ฉด ๋œ๋‹ค.

์›๊ฒฉ์œผ๋กœ redis์— ์ ‘๊ทผํ•˜๊ธฐ.

์ฒซ๋ฒˆ์งธ๋กœ ioredis ๋ผ๋Š” ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•œ๋‹ค.
yarn add ioredis
ํ˜„์žฌ ๊ธ€์—์„œ๋Š” ioredis ์— ๋Œ€ํ•œ ์‹ฌํ™”์ ์ธ ๋‚ด์šฉ์€ ๋‹ค๋ฃจ์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์ ‘์†ํ•˜๊ณ , key์— ๋Œ€ํ•œ value ๋ฅผ ์‹ฌ์–ด๋†“๋Š” ์ž‘์—…๊นŒ์ง€๋งŒ ๋‹ค๋ฃฌ๋‹ค. ๋” ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด, https://github.com/redis/ioredis ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ  ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.
import Redis from 'ioredis' const redisClient = new Redis({ host: process.env.REDIS_URL ?? '', // host url port: process.env.REDIS_PORT ? +process.env.REDIS_PORT : undefined, // port number password: process.env.REDIS_PASSWORD ?? '', // redis password }) export const redisKeys = { // ... ๋“ค์–ด๊ฐˆ key ๊ฐ’์— ๋Œ€ํ•œ key factory } as const export class RedisClient { static async get<T>(key: string) { try { const value = await redisClient.get(key) if (!value) { return null } const parsed = JSON.parse(value) as T return parsed } catch (e) { console.error(e) return null } } static async set(key: string, value: string, expire?: number) { await redisClient.set(key, value) if (expire) { await redisClient.expire(key, expire) } } }
์œ„์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ RedisClient ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค ํด๋ž˜์Šค๋ฅผ ์„ค์ • ํ•˜์˜€๋‹ค. controller์™€ ๊ฐ™์€ ๋ ˆ์ด์–ด์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ๋ฉด ๋œ๋‹ค!
const redisValue = await RedisClient.get<SerializedType[]>( redisKeys.SOME_KEY(params) // key factory ์—์„œ parameter ๋กœ ๋”ฐ๋กœ ํ‚ค ๊ฐ’์„ ๊ตฌ๋ถ„ํ•œ๋‹ค ) if (redisValue) { // ๋ ˆ๋””์Šค์— ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ return rep.status(200).send(redisValue) } // ... ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง const dto = await SomeDTO.getById(req.params.id) const response = dto.serialize() await RedisClient.set( redisKeys.SOME_KEY(params), JSON.stringify(response), 60 * 60 // expiry time ) // ๋ ˆ๋””์Šค์— ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด, ์œ„์™€ ๊ฐ™์ด set ํ•ด์ฃผ๊ณ , ๊ฐ’์„ ๋ฐ˜ํ™˜ return rep.status(200).send(response)
ย 
โ† Go home