From e3f74cfde07873e8170407a79cb395f7f2304ce4 Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 15 Nov 2024 15:09:58 -0800 Subject: [PATCH] Changing to Redis ShardClient --- .env-prod | 3 +- .github/workflows/coverage.yml | 2 +- .github/workflows/run-tests.yml | 2 +- crank/settings/base.py | 6 +- crank/settings/prod.py | 23 ++++++ k8s/deployment.yml | 6 +- k8s/redis.yml | 124 ++++++++++++++++++-------------- 7 files changed, 106 insertions(+), 60 deletions(-) diff --git a/.env-prod b/.env-prod index 16987ed..0d66653 100644 --- a/.env-prod +++ b/.env-prod @@ -5,5 +5,6 @@ DB_NAME=crank DB_USER=crank DB_PORT=3306 PYTHON_UNBUFFERED=1 -REDIS_URL=redis://redis:6379/0 +REDIS_MASTER_URL=redis://redis-master:6379/0 +REDIS_SLAVE_URL=redis://redis-slave:6379/0 CACHE_TTL=60 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4faa8fd..3828336 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -66,7 +66,7 @@ jobs: ENV: dev SECRET_KEY: ${{ secrets.SECRET_KEY }} DJANGO_SETTINGS_MODULE: 'crank.settings' - REDIS_URL: 'redis://localhost:6379/0' + REDIS_MASTER_URL: 'redis://localhost:6379/0' CACHE_TTL: 60 PYTHON_UNBUFFERED: 1 run: | diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 4ab1bde..36727c9 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -61,7 +61,7 @@ jobs: env: ENV: dev SECRET_KEY: '${{ secrets.SECRET_KEY }}' - REDIS_URL: 'redis://localhost:6379/0' + REDIS_MASTER_URL: 'redis://localhost:6379/0' CACHE_TTL: 60 run: | pytest diff --git a/crank/settings/base.py b/crank/settings/base.py index 801a45f..070fe93 100644 --- a/crank/settings/base.py +++ b/crank/settings/base.py @@ -157,12 +157,13 @@ SESSION_COOKIE_AGE = 1800 # 30 minutes in seconds CACHE_MIDDLEWARE_SECONDS = int(os.environ["CACHE_TTL"]) # Timeout for cached items in seconds -REDIS_URL = os.environ["REDIS_URL"] +REDIS_MASTER_URL = os.environ.get("REDIS_MASTER_URL", "redis://redis-master:6379/0") + # Optional: To use Redis for session storage CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', - 'LOCATION': REDIS_URL, + 'LOCATION': REDIS_MASTER_URL, 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'SOCKET_CONNECT_TIMEOUT': 5, # in seconds @@ -174,6 +175,7 @@ # Set the TTL for session entries in Redis SESSION_REDIS = { 'ttl': 1800, # 30 minutes in seconds + 'master': REDIS_MASTER_URL, } # Password validation diff --git a/crank/settings/prod.py b/crank/settings/prod.py index 613ab1e..03528fe 100644 --- a/crank/settings/prod.py +++ b/crank/settings/prod.py @@ -7,6 +7,8 @@ from django.db import connection from pathlib import Path +from crank.settings import REDIS_MASTER_URL + pymysql.install_as_MySQLdb() BASE_DIR = Path(__file__).resolve().parent.parent.parent @@ -19,6 +21,27 @@ SESSION_COOKIE_HTTPONLY = True CSRF_COOKIE_SECURE = True +REDIS_SLAVE_URLS = os.environ.get("REDIS_SLAVE_URLS", "redis://redis-slave:6379/0").split(",") +REDIS_URLS = [REDIS_MASTER_URL] + REDIS_SLAVE_URLS + +CACHES = { + 'default': { + 'BACKEND': 'django_redis.cache.RedisCache', + 'LOCATION': REDIS_URLS, + 'OPTIONS': { + 'CLIENT_CLASS': 'django_redis.client.ShardClient', + 'SOCKET_CONNECT_TIMEOUT': 5, # in seconds + 'SOCKET_TIMEOUT': 5, # in seconds + } + } +} + +SESSION_REDIS = { + 'ttl': 1800, # 30 minutes in seconds + 'master': REDIS_MASTER_URL, + 'slaves': REDIS_SLAVE_URLS, +} + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', diff --git a/k8s/deployment.yml b/k8s/deployment.yml index 96ab280..ee27d90 100644 --- a/k8s/deployment.yml +++ b/k8s/deployment.yml @@ -84,8 +84,10 @@ spec: value: "3306" - name: ENV value: "prod" - - name: REDIS_URL - value: "redis://redis:6379/0" + - name: REDIS_MASTER_URL + value: "redis://redis-master:6379/0" + - name: REDIS_SLAVE_URLS + value: "redis://redis-slave:6379/0" - name: CACHE_TTL value: "60" - name: PYTHONUNBUFFERED diff --git a/k8s/redis.yml b/k8s/redis.yml index 482e8c5..1562d20 100644 --- a/k8s/redis.yml +++ b/k8s/redis.yml @@ -1,6 +1,5 @@ # Copyright (c) 2024 Isaac Adams # Licensed under the MIT License. See LICENSE file in the project root for full license information. ---- apiVersion: v1 kind: Namespace metadata: @@ -9,83 +8,102 @@ metadata: apiVersion: v1 kind: Service metadata: - name: redis + name: redis-master namespace: crank labels: app: redis + role: master spec: ports: - - port: 6379 - targetPort: 6379 - clusterIP: None # Headless service + - port: 6379 + targetPort: 6379 selector: app: redis + role: master +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-slave + namespace: crank + labels: + app: redis + role: slave +spec: + ports: + - port: 6379 + targetPort: 6379 + selector: + app: redis + role: slave --- apiVersion: apps/v1 -kind: ConfigMap +kind: Deployment metadata: - name: redis-config + name: redis-master namespace: crank -data: - redis.conf: | - # Redis configuration - bind 0.0.0.0 - port 6379 - dir /data - appendonly yes - # Conditional replication configuration - {{- if eq .Env.REDIS_ROLE "slave" }} - slaveof redis-master 6379 - {{- end }} + labels: + app: redis + role: master +spec: + replicas: 1 + selector: + matchLabels: + app: redis + role: master + template: + metadata: + labels: + app: redis + role: master + spec: + containers: + - name: redis + image: redis:latest + ports: + - containerPort: 6379 + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" --- apiVersion: apps/v1 kind: Deployment metadata: - name: redis + name: redis-slave namespace: crank labels: app: redis + role: slave spec: - replicas: 2 + replicas: 1 selector: matchLabels: app: redis + role: slave template: metadata: labels: app: redis + role: slave spec: containers: - - name: redis - image: redis:7.0.5-alpine - ports: - - containerPort: 6379 - resources: - requests: - memory: "256Mi" - cpu: "250m" - limits: - memory: "512Mi" - cpu: "500m" - env: - - name: REDIS_ROLE - valueFrom: - fieldRef: - fieldPath: metadata.labels['role'] - command: [ "redis-server", "/etc/redis/redis.conf" ] - volumeMounts: - - name: redis-storage - mountPath: /data - - name: redis-config-storage - mountPath: /etc/redis - subPath: redis.conf - volumes: - - name: redis-storage - persistentVolumeClaim: - claimName: redis-pvc - - name: redis-config-volume - configMap: - name: redis-config - items: - - key: redis.conf - path: redis.conf \ No newline at end of file + - name: redis + image: redis:latest + ports: + - containerPort: 6379 + env: + - name: REDIS_MASTER_SERVICE_HOST + value: "redis-master" + - name: REDIS_REPLICATION_MODE + value: "slave" + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" \ No newline at end of file