This page looks best with JavaScript enabled

Redis Master-Slave on FreeBSD

 ·  🎃 kr0m

In a previous article, we explained how to set up a Redis Master-Slave on Linux. This time we will do it on FreeBSD. Conceptually, the steps are the same, only some details regarding installation and the location of the configuration file change.

As a test, I will set up two Jails on Iocage where I will install everything necessary. I say as a test because we should set up the Master and the Slave on different physical servers and even if possible in different networks or data centers to increase the robustness of the system in case of problems.

MightyMax # ~> iocage list
+-----+---------+-------+--------------+---------------+  
| JID |  NAME   | STATE |   RELEASE    |      IP4      |  
+=====+=========+=======+==============+===============+  
| 14  | redis00 | up    | 12.2-RELEASE | 192.168.69.55 |  
+-----+---------+-------+--------------+---------------+  
| 12  | redis01 | up    | 12.2-RELEASE | 192.168.69.56 |  
+-----+---------+-------+--------------+---------------+

We install Redis on both servers:

pkg install redis

We bind the service to all IPs:

sed -i -e ’s/bind\ 127.0.0.1/bind\ 0.0.0.0/g’ /usr/local/etc/redis.conf

We enable authentication:

echo "requirepass PASSWORD" » /usr/local/etc/redis.conf

We enable the service:

sysrc redis_enable="yes"

We start the service:

service redis start

We check that we can access it through redis-cli:

redis-cli -a PASSWORD info

# Server  
redis_version:5.0.9  
redis_git_sha1:00000000  
redis_git_dirty:0  
redis_build_id:521d1e24a8a777ac  
redis_mode:standalone  
os:FreeBSD 12.2-RELEASE-p4 amd64  
arch_bits:64  
multiplexing_api:kqueue  
atomicvar_api:atomic-builtin  
gcc_version:4.2.1  
process_id:87069  
run_id:b05eb0f543a393289abd0a5f166a2863c2620a2a  
tcp_port:6379  
uptime_in_seconds:45  
uptime_in_days:0  
hz:10  
configured_hz:10  
lru_clock:6584244  
executable:/usr/local/bin/redis-server  
config_file:/usr/local/etc/redis.conf  
  
# Clients  
connected_clients:1  
client_recent_max_input_buffer:4  
client_recent_max_output_buffer:0  
blocked_clients:0  
  
# Memory  
used_memory:1436628  
used_memory_human:1.37M  
used_memory_rss:1402800  
used_memory_rss_human:1.34M  
used_memory_peak:1436628  
used_memory_peak_human:1.37M  
used_memory_peak_perc:100.00%  
used_memory_overhead:1435094  
used_memory_startup:1385400  
used_memory_dataset:1534  
used_memory_dataset_perc:2.99%  
allocator_allocated:1402800  
allocator_active:1364912  
allocator_resident:1364912  
total_system_memory:0  
total_system_memory_human:0B  
used_memory_lua:37888  
used_memory_lua_human:37.00K  
used_memory_scripts:0  
used_memory_scripts_human:0B  
number_of_cached_scripts:0  
maxmemory:0  
maxmemory_human:0B  
maxmemory_policy:noeviction  
allocator_frag_ratio:0.97  
allocator_frag_bytes:18446744073709513728  
allocator_rss_ratio:1.00  
allocator_rss_bytes:0  
rss_overhead_ratio:1.03  
rss_overhead_bytes:37888  
mem_fragmentation_ratio:1.00  
mem_fragmentation_bytes:0  
mem_not_counted_for_evict:0  
mem_replication_backlog:0  
mem_clients_slaves:0  
mem_clients_normal:49694  
mem_aof_buffer:0  
mem_allocator:libc  
active_defrag_running:0  
lazyfree_pending_objects:0  
  
# Persistence  
loading:0  
rdb_changes_since_last_save:0  
rdb_bgsave_in_progress:0  
rdb_last_save_time:1617196935  
rdb_last_bgsave_status:ok  
rdb_last_bgsave_time_sec:-1  
rdb_current_bgsave_time_sec:-1  
rdb_last_cow_size:0  
aof_enabled:0  
aof_rewrite_in_progress:0  
aof_rewrite_scheduled:0  
aof_last_rewrite_time_sec:-1  
aof_current_rewrite_time_sec:-1  
aof_last_bgrewrite_status:ok  
aof_last_write_status:ok  
aof_last_cow_size:0  
  
# Stats  
total_connections_received:3  
total_commands_processed:4  
instantaneous_ops_per_sec:0  
total_net_input_bytes:132  
total_net_output_bytes:14794  
instantaneous_input_kbps:0.00  
instantaneous_output_kbps:0.00  
rejected_connections:0  
sync_full:0  
sync_partial_ok:0  
sync_partial_err:0  
expired_keys:0  
expired_stale_perc:0.00  
expired_time_cap_reached_count:0  
evicted_keys:0  
keyspace_hits:0  
keyspace_misses:0  
pubsub_channels:0  
pubsub_patterns:0  
latest_fork_usec:0  
migrate_cached_sockets:0  
slave_expires_tracked_keys:0  
active_defrag_hits:0  
active_defrag_misses:0  
active_defrag_key_hits:0  
active_defrag_key_misses:0  
  
# Replication  
role:master  
connected_slaves:0  
master_replid:3b9f3843dde887b4a3c88897e8702698232075a5  
master_replid2:0000000000000000000000000000000000000000  
master_repl_offset:0  
second_repl_offset:-1  
repl_backlog_active:0  
repl_backlog_size:1048576  
repl_backlog_first_byte_offset:0  
repl_backlog_histlen:0  
  
# CPU  
used_cpu_sys:0.007278  
used_cpu_user:0.011265  
used_cpu_sys_children:0.000000  
used_cpu_user_children:0.000000  
  
# Cluster  
cluster_enabled:0  
  
# Keyspace

Now we will connect redis01 as a slave of redis00.

We run on redis01:

echo "slaveof 192.168.69.55 6379" » /usr/local/etc/redis.conf
echo "masterauth PASSWORD" » /usr/local/etc/redis.conf

We restart the service:

service redis restart

We check on each server that the topology is correct.

On redis00 we will see:

redis-cli -a PASSWORD info

# Replication  
role:master  
connected_slaves:1  
slave0:ip=192.168.69.56,port=6379,state=online,offset=79226,lag=0

On redis01 we will see:

redis-cli -a PASSWORD info

# Replication  
role:slave  
master_host:192.168.69.55  
master_port:6379  
master_link_status:up

We assign firewall rules on each server to restrict access to the redis:

$cmd 01114 allow all from CLIENT_IP to REDIS_SERVER_IP any in via $wanif  
$cmd 01114 allow all from REDIS_SERVER_IP any to CLIENT_IP out via $wanif  
$cmd 60000 deny log all from any to any

NOTE: This is just an example with specific Redis rules. We can refer to this previous article where it is explained in detail how to set up a firewall on IPFW.

If you liked the article, you can treat me to a RedBull here