一键构建 Redis Cluster

Posted on Mon 25 May 2020 in Journal

闲言碎语

学我者生,似我者死,这句话可以用在 Spring Cloud 的诸多子项目上,换个说法, “参考我者生,使用我者死”, 有很多实验性的东西,想法不错,实现很矬,有些压根不实用,产品级的服务应用需要更精细的雕琢和打磨。

Redis cluster 快速构建

Redis 5.0 自身就提供了构建 redis 的命令, 简单用 Fabric 写一个脚本,一键构建 Redis Cluster

说是一键构建,实际是三步

  1. fab generate_config
  2. fab start_redis
  3. fab create_redis_cluster

源代码如下

from fabric.api import *
from fabric.api import settings
from fabric.context_managers import *
from fabric.contrib.console import confirm
import os, subprocess

redis_path = '../src'
redis_config = '''daemonize yes
bind 0.0.0.0
port 9001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

'''
@task
def clean_config():
    for port in range(9001,9007):
        local("rm -rf {}".format(port))

@task
def write_config(file_path, port):
    config_content = redis_config.replace('9001', str(port))
    with open(file_path, "w") as fp:
        fp.write(config_content)
@task
def generate_config():
    for port in range(9001,9007):
        local("mkdir -p {}".format(port))
        config_file = '{}/redis.conf'.format(port)
        print("write {}".format(config_file))
        write_config(config_file, port)
@task
def start_redis():
    for folder in range(9001,9007):
        with lcd(str(folder)):
            local("../{}/redis-server ./redis.conf".format(redis_path))

@task
def stop_redis():
    cmd = redis_path + "/redis-cli -p {} shutdown nosave"
    for port in range(9001,9007):
        local(cmd.format(port))
@task
def kill_redis():
    cmd = "ps -efw --width 1024|grep redis-server |grep -v grep|awk '{print $2}"
    pids = subprocess.check_output(cmd, shell=True)
    print(pids)
    with settings(warn_only=True):
        for pid in pids.decode("utf-8").split('\n'):
            local("kill -9 {}".format(pid))
@task
def check_ports_mac():
    with settings(warn_only=True):
        for port in range(9001,9007):
            local("lsof -nP -iTCP:{} | grep LISTEN".format(port))
@task
def check_redis():
    cmd = "ps -ef|grep redis-server |grep -v grep"
    with settings(warn_only=True):
        local(cmd)

@task
def create_redis_cluster():
    cmd = redis_path + "/redis-cli --cluster create {} {}"
    host_and_ports = ""
    for port in range(9001,9007):
            host_and_ports = host_and_ports + "0.0.0.0:{} ".format(port)
    option = "--cluster-replicas 1"
    local(cmd.format(host_and_ports, option))

@task
def redis_cli():
    local(redis_path + "/redis-cli -c -p 9001")

最后可以用 redis info 命令查看一下

fab redis_cli:info

结果如下:

# Server 服务器信息
redis_version:5.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:391103cbae5277b6
redis_mode:cluster
os:Linux 4.4.0-135-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:5.4.0
process_id:19702
run_id:0c3d2c132eefbf68a23dab136cdc79999b6c8ca3
tcp_port:9001
uptime_in_seconds:1444
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:14386466
executable:/home/walter/package/redis-5.0.8/src/redis-server
config_file:/home/walter/mdd/oss/redis/9001/./redis.conf

# Clients 客户端信息
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

# Memory 内存信息
used_memory:2652664
used_memory_human:2.53M
used_memory_rss:5267456
used_memory_rss_human:5.02M
used_memory_peak:2693616
used_memory_peak_human:2.57M
used_memory_peak_perc:98.48%
used_memory_overhead:2578384
used_memory_startup:1463192
used_memory_dataset:74280
used_memory_dataset_perc:6.24%
allocator_allocated:2638792
allocator_active:2822144
allocator_resident:5382144
total_system_memory:8370958336
total_system_memory_human:7.80G
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:1.07

allocator_frag_bytes:183352
allocator_rss_ratio:1.91
allocator_rss_bytes:2560000
rss_overhead_ratio:0.98
rss_overhead_bytes:-114688
mem_fragmentation_ratio:2.03
mem_fragmentation_bytes:2677952
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_clients_slaves:16922
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
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:1591443327
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:274432
aof_enabled:1
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
aof_current_size:0
aof_base_size:0
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

# Stats 统计信息
total_connections_received:4
total_commands_processed:1448
instantaneous_ops_per_sec:0
total_net_input_bytes:52741
total_net_output_bytes:14030
instantaneous_input_kbps:0.02
instantaneous_output_kbps:0.01
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:1
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:178
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:1
slave0:ip=127.0.0.1,port=9005,state=online,offset=2016,lag=1
master_replid:d633853458a2973c12ab79442bc807d35e387f5d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2016
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2016

# CPU 中央处理器信息
used_cpu_sys:0.912000
used_cpu_user:0.844000
used_cpu_sys_children:0.000000
used_cpu_user_children:0.000000

# Cluster 集群信息
cluster_enabled:1