Skip to content

Commit

Permalink
create multiple Redis DB instances based on CONFIG at /etc/sonic/data…
Browse files Browse the repository at this point in the history
…base_config.json (sonic-net#2182)

this is the first step to moving different databases tables into different database instances

in this PR, only handle multiple database instances creation based on user configuration at /etc/sonic/database_config.json

we keep current method to create single database instance if no extra/new DATABASE configuration exist in database_config.json file.

if user try to configure more db instances at database_config.json , we create those new db instances along with the original db instance existing today.

The configuration is as below, later we can add more db related information if needed:
{
...
"DATABASE": {
"redis-db-01" : {
"port" : "6380",
"database": ["APPL_DB", "STATE_DB"]
},
"redis-db-02" : {
"port" : "6381",
"database":["ASIC_DB"]
},
}
...
}

The detail description is at design doc at sonic-net/SONiC#271

The main idea is : when database.sh started, we check the configuration and generate corresponding scripts.

rc.local service handle old_config copy when loading new images, there is no dependency between rc.local and database service today, for safety and make sure the copy operation are done before database try to read it, we make database service run after rc.local

Then database docker started, we check the configuration and generate corresponding scripts/.conf in database docker as well.

based on those conf, we create databases instances as required.

at last, we ping_pong check database are up and continue


Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com
  • Loading branch information
dzhangalibaba authored and wangshengjun committed Apr 28, 2020
1 parent 8f27851 commit ccd51c2
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 27 deletions.
7 changes: 5 additions & 2 deletions dockers/docker-database/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ RUN apt-get clean -y && \
s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \
' /etc/redis/redis.conf

COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"]
COPY ["docker-database-init.sh", "/usr/local/bin/"]
COPY ["ping_pong_db_insts", "/usr/local/bin/"]
COPY ["database_config.json", "/etc/default/sonic-db/"]

ENTRYPOINT ["/usr/bin/supervisord"]
ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"]
43 changes: 43 additions & 0 deletions dockers/docker-database/database_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"INSTANCES": {
"redis":{
"port": 6379,
"socket": "/var/run/redis/redis.sock"
}
},
"DATABASES" : {
"APPL_DB" : {
"id" : 0,
"instance" : "redis"
},
"ASIC_DB" : {
"id" : 1,
"instance" : "redis"
},
"COUNTERS_DB" : {
"id" : 2,
"instance" : "redis"
},
"LOGLEVEL_DB" : {
"id" : 3,
"instance" : "redis"
},
"CONFIG_DB" : {
"id" : 4,
"instance" : "redis"
},
"PFC_WD_DB" : {
"id" : 5,
"instance" : "redis"
},
"FLEX_COUNTER_DB" : {
"id" : 5,
"instance" : "redis"
},
"STATE_DB" : {
"id" : 6,
"instance" : "redis"
}
},
"VERSION" : "1.0"
}
14 changes: 14 additions & 0 deletions dockers/docker-database/docker-database-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

mkdir -p /var/run/redis/sonic-db
if [ -f /etc/sonic/database_config.json ]; then
cp /etc/sonic/database_config.json /var/run/redis/sonic-db
else
cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db
fi

mkdir -p /etc/supervisor/conf.d/
# generate all redis server supervisord configuration file
sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf

exec /usr/bin/supervisord
40 changes: 40 additions & 0 deletions dockers/docker-database/ping_pong_db_insts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/python
import json
import os
import subprocess
import time
import syslog

def ping_redis(cmd):
output = ''
while True:
try:
output = subprocess.check_output(cmd, shell=True)
except subprocess.CalledProcessError as e:
syslog.syslog(syslog.LOG_ERR, 'ping redis failed, cmd : {}'.format(cmd))

if 'PONG' in output:
break
syslog.syslog(syslog.LOG_ERR, 'ping response : {}'.format(output))
time.sleep(1)

database_config_file = "/var/run/redis/sonic-db/database_config.json"

data = {}
while True:
if os.path.isfile(database_config_file):
with open(database_config_file, "r") as read_file:
data = json.load(read_file)
break
time.sleep(1)
syslog.syslog(syslog.LOG_ERR, 'config file {} does not exist right now'.format(database_config_file))

while True:
if 'INSTANCES' in data:
for inst in data["INSTANCES"]:
port = data["INSTANCES"][inst]["port"]
cmd = "redis-cli -p " + str(port) + " ping"
ping_redis(cmd)
break
time.sleep(1)
syslog.syslog(syslog.LOG_ERR, 'config file {} does not have INSTANCES'.format(database_config_file))
21 changes: 0 additions & 21 deletions dockers/docker-database/supervisord.conf

This file was deleted.

24 changes: 24 additions & 0 deletions dockers/docker-database/supervisord.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[supervisord]
logfile_maxbytes=1MB
logfile_backups=2
nodaemon=true

[program:rsyslogd]
command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n"
priority=1
autostart=true
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

{% if INSTANCES %}
{% for redis_inst, redis_items in INSTANCES.iteritems() %}
[program: {{ redis_inst }}]
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['socket'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}"
priority=2
autostart=true
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
{% endfor %}
{% endif %}
1 change: 1 addition & 0 deletions files/build_templates/database.service.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Description=Database container
Requires=docker.service
After=docker.service
After=rc-local.service

[Service]
User=root
Expand Down
10 changes: 6 additions & 4 deletions files/build_templates/docker_image_ctl.j2
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ function postStartAction()
{
{%- if docker_container_name == "database" %}
# Wait until redis starts
REDIS_SOCK="/var/run/redis/redis.sock"
until [[ $(/usr/bin/docker exec database redis-cli -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do
sleep 1;
done
/usr/bin/docker exec database ping_pong_db_insts
if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then
rm -f $WARM_DIR/dump.rdb
else
Expand Down Expand Up @@ -163,6 +160,11 @@ start() {

{%- if docker_container_name == "database" %}
echo "Creating new {{docker_container_name}} container"
# if database_config exists in old_config, use it; otherwise use the default one in new image
if [ -f /etc/sonic/old_config/database_config.json ]; then
echo "Use database_config.json from old system..."
mv /etc/sonic/old_config/database_config.json /etc/sonic/
fi
{%- else %}
echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU"
{%- endif %}
Expand Down

0 comments on commit ccd51c2

Please sign in to comment.