what happen if one of your servers,services,dbs get down , and you slept in bed and you think everything is ok ?
the simplest definition of HA is :
HA make your server stay always up , if one server or service getting down , its will replace it with a alternative healthy server or service
what about servers replicates?if you wanna make your HA system work you should make all users share the same level of information, that’s mean copying data from a database in one server to a database in another. so all servers have same data and records
many dbms backend’s such as mysql , SQL Server and Postgresql have replication system for their system .
requirements 3 or more replicated database backend server 1 django app Getting startfirst we should define our main dbms and then or alternative or backup dbsm servers to django, so just need to do something like this in our django settings
in this example i used postgresql as my dbms backend
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'my_database', 'USER': 'postgre_user', 'PASSWORD': 'blahblah', 'HOST': '192.168.1.2', 'PORT': '5432', }, 'failover1': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'my_database', 'USER': 'postgre_user', 'PASSWORD': 'blahblah', 'HOST': '192.168.1.3', 'PORT': '5432', }, 'failover2': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'my_database', 'USER': 'postgre_user', 'PASSWORD': 'blahblah', 'HOST': '192.168.1.4', 'PORT': '5432', } }with this setting our app just use the default backend (192.168.1.2) for its read and write and if this server get down by any reason our app will stop working
so lets code :)
Simple code for check our servers statusI just wrote a simple code to check our dbms server status and save current avalaible server in a file.
for reducing requests , checking servers status happen in every 10 second
file:dbha.py
# coding=utf-8 from django.conf import settings from datetime import datetime import socket, os def test_connection_to_db(database_name): try: db_definition = getattr(settings, 'DATABASES')[database_name] s = socket.create_connection((db_definition['HOST'], db_definition['PORT']), 5) s.close() return True except Exception as e: return False def available_db(): with open(os.path.dirname(__file__) + '/dbha_last_check.txt', 'r') as f: f = f.read().splitlines() dbha_last_check = datetime.strptime(f[0], '%Y-%m-%d %H:%M:%S') last_db = f[1] if (datetime.now() - dbha_last_check).seconds > 10: if test_connection_to_db('default'): db = 'default' elif test_connection_to_db('failover1'): db = 'failover1' elif test_connection_to_db('failover2'): db = 'failover2' with open(os.path.dirname(__file__) + '/dbha_last_check.txt', 'w') as status_file: lines_of_text = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "\n" + db status_file.write(lines_of_text) status_file.close() return db return last_db creating our custom django database routedjango framework have a database route system feature, so we can use to handle our fail over and HA system .
first we need to make router.py file in our app root directory with this content
file:router.py
# -*- coding: UTF-8 -*- import dbha class ModelDatabaseRouter(object): def db_for_read(self, model, **hints): """Point all read operations to our available dbms server""" return dbha.available_db() def db_for_write(self, model, **hints): """Point all write operations to our available dbms server""" return dbha.available_db()with this code we will get last available dbms server
and in the end we need to tell django to use our router instance it’s default router so just need to put this in our django settings
DATABASE_ROUTERS = ['app.router.ModelDatabaseRouter']