实践环境

  • 系统环境:debian12
  • redis版本:redis-7.2.3
  • 单台服务器多实例(实用环境可以分布部署到多台服务器)

基本安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
## 安装编译依赖
root@master-100:~# apt update && apt upgrade -y && apt install build-essential

## 下载源码包
root@master-100:~# wget -c https://github.com/redis/redis/archive/7.2.3.tar.gz

## 解压并进入目录
root@master-100:~# tar xf 7.2.3.tar.gz
root@master-100:~# ls
7.2.3.tar.gz app redis-7.2.3
root@master-100:~# cd redis-7.2.3/
root@master-100:~/redis-7.2.3# ls
00-RELEASENOTES COPYING MANIFESTO runtest-cluster sentinel.conf utils
BUGS deps README.md runtest-moduleapi src
CODE_OF_CONDUCT.md INSTALL redis.conf runtest-sentinel tests
CONTRIBUTING.md Makefile runtest SECURITY.md TLS.md

## 编译并安装
root@master-100:~/redis-7.2.3# make -j$(nproc) && make PREFIX=/usr/local/redis install

## 查看
root@master-100:/usr/local/redis# ls -l bin
total 28916
-rwxr-xr-x 1 root root 6767520 Dec 30 15:17 redis-benchmark
lrwxrwxrwx 1 root root 12 Dec 30 15:17 redis-check-aof -> redis-server
lrwxrwxrwx 1 root root 12 Dec 30 15:17 redis-check-rdb -> redis-server
-rwxr-xr-x 1 root root 7043224 Dec 30 15:17 redis-cli
lrwxrwxrwx 1 root root 12 Dec 30 15:17 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 15792848 Dec 30 15:17 redis-server

## 创建必要目录
root@master-100:/usr/local/redis# mkdir data etc log run && ls
bin data etc log run

## 使用脚本安装实例,注释脚本
root@master-100:~/redis-7.2.3/utils# sed -n '76,84p' install_server.sh
#bail if this system is managed by systemd
#_pid_1_exe="$(readlink -f /proc/1/exe)"
#if [ "${_pid_1_exe##*/}" = systemd ]
#then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
# exit 1
#fi
#unset _pid_1_exe

## 执行脚本
root@master-100:~/redis-7.2.3/utils# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] /usr/local/redis/etc/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] /usr/local/redis/log/6379.log
Please select the data directory for this instance [/var/lib/redis/6379] /usr/local/redis/data/6379
Please select the redis executable path [/usr/local/redis/bin/redis-server] /usr/local/redis/bin/redis-server
Selected config:
Port : 6379
Config file : /usr/local/redis/etc/6379.conf
Log file : /usr/local/redis/log/6379.log
Data dir : /usr/local/redis/data/6379
Executable : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Success!
Starting Redis server...
Installation successful!

## 修改启动脚本
root@test:/usr/local/redis# cat /etc/init.d/redis_6379 |grep shutdown
$CLIEXEC -p $REDISPORT -a 123456 --no-auth-warning shutdown ## 设置密码后修改此行
echo "Waiting for Redis to shutdown ..."
root@test:/usr/local/redis# cat /etc/init.d/redis_6379 |grep pid
PIDFILE=/usr/local/redis/run/6379.pid

## 环境变量
root@master-100:/usr/local/redis# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/elastic/jdk/bin:/usr/local/node/bin:/usr/local/mysql/bin:/usr/local/mongo/bin:/usr/local/redis/bin

## 启动查看
root@master-100:/usr/local/redis# /etc/init.d/redis_6379 start
root@master-100:/usr/local/redis# netstat -lnpt | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 6251/redis-server 1
tcp6 0 0 ::1:6379 :::* LISTEN 6251/redis-server 1

基本配置文件示例

  • 6379.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    bind 0.0.0.0
    protected-mode yes
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize yes
    pidfile "/usr/local/redis/run/6379.pid"
    loglevel notice
    logfile "/usr/local/redis/log/6379.log"
    databases 16
    always-show-logo no
    set-proc-title yes
    proc-title-template "{title} {listen-addr} {server-mode}"
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename "dump.rdb"
    rdb-del-sync-files no
    dir "/usr/local/redis/data/6379"
    replica-serve-stale-data yes
    replica-read-only yes
    repl-diskless-sync yes
    repl-diskless-sync-delay 5
    repl-diskless-sync-max-replicas 0
    repl-diskless-load disabled
    repl-disable-tcp-nodelay no
    replica-priority 100
    acllog-max-len 128
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    replica-lazy-flush no
    lazyfree-lazy-user-del no
    lazyfree-lazy-user-flush no
    oom-score-adj no
    oom-score-adj-values 0 200 800
    disable-thp yes
    appendonly no
    appendfilename "appendonly.aof"
    appenddirname "appendonlydir"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    aof-use-rdb-preamble yes
    aof-timestamp-enabled no

    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-listpack-entries 512
    hash-max-listpack-value 64
    list-max-listpack-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-listpack-entries 128
    zset-max-listpack-value 64
    hll-sparse-max-bytes 3000
    stream-node-max-bytes 4kb
    stream-node-max-entries 100
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit replica 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    dynamic-hz yes
    aof-rewrite-incremental-fsync yes
    rdb-save-incremental-fsync yes
    jemalloc-bg-thread yes
    save 900 1
    save 300 10
    save 60 10000

    ## 设置密码
    #requirepass sdafhsal
    aclfile "/usr/local/redis/etc/acl.conf"
  • acl.conf
    1
    2
    3
    user default on sanitize-payload #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* &* +@all

    user haifei on sanitize-payload #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~haifei* &* +@all
  • acl密码加密算法
    1
    2
    root@master-100:/usr/local/redis# echo -n "123456" | shasum -a 256 
    8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 -
  • 自定义配置后验证
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    root@master-100:/usr/local/redis/etc# redis-cli
    127.0.0.1:6379> keys *
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth 123456
    OK
    127.0.0.1:6379> keys *
    (empty array)
    127.0.0.1:6379> set name haifei
    OK
    127.0.0.1:6379> keys *
    1) "name"
    127.0.0.1:6379> get name
    "haifei"
    127.0.0.1:6379> auth haifei 123456
    OK
    127.0.0.1:6379> keys *
    1) "name"
    127.0.0.1:6379> get name
    (error) NOPERM No permissions to access a key
    127.0.0.1:6379>

创建多实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## 配置文件
root@master-100:/usr/local/redis/etc# cat 6379.conf | sed 's@6379@6380@g' > 6380.conf
root@master-100:/usr/local/redis/etc# cat 6379.conf | sed 's@6379@6381@g' > 6381.conf
root@master-100:/usr/local/redis/etc# ls
6379.conf 6380.conf 6381.conf acl.conf

## 数据目录
mkdir /usr/local/redis/data/{6380,6381}

## 启动脚本
root@master-100:/etc/init.d# cat redis_6379 | sed 's@6379@6380@g' > redis_6380
root@master-100:/etc/init.d# cat redis_6379 | sed 's@6379@6381@g' > redis_6381
root@master-100:/etc/init.d# chmod +x redis_6380 redis_6381
root@master-100:/etc/init.d# ls -l redis_63*
-rwxr-xr-x 1 root root 1758 Dec 30 16:20 redis_6379
-rwxr-xr-x 1 root root 1758 Dec 30 16:21 redis_6380
-rwxr-xr-x 1 root root 1758 Dec 30 16:22 redis_6381

## 启动后查看
root@master-100:/etc/init.d# netstat -lnpt | grep redis
tcp 0 0 0.0.0.0:6380 0.0.0.0:* LISTEN 6489/redis-server 0
tcp 0 0 0.0.0.0:6381 0.0.0.0:* LISTEN 6496/redis-server 0
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 6478/redis-server 0

redis主从复制

  • 主节点6379追加配置参数
    1
    2
    3
    ## 主从复制
    min-replicas-to-write 1
    min-replicas-max-lag 10
  • 从节点6380和6381追加配置
    1
    2
    3
    4
    5
    6
    ## 主从复制
    min-replicas-to-write 1
    min-replicas-max-lag 10

    replicaof 192.168.250.100 6379
    masterauth "123456"
  • 重启查看
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    min_slaves_good_slaves:2
    slave0:ip=192.168.250.100,port=6380,state=online,offset=98,lag=1
    slave1:ip=192.168.250.100,port=6381,state=online,offset=98,lag=1
    master_failover_state:no-failover
    master_replid:3aa10f9a99e7323fd10fb4dc68e7789d3108f29a
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:98
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:98

故障自转移,添加sentinel节点

  • sentinel实例配置文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    protected-mode no
    port 26379
    daemonize yes
    pidfile /usr/local/redis/run/sentinel-26379.pid
    loglevel notice
    logfile /usr/local/redis/log/sentinel-26379.log
    # dir /usr/local/redis/data/26379
    acllog-max-len 128

    sentinel monitor mymaster 192.168.250.100 6379 2
    sentinel auth-pass mymaster 123456
    sentinel down-after-milliseconds mymaster 5000
    sentinel master-reboot-down-after-period mymaster 3000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 60000
    sentinel resolve-hostnames no
    sentinel announce-hostnames no
    1
    2
    root@master-100:/usr/local/redis/etc# cat sentinel-26379.conf | sed 's@26379@26380@g' > sentinel-26380.conf
    root@master-100:/usr/local/redis/etc# cat sentinel-26379.conf | sed 's@26379@26381@g' > sentinel-26381.conf
  • 启动脚本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #!/bin/sh
    #Configurations injected by install_server below....

    EXEC=/usr/local/redis/bin/redis-server
    CLIEXEC=/usr/local/redis/bin/redis-cli
    PIDFILE=/usr/local/redis/run/sentinel-26379.pid
    CONF="/usr/local/redis/etc/sentinel-26379.conf"
    REDISPORT="26379"
    ###############
    # SysV Init Information
    # chkconfig: - 58 74
    # description: redis_6379 is the redis daemon.
    ### BEGIN INIT INFO
    # Provides: redis_6379
    # Required-Start: $network $local_fs $remote_fs
    # Required-Stop: $network $local_fs $remote_fs
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Should-Start: $syslog $named
    # Should-Stop: $syslog $named
    # Short-Description: start and stop redis_6379
    # Description: Redis daemon
    ### END INIT INFO


    case "$1" in
    start)
    if [ -f $PIDFILE ]
    then
    echo "$PIDFILE exists, process is already running or crashed"
    else
    echo "Starting Redis server..."
    $EXEC $CONF --sentinel
    fi
    ;;
    stop)
    if [ ! -f $PIDFILE ]
    then
    echo "$PIDFILE does not exist, process is not running"
    else
    PID=$(cat $PIDFILE)
    echo "Stopping ..."
    $CLIEXEC -p $REDISPORT shutdown
    while [ -x /proc/${PID} ]
    do
    echo "Waiting for Sentinel to shutdown ..."
    sleep 1
    done
    echo "Sentinel stopped"
    fi
    ;;
    status)
    PID=$(cat $PIDFILE)
    if [ ! -x /proc/${PID} ]
    then
    echo 'Sentinel is not running'
    else
    echo "Sentinel is running ($PID)"
    fi
    ;;
    restart)
    $0 stop
    $0 start
    ;;
    *)
    echo "Please use start, stop, restart or status as first argument"
    ;;
    esac
    1
    2
    3
    4
    5
    6
    7
    8
    root@master-100:/etc/init.d# vim sentinel_26379
    root@master-100:/etc/init.d# cat sentinel_26379 | sed 's@26379@26380@g' > sentinel_26380
    root@master-100:/etc/init.d# cat sentinel_26379 | sed 's@26379@26381@g' > sentinel_26381
    root@master-100:/etc/init.d# chmod +x sentinel_263*
    root@master-100:/etc/init.d# ls -l sentinel_263*
    -rwxr-xr-x 1 root root 1775 Dec 30 17:00 sentinel_26379
    -rwxr-xr-x 1 root root 1775 Dec 30 17:01 sentinel_26380
    -rwxr-xr-x 1 root root 1775 Dec 30 17:01 sentinel_26381
  • 启动查看
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    root@master-100:/etc/init.d# ./sentinel_26379 start
    root@master-100:/etc/init.d# netstat -lnpt |grep 263*
    tcp 0 0 0.0.0.0:26380 0.0.0.0:* LISTEN 6676/redis-server *
    tcp 0 0 0.0.0.0:26381 0.0.0.0:* LISTEN 6684/redis-server *
    tcp 0 0 0.0.0.0:26379 0.0.0.0:* LISTEN 6669/redis-server

    ## sentinel信息
    root@master-100:/usr/local/redis/etc# redis-cli -p 26379 info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_tilt_since_seconds:-1
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=192.168.250.100:6379,slaves=2,sentinels=3

    ## 查看master状态
    root@master-100:/usr/local/redis# redis-cli -p 26379 sentinel master mymaster
    1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.250.100"
    5) "port"
    6) "6379"

    root@master-100:/usr/local/redis/etc# redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
    1) "192.168.250.100"
    2) "6379"

    root@master-100:/usr/local/redis# redis-cli -p 26379 sentinel sentinels mymaster
    1) 1) "name"
    2) "963081b09fa1d490a45353616585263402a7a0bc"
    3) "ip"
    4) "192.168.250.100"
    5) "port"
    6) "26381"

    root@master-100:/usr/local/redis# redis-cli -p 26379 sentinel replicas mymaster
    1) 1) "name"
    2) "192.168.250.100:6381"
    3) "ip"
    4) "192.168.250.100"
    5) "port"
    6) "6381"
  • 转移测试
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ## 关闭6379主节点,发现6381自动变为主节点
    root@master-100:/usr/local/redis# /etc/init.d/redis_6379 stop
    Stopping ...
    Redis stopped
    root@master-100:/usr/local/redis# redis-cli -p 6381
    127.0.0.1:6381> auth 123456
    OK
    127.0.0.1:6381> info replication
    # Replication
    role:master
    connected_slaves:1
    min_slaves_good_slaves:1
    slave0:ip=192.168.250.100,port=6380,state=online,offset=106457,lag=1
    master_failover_state:no-failover
    master_replid:4697abb5c3e54854d8ad93aa67740590eb9ad9f3
    master_replid2:3aa10f9a99e7323fd10fb4dc68e7789d3108f29a
    master_repl_offset:106747
    second_repl_offset:103956
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:15
    repl_backlog_histlen:106733